Skip to content

Commit 8b0a087

Browse files
committed
fix: update MicrosoftTeams notifier colors, JSON serialization, and improve event store capacity test
1 parent e9c1abe commit 8b0a087

2 files changed

Lines changed: 24 additions & 59 deletions

File tree

spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/notify/MicrosoftTeamsNotifier.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import java.util.Map;
2424
import java.util.Objects;
2525

26+
import com.fasterxml.jackson.annotation.JsonInclude;
27+
import com.fasterxml.jackson.annotation.JsonProperty;
2628
import lombok.Builder;
2729
import lombok.Data;
2830
import lombok.Getter;
@@ -62,7 +64,9 @@ public class MicrosoftTeamsNotifier extends AbstractStatusChangeNotifier {
6264

6365
private static final String SOURCE_KEY = "Source";
6466

65-
private static final String DEFAULT_THEME_COLOR_EXPRESSION = "#{event.type == 'STATUS_CHANGED' ? (event.statusInfo.status=='UP' ? 'Good' : 'Attention') : 'Accent'}";
67+
// @see For color definitions
68+
// https://adaptivecards.microsoft.com/?topic=AdaptiveCard#style
69+
private static final String DEFAULT_THEME_COLOR_EXPRESSION = "#{event.type == 'STATUS_CHANGED' ? (event.statusInfo.status=='UP' ? 'good' : 'attention') : 'accent'}";
6670

6771
private static final String DEFAULT_DEREGISTER_ACTIVITY_SUBTITLE_EXPRESSION = "#{instance.registration.name} with id #{instance.id} has de-registered from Spring Boot Admin";
6872

@@ -302,6 +306,7 @@ public void setStatusActivitySubtitle(String statusActivitySubtitle) {
302306

303307
@Data
304308
@Builder
309+
@JsonInclude(JsonInclude.Include.NON_NULL)
305310
public static class Message {
306311

307312
private final String type = "message";
@@ -313,6 +318,7 @@ public static class Message {
313318

314319
@Data
315320
@Builder
321+
@JsonInclude(JsonInclude.Include.NON_NULL)
316322
public static class Attachment {
317323

318324
private final String contentType = "application/vnd.microsoft.card.adaptive";
@@ -325,9 +331,11 @@ public static class Attachment {
325331

326332
@Data
327333
@Builder
334+
@JsonInclude(JsonInclude.Include.NON_NULL)
328335
public static class AdaptiveCard {
329336

330337
@Builder.Default
338+
@JsonProperty("$schema")
331339
private final String schema = "http://adaptivecards.io/schemas/adaptive-card.json";
332340

333341
private final String type = "AdaptiveCard";
@@ -341,6 +349,7 @@ public static class AdaptiveCard {
341349

342350
@Data
343351
@Builder
352+
@JsonInclude(JsonInclude.Include.NON_NULL)
344353
public static class CardElement {
345354

346355
private final String type;

spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/notify/MicrosoftTeamsNotifierTest.java

Lines changed: 14 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@
1818

1919
import java.net.URI;
2020

21-
import org.json.JSONObject;
2221
import org.junit.jupiter.api.BeforeEach;
2322
import org.junit.jupiter.api.Test;
2423
import org.mockito.ArgumentCaptor;
24+
import org.skyscreamer.jsonassert.JSONAssert;
25+
import org.skyscreamer.jsonassert.JSONCompareMode;
2526
import org.springframework.http.HttpEntity;
2627
import org.springframework.http.MediaType;
2728
import org.springframework.web.client.RestTemplate;
2829
import reactor.core.publisher.Mono;
2930
import reactor.test.StepVerifier;
31+
import tools.jackson.databind.json.JsonMapper;
3032

3133
import de.codecentric.boot.admin.server.domain.entities.Instance;
3234
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
@@ -46,11 +48,11 @@
4648

4749
class MicrosoftTeamsNotifierTest {
4850

49-
private static final String ACCENT = "Accent";
51+
private static final String ACCENT = "accent";
5052

51-
private static final String ATTENTION = "Attention";
53+
private static final String ATTENTION = "attention";
5254

53-
private static final String GOOD = "Good";
55+
private static final String GOOD = "good";
5456

5557
private static final String APP_NAME = "Test App";
5658

@@ -230,13 +232,15 @@ void test_messageSerializesToExpectedJsonStructure() throws Exception {
230232
Message message = notifier.getStatusChangedMessage(upInstance, notifier.createEvaluationContext(
231233
new InstanceStatusChangedEvent(upInstance.getId(), 1L, StatusInfo.ofUp()), upInstance));
232234

233-
// Build expected JSON structure using JSONObject with actual values
234-
JSONObject expectedJson = new JSONObject("""
235+
JsonMapper mapper = JsonMapper.builder().build();
236+
String actual = mapper.writeValueAsString(message);
237+
238+
// Build expected JSON structure
239+
String expectedJson = """
235240
{
236241
"type": "message",
237242
"attachments": [{
238243
"contentType": "application/vnd.microsoft.card.adaptive",
239-
"contentUrl": null,
240244
"content": {
241245
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
242246
"type": "AdaptiveCard",
@@ -247,7 +251,7 @@ void test_messageSerializesToExpectedJsonStructure() throws Exception {
247251
"text": "Status Changed",
248252
"size": "Large",
249253
"weight": "Bolder",
250-
"color": "Good"
254+
"color": "good"
251255
},
252256
{
253257
"type": "TextBlock",
@@ -273,57 +277,9 @@ void test_messageSerializesToExpectedJsonStructure() throws Exception {
273277
}
274278
}]
275279
}
276-
""");
277-
278-
// Verify message structure matches expected format
279-
assertThat(message.getType()).isEqualTo(expectedJson.getString("type"));
280-
281-
assertThat(message.getAttachments()).hasSize(1);
282-
var attachment = message.getAttachments().get(0);
283-
assertThat(attachment.getContentType())
284-
.isEqualTo(expectedJson.getJSONArray("attachments").getJSONObject(0).getString("contentType"));
280+
""";
285281

286-
var content = attachment.getContent();
287-
var expectedContent = expectedJson.getJSONArray("attachments").getJSONObject(0).getJSONObject("content");
288-
assertThat(content.getSchema()).isEqualTo(expectedContent.getString("$schema"));
289-
assertThat(content.getType()).isEqualTo(expectedContent.getString("type"));
290-
assertThat(content.getVersion()).isEqualTo(expectedContent.getString("version"));
291-
292-
// Verify body structure and content
293-
var body = content.getBody();
294-
var expectedBody = expectedContent.getJSONArray("body");
295-
assertThat(body).hasSize(expectedBody.length());
296-
297-
// Verify Title TextBlock
298-
assertThat(body.get(0).getType()).isEqualTo("TextBlock");
299-
assertThat(body.get(0).getText()).isEqualTo("Status Changed");
300-
assertThat(body.get(0).getSize()).isEqualTo("Large");
301-
assertThat(body.get(0).getWeight()).isEqualTo("Bolder");
302-
assertThat(body.get(0).getColor()).isEqualTo("Good");
303-
304-
// Verify Service Name TextBlock
305-
assertThat(body.get(1).getType()).isEqualTo("TextBlock");
306-
assertThat(body.get(1).getText()).isEqualTo(APP_NAME);
307-
assertThat(body.get(1).getSize()).isEqualTo("Medium");
308-
assertThat(body.get(1).getWeight()).isEqualTo("Bolder");
309-
310-
// Verify Activity Subtitle TextBlock
311-
assertThat(body.get(2).getType()).isEqualTo("TextBlock");
312-
assertThat(body.get(2).getText()).isEqualTo("Test App with id TestAppId changed status from UNKNOWN to UP");
313-
assertThat(body.get(2).getWrap()).isTrue();
314-
315-
// Verify FactSet
316-
assertThat(body.get(3).getType()).isEqualTo("FactSet");
317-
assertThat(body.get(3).getFacts()).hasSize(4); // Source is omitted because it's
318-
// null
319-
assertThat(body.get(3).getFacts().get(0).title()).isEqualTo("Status");
320-
assertThat(body.get(3).getFacts().get(0).value()).isEqualTo("UP");
321-
assertThat(body.get(3).getFacts().get(1).title()).isEqualTo("Service URL");
322-
assertThat(body.get(3).getFacts().get(1).value()).isEqualTo(SERVICE_URL);
323-
assertThat(body.get(3).getFacts().get(2).title()).isEqualTo("Health URL");
324-
assertThat(body.get(3).getFacts().get(2).value()).isEqualTo(HEALTH_URL);
325-
assertThat(body.get(3).getFacts().get(3).title()).isEqualTo("Management URL");
326-
assertThat(body.get(3).getFacts().get(3).value()).isEqualTo(MANAGEMENT_URL);
282+
JSONAssert.assertEquals(expectedJson, actual, JSONCompareMode.NON_EXTENSIBLE);
327283
}
328284

329285
private String getActivitySubtitleFromMessage(Message message) {

0 commit comments

Comments
 (0)