From 2a45ca880b8bf3fa8386fb6dcc4f5a8af3978539 Mon Sep 17 00:00:00 2001 From: Jessica Rodriguez Date: Wed, 18 Dec 2024 11:05:34 -0500 Subject: [PATCH 1/4] add inventory uri builder --- .../processors/InsightsUrlsBuilder.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java new file mode 100644 index 0000000000..954cd8abff --- /dev/null +++ b/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java @@ -0,0 +1,65 @@ +package com.redhat.cloud.notifications.processors; + +import com.redhat.cloud.notifications.models.Environment; +import com.redhat.cloud.notifications.models.Event; +import io.vertx.core.json.JsonObject; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import java.util.ArrayList; +import java.util.Optional; + +@ApplicationScoped +public class InsightsUrlsBuilder { + + @Inject + Environment environment; + + /** + *

Constructs an Insights URL corresponding to the specific inventory item which generated the notification.

+ * + *

In addition to the required fields of {@link com.redhat.cloud.notifications.ingress.Action Action}, an + * inventory URL will only be generated if fields from one of these two formats are present:

+ * + * + * + *

If neither field is present, an {@link Optional#empty()} will be returned.

+ * + * @param data a payload converted by + * {@link com.redhat.cloud.notifications.transformers.BaseTransformer#toJsonObject(Event) BaseTransformer#toJsonObject(Event)} + * @return URL to the generating inventory item, if required fields are present + */ + public Optional buildInventoryUrl(JsonObject data) { + String path; + ArrayList queryParamParts = new ArrayList<>(); + + String environmentUrl = environment.url(); + String displayName = data.getString("display_name", ""); + String inventoryId = data.getString("inventory_id", ""); + + if (!displayName.isEmpty() + && data.getString("bundle", "").equals("openshift") + && data.getString("application", "").equals("advisor")) { + path = "/openshift/insights/advisor/clusters/" + displayName; + } else { + path = "/insights/inventory/"; + if (!inventoryId.isEmpty()) { + path += inventoryId; + } else if (!displayName.isEmpty()) { + queryParamParts.add("hostname_or_id=" + displayName); + } else { + return Optional.empty(); + } + } + + if (!queryParamParts.isEmpty()) { + String queryParams = "?" + String.join("&", queryParamParts); + path += queryParams; + } + + return Optional.of(environmentUrl + path); + } +} From 8ed9e4a0f1c7cceda14bfc21b6481116b4606f15 Mon Sep 17 00:00:00 2001 From: Jessica Rodriguez Date: Wed, 18 Dec 2024 11:19:34 -0500 Subject: [PATCH 2/4] add application uri builder --- .../processors/InsightsUrlsBuilder.java | 47 +++++++++++++++++-- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java index 954cd8abff..1bc08d55d2 100644 --- a/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java +++ b/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java @@ -1,5 +1,6 @@ package com.redhat.cloud.notifications.processors; +import com.redhat.cloud.notifications.ingress.Action; import com.redhat.cloud.notifications.models.Environment; import com.redhat.cloud.notifications.models.Event; import io.vertx.core.json.JsonObject; @@ -18,15 +19,15 @@ public class InsightsUrlsBuilder { /** *

Constructs an Insights URL corresponding to the specific inventory item which generated the notification.

* - *

In addition to the required fields of {@link com.redhat.cloud.notifications.ingress.Action Action}, an - * inventory URL will only be generated if fields from one of these two formats are present:

+ *

An inventory URL will only be generated if fields from one of these two formats are present:

* *
    *
  • {@code { "context": { "display_name": "non_empty_string" } }}
  • *
  • {@code { "context": { "inventory_id": "non_empty_string" }}}
  • *
* - *

If neither field is present, an {@link Optional#empty()} will be returned.

+ *

If neither field is present, an {@link Optional#empty()} will be returned. If expected fields of + * {@link Action#getBundle()} or {@link Action#getApplication()} are missing, an inaccurate URL may be returned.

* * @param data a payload converted by * {@link com.redhat.cloud.notifications.transformers.BaseTransformer#toJsonObject(Event) BaseTransformer#toJsonObject(Event)} @@ -43,13 +44,13 @@ public Optional buildInventoryUrl(JsonObject data) { if (!displayName.isEmpty() && data.getString("bundle", "").equals("openshift") && data.getString("application", "").equals("advisor")) { - path = "/openshift/insights/advisor/clusters/" + displayName; + path = String.format("/openshift/insights/advisor/clusters/%s", displayName); } else { path = "/insights/inventory/"; if (!inventoryId.isEmpty()) { path += inventoryId; } else if (!displayName.isEmpty()) { - queryParamParts.add("hostname_or_id=" + displayName); + queryParamParts.add(String.format("hostname_or_id=%s", displayName)); } else { return Optional.empty(); } @@ -62,4 +63,40 @@ public Optional buildInventoryUrl(JsonObject data) { return Optional.of(environmentUrl + path); } + + /** + *

Constructs an Insights URL corresponding to the specific inventory item which generated the notification.

+ * + *

If the required field {@link Action#getApplication()} is not present, an + * {@link Optional#empty()} will be returned. If the expected field {@link Action#getBundle()} is not present, an + * inaccurate URL may be returned.

+ * + * @param data a payload converted by + * {@link com.redhat.cloud.notifications.transformers.BaseTransformer#toJsonObject(Event) BaseTransformer#toJsonObject(Event)} + * @return URL to the generating application, if required fields are present + */ + public Optional buildApplicationUrl(JsonObject data) { + String path = ""; + + String environmentUrl = environment.url(); + String bundle = data.getString("bundle", ""); + String application; + + if (data.containsKey("application") && !data.getString("application", "").isEmpty()) { + application = data.getString("application"); + } else { + return Optional.empty(); + } + + if (bundle.equals("application-services") && application.equals("rhosak")) { + path = "application-services/streams"; + } else { + if (bundle.equals("openshift")) { + path = "openshift/"; + } + path += "insights/" + application; + } + + return Optional.of(String.format("%s/%s", environmentUrl, path)); + } } From bca235318dd9d8b881dcb318eb9e31001c858273 Mon Sep 17 00:00:00 2001 From: Jessica Rodriguez Date: Wed, 18 Dec 2024 13:16:23 -0500 Subject: [PATCH 3/4] add Insights URL gen to processors & PD connector CamelProcessor tests and db migration not completed yet --- .../pagerduty/PagerDutyTransformer.java | 39 +++++- .../pagerduty/PagerDutyTestUtils.java | 112 +++++++++++++++--- .../pagerduty/PagerDutyTransformerTest.java | 52 ++++++-- .../processors/camel/CamelProcessor.java | 6 + .../pagerduty/PagerDutyProcessor.java | 6 + .../pagerduty/PagerDutyProcessorTest.java | 16 ++- 6 files changed, 198 insertions(+), 33 deletions(-) diff --git a/connector-pagerduty/src/main/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformer.java b/connector-pagerduty/src/main/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformer.java index b9f00367ab..b12da65f12 100644 --- a/connector-pagerduty/src/main/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformer.java +++ b/connector-pagerduty/src/main/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformer.java @@ -25,6 +25,7 @@ public class PagerDutyTransformer implements Processor { public static final String ACCOUNT_ID = "account_id"; public static final String APPLICATION = "application"; + public static final String APPLICATION_URL = "application_url"; public static final String BUNDLE = "bundle"; public static final String CLIENT = "client"; public static final String CLIENT_URL = "client_url"; @@ -36,12 +37,16 @@ public class PagerDutyTransformer implements Processor { public static final String EVENT_TYPE = "event_type"; public static final String EVENTS = "events"; public static final String GROUP = "group"; + public static final String HREF = "href"; + public static final String INVENTORY_URL = "inventory_url"; + public static final String LINKS = "links"; public static final String ORG_ID = "org_id"; public static final String SEVERITY = "severity"; public static final String SOURCE = "source"; public static final String SOURCE_NAMES = "source_names"; public static final String SUMMARY = "summary"; public static final String TIMESTAMP = "timestamp"; + public static final String TEXT = "text"; public static final DateTimeFormatter PD_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS+0000"); @@ -53,6 +58,7 @@ public void process(Exchange exchange) { JsonObject message = new JsonObject(); message.put(EVENT_ACTION, PagerDutyEventAction.TRIGGER); message.mergeIn(getClientLink(cloudEventPayload, cloudEventPayload.getString(ENVIRONMENT_URL))); + message.mergeIn(getClientLinks(cloudEventPayload)); JsonObject messagePayload = new JsonObject(); messagePayload.put(SUMMARY, cloudEventPayload.getString(EVENT_TYPE)); @@ -92,7 +98,9 @@ public void process(Exchange exchange) { exchange.getIn().setBody(message.encode()); } - /** Validates that the inputs for the required Alert Event fields are present */ + /** + * Validates that the inputs for the required Alert Event fields are present + */ private void validatePayload(final JsonObject cloudEventPayload) { String summary = cloudEventPayload.getString(EVENT_TYPE); if (summary == null || summary.isEmpty()) { @@ -155,7 +163,34 @@ private JsonObject getClientLink(final JsonObject cloudEventPayload, String envi return clientLink; } - private JsonObject getSourceNames(final JsonObject cloudSource) { + /** + * Performs the following link conversions: + *
    + *
  • {@link #APPLICATION} integrated into {@link #CLIENT}
  • + *
  • {@link #APPLICATION_URL} becomes {@link #CLIENT_URL}
  • + *
  • {@link #INVENTORY_URL}, if present, creates an entry in the {@link #LINKS} object
  • + *
+ *

+ * The result is similar to the links provided in Microsoft Teams notifications. + */ + static JsonObject getClientLinks(final JsonObject cloudEventPayload) { + JsonObject clientLinks = new JsonObject(); + + clientLinks.put(CLIENT, String.format("Open %s", cloudEventPayload.getString(APPLICATION))); + clientLinks.put(CLIENT_URL, cloudEventPayload.getString(APPLICATION_URL)); + + String inventoryUrl = cloudEventPayload.getString(INVENTORY_URL, ""); + if (!inventoryUrl.isEmpty()) { + clientLinks.put(LINKS, JsonObject.of( + HREF, inventoryUrl, + TEXT, "Host" + )); + } + + return clientLinks; + } + + static JsonObject getSourceNames(final JsonObject cloudSource) { if (cloudSource != null) { JsonObject sourceNames = new JsonObject(); diff --git a/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTestUtils.java b/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTestUtils.java index 8adbd6066f..eecb6584c4 100644 --- a/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTestUtils.java +++ b/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTestUtils.java @@ -1,10 +1,13 @@ package com.redhat.cloud.notifications.connector.pagerduty; +import com.redhat.cloud.notifications.ingress.Action; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import java.time.DateTimeException; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Optional; import static com.redhat.cloud.notifications.TestConstants.DEFAULT_ACCOUNT_ID; import static com.redhat.cloud.notifications.TestConstants.DEFAULT_ORG_ID; @@ -12,6 +15,7 @@ import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyCloudEventDataExtractor.AUTHENTICATION; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.ACCOUNT_ID; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.APPLICATION; +import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.APPLICATION_URL; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.BUNDLE; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.CLIENT; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.CLIENT_URL; @@ -23,6 +27,7 @@ import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.EVENT_ACTION; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.EVENT_TYPE; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.GROUP; +import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.INVENTORY_URL; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.ORG_ID; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.PAYLOAD; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.PD_DATE_TIME_FORMATTER; @@ -31,9 +36,13 @@ import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.SOURCE_NAMES; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.SUMMARY; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.TIMESTAMP; +import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.getClientLinks; +import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.getSourceNames; public class PagerDutyTestUtils { + static final String DEFAULT_ENVIRONMENT_URL = "https://console.redhat.com"; + static JsonObject createCloudEventData(String url) { JsonObject authentication = new JsonObject(); authentication.put("type", SECRET_TOKEN.name()); @@ -56,6 +65,10 @@ static JsonObject createIncomingPayload(JsonObject cloudEventData) { payload.put(ACCOUNT_ID, DEFAULT_ACCOUNT_ID); payload.put(APPLICATION, "default-application"); payload.put(BUNDLE, "default-bundle"); + payload.put(CONTEXT, JsonObject.of( + DISPLAY_NAME, "console", + "inventory_id", "8a4a4f75-5319-4255-9eb5-1ee5a92efd7f" + )); payload.put(EVENT_TYPE, "default-event-type"); payload.put(EVENTS, JsonArray.of( JsonObject.of("event-1-key", "event-1-value"), @@ -77,6 +90,10 @@ static JsonObject createIncomingPayload(JsonObject cloudEventData) { payload.put(SOURCE, source); payload.put(ENVIRONMENT_URL, "https://console.redhat.com"); + InsightsUrlsBuilder.buildInventoryUrl(payload) + .ifPresent(url -> payload.put(INVENTORY_URL, url)); + InsightsUrlsBuilder.buildApplicationUrl(payload) + .ifPresent(url -> payload.put(APPLICATION_URL, url)); payload.put(SEVERITY, PagerDutySeverity.WARNING); cloudEventData.put(PAYLOAD, payload); @@ -91,6 +108,7 @@ static JsonObject buildExpectedOutgoingPayload(final JsonObject incoming) { JsonObject oldInnerPayload = expected.getJsonObject(PAYLOAD); expected.put(EVENT_ACTION, PagerDutyEventAction.TRIGGER); expected.mergeIn(getClientLink(oldInnerPayload, oldInnerPayload.getString(ENVIRONMENT_URL))); + expected.mergeIn(getClientLinks(oldInnerPayload)); JsonObject newInnerPayload = new JsonObject(); newInnerPayload.put(SUMMARY, oldInnerPayload.getString(EVENT_TYPE)); @@ -159,29 +177,89 @@ private static JsonObject getClientLink(final JsonObject oldInnerPayload, String return clientLink; } +} - private static JsonObject getSourceNames(final JsonObject oldInnerSourceNames) { - if (oldInnerSourceNames != null) { - JsonObject newInnerSourceNames = new JsonObject(); +/** + * This class emulates the functionality of the same class within notifications-engine. + */ +class InsightsUrlsBuilder { + /** + *

Constructs an Insights URL corresponding to the specific inventory item which generated the notification.

+ * + *

An inventory URL will only be generated if fields from one of these two formats are present:

+ * + *
    + *
  • {@code { "context": { "display_name": "non_empty_string" } }}
  • + *
  • {@code { "context": { "inventory_id": "non_empty_string" }}}
  • + *
+ * + *

If neither field is present, an {@link Optional#empty()} will be returned. If expected fields of + * {@link Action#getBundle()} or {@link Action#getApplication()} are missing, an inaccurate URL may be returned.

+ * + * @param data a payload converted by {@code BaseTransformer#toJsonObject(Event)} + * @return URL to the generating inventory item, if required fields are present + */ + static Optional buildInventoryUrl(JsonObject data) { + String path; + ArrayList queryParamParts = new ArrayList<>(); - JsonObject application = oldInnerSourceNames.getJsonObject(APPLICATION); - if (application != null) { - newInnerSourceNames.put(APPLICATION, application.getString(DISPLAY_NAME)); - } - JsonObject bundle = oldInnerSourceNames.getJsonObject(BUNDLE); - if (bundle != null) { - newInnerSourceNames.put(BUNDLE, bundle.getString(DISPLAY_NAME)); - } - JsonObject eventType = oldInnerSourceNames.getJsonObject(EVENT_TYPE); - if (eventType != null) { - newInnerSourceNames.put(EVENT_TYPE, eventType.getString(DISPLAY_NAME)); + String displayName = data.getString("display_name", ""); + String inventoryId = data.getString("inventory_id", ""); + + if (!displayName.isEmpty() + && data.getString("bundle", "").equals("openshift") + && data.getString("application", "").equals("advisor")) { + path = String.format("/openshift/insights/advisor/clusters/%s", displayName); + } else { + path = "/insights/inventory/"; + if (!inventoryId.isEmpty()) { + path += inventoryId; + } else if (!displayName.isEmpty()) { + queryParamParts.add(String.format("hostname_or_id=%s", displayName)); + } else { + return Optional.empty(); } + } - if (!newInnerSourceNames.isEmpty()) { - return newInnerSourceNames; + if (!queryParamParts.isEmpty()) { + String queryParams = "?" + String.join("&", queryParamParts); + path += queryParams; + } + + return Optional.of(PagerDutyTestUtils.DEFAULT_ENVIRONMENT_URL + path); + } + + /** + *

Constructs an Insights URL corresponding to the specific inventory item which generated the notification.

+ * + *

If the required field {@link Action#getApplication()} is not present, an + * {@link Optional#empty()} will be returned. If the expected field {@link Action#getBundle()} is not present, an + * inaccurate URL may be returned.

+ * + * @param data a payload converted by {@code BaseTransformer#toJsonObject(Event)} + * @return URL to the generating application, if required fields are present + */ + static Optional buildApplicationUrl(JsonObject data) { + String path = ""; + + String bundle = data.getString("bundle", ""); + String application; + + if (data.containsKey("application") && !data.getString("application", "").isEmpty()) { + application = data.getString("application"); + } else { + return Optional.empty(); + } + + if (bundle.equals("application-services") && application.equals("rhosak")) { + path = "application-services/streams"; + } else { + if (bundle.equals("openshift")) { + path = "openshift/"; } + path += "insights/" + application; } - return null; + return Optional.of(String.format("%s/%s", PagerDutyTestUtils.DEFAULT_ENVIRONMENT_URL, path)); } } diff --git a/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformerTest.java b/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformerTest.java index b0888ab8a6..e910e53e3b 100644 --- a/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformerTest.java +++ b/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformerTest.java @@ -20,6 +20,7 @@ import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.ENVIRONMENT_URL; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.EVENTS; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.EVENT_TYPE; +import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.INVENTORY_URL; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.PAYLOAD; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.SEVERITY; import static com.redhat.cloud.notifications.connector.pagerduty.PagerDutyTransformer.SOURCE; @@ -28,7 +29,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -/** These test cases are intended to verify that the {@link PagerDutyTransformer} can handle various possible inputs. */ +/** + * These test cases are intended to verify that the {@link PagerDutyTransformer} can handle various possible inputs. + */ @QuarkusTest @QuarkusTestResource(TestLifecycleManager.class) public class PagerDutyTransformerTest extends CamelQuarkusTestSupport { @@ -83,8 +86,10 @@ void testSuccessfulPayloadTransform() { validatePayloadTransform(cloudEventData, expectedPayload); } - /** This is a real test message generated from the {@code /endpoints/{uuid}/test} integrations endpoint, with the - * account and org id replaced. */ + /** + * This is a slightly modified version of a real test message generated from the {@code /endpoints/{uuid}/test} + * integrations endpoint, with the account and org id replaced. + */ @Test void testSuccessfulTestMessage() { JsonObject cloudEventData = createIncomingPayload(TEST_URL); @@ -108,6 +113,10 @@ void testSuccessfulTestMessage() { ); cloudEventPayload.put("recipients", JsonArray.of()); cloudEventPayload.put("environment_url", "https://console.redhat.com"); + InsightsUrlsBuilder.buildInventoryUrl(cloudEventPayload) + .ifPresent(url -> cloudEventPayload.put("inventory_url", url)); + InsightsUrlsBuilder.buildApplicationUrl(cloudEventPayload) + .ifPresent(url -> cloudEventPayload.put("application_url", url)); cloudEventPayload.put("severity", "warning"); cloudEventData.put(PAYLOAD, cloudEventPayload); @@ -130,8 +139,7 @@ void testInvalidTimestampDropped() { void testMissingSourceNames() { JsonObject cloudEventData = createIncomingPayload(TEST_URL); JsonObject cloudPayload = cloudEventData.getJsonObject(PAYLOAD); - cloudEventData.remove(SOURCE); - cloudEventData.put(PAYLOAD, cloudPayload); + cloudPayload.remove(SOURCE); JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData); validatePayloadTransform(cloudEventData, expectedPayload); @@ -142,10 +150,7 @@ void testMissingApplicationDisplayName() { JsonObject cloudEventData = createIncomingPayload(TEST_URL); JsonObject cloudPayload = cloudEventData.getJsonObject(PAYLOAD); JsonObject sourceNames = cloudPayload.getJsonObject(SOURCE); - sourceNames.remove(APPLICATION); - cloudPayload.put(SOURCE, sourceNames); - cloudEventData.put(PAYLOAD, cloudPayload); JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData); validatePayloadTransform(cloudEventData, expectedPayload); @@ -167,7 +172,6 @@ void testMissingEvents() { JsonObject cloudEventData = createIncomingPayload(TEST_URL); JsonObject cloudPayload = cloudEventData.getJsonObject(PAYLOAD); cloudPayload.remove(EVENTS); - cloudEventData.put(PAYLOAD, cloudPayload); JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData); validatePayloadTransform(cloudEventData, expectedPayload); @@ -187,6 +191,17 @@ void testWithClientDisplayName() { validatePayloadTransform(cloudEventData, expectedPayload); } + @Test + void testWithMissingClientDisplayName() { + JsonObject cloudEventData = createIncomingPayload(TEST_URL); + JsonObject cloudPayload = cloudEventData.getJsonObject(PAYLOAD); + JsonObject context = cloudPayload.getJsonObject(CONTEXT); + context.remove(DISPLAY_NAME); + + JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData); + validatePayloadTransform(cloudEventData, expectedPayload); + } + @Test void testWithClientDisplayNameAndInventoryId() { JsonObject cloudEventData = createIncomingPayload(TEST_URL); @@ -196,6 +211,14 @@ void testWithClientDisplayNameAndInventoryId() { "inventory_id", "8a4a4f75-5319-4255-9eb5-1ee5a92efd7f" )); cloudEventData.put(PAYLOAD, cloudPayload); + } + + @Test + void testWithMissingInventoryId() { + JsonObject cloudEventData = createIncomingPayload(TEST_URL); + JsonObject cloudPayload = cloudEventData.getJsonObject(PAYLOAD); + JsonObject context = cloudPayload.getJsonObject(CONTEXT); + context.remove("inventory_id"); JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData); validatePayloadTransform(cloudEventData, expectedPayload); @@ -211,6 +234,16 @@ void testMissingEnvironmentUrl() { validatePayloadTransform(cloudEventData, expectedPayload); } + @Test + void testMissingInventoryUrl() { + JsonObject cloudEventData = createIncomingPayload(TEST_URL); + JsonObject cloudPayload = cloudEventData.getJsonObject(PAYLOAD); + cloudPayload.remove(INVENTORY_URL); + + JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData); + validatePayloadTransform(cloudEventData, expectedPayload); + } + void verifyTransformExceptionThrown(JsonObject cloudEventData, Class exceptionType, String exceptionMessage) { Exchange exchange = createExchangeWithBody(context, "I am not used!"); @@ -219,7 +252,6 @@ void verifyTransformExceptionThrown(JsonObject cloudEventData, Class data.put("inventory_url", url)); + insightsUrlsBuilder.buildApplicationUrl(data).ifPresent(url -> data.put("application_url", url)); Map dataAsMap; try { diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessor.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessor.java index fa1ef86a50..ef41598b62 100644 --- a/engine/src/main/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessor.java +++ b/engine/src/main/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessor.java @@ -8,6 +8,7 @@ import com.redhat.cloud.notifications.models.PagerDutyProperties; import com.redhat.cloud.notifications.processors.ConnectorSender; import com.redhat.cloud.notifications.processors.EndpointTypeProcessor; +import com.redhat.cloud.notifications.processors.InsightsUrlsBuilder; import com.redhat.cloud.notifications.transformers.BaseTransformer; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; @@ -37,6 +38,9 @@ public class PagerDutyProcessor extends EndpointTypeProcessor { @Inject Environment environment; + @Inject + InsightsUrlsBuilder insightsUrlsBuilder; + @Inject MeterRegistry registry; @@ -74,6 +78,8 @@ private void process(Event event, Endpoint endpoint) { JsonObject connectorData = new JsonObject(); JsonObject transformedEvent = transformer.toJsonObject(event); transformedEvent.put("environment_url", environment.url()); + insightsUrlsBuilder.buildInventoryUrl(transformedEvent).ifPresent(url -> transformedEvent.put("inventory_url", url)); + insightsUrlsBuilder.buildApplicationUrl(transformedEvent).ifPresent(url -> transformedEvent.put("application_url", url)); transformedEvent.put("severity", properties.getSeverity()); connectorData.put(PAYLOAD, transformedEvent); diff --git a/engine/src/test/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessorTest.java b/engine/src/test/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessorTest.java index 4dbcd2eb02..1067db67d1 100644 --- a/engine/src/test/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessorTest.java +++ b/engine/src/test/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessorTest.java @@ -19,6 +19,7 @@ import com.redhat.cloud.notifications.models.NotificationStatus; import com.redhat.cloud.notifications.models.PagerDutyProperties; import com.redhat.cloud.notifications.models.PagerDutySeverity; +import com.redhat.cloud.notifications.processors.InsightsUrlsBuilder; import com.redhat.cloud.notifications.transformers.BaseTransformer; import io.quarkus.test.InjectMock; import io.quarkus.test.common.QuarkusTestResource; @@ -73,6 +74,9 @@ public class PagerDutyProcessorTest { @Inject Environment environment; + @Inject + InsightsUrlsBuilder insightsUrlsBuilder; + @PostConstruct void postConstruct() { inMemorySink = inMemoryConnector.sink(TOCAMEL_CHANNEL); @@ -122,10 +126,14 @@ void testPagerDutyUsingConnector() { Message message = inMemorySink.received().getFirst(); JsonObject payload = message.getPayload(); - final JsonObject payloadToSent = transformer.toJsonObject(event); - payloadToSent.put("environment_url", environment.url()); - payloadToSent.put("severity", PagerDutySeverity.ERROR); - assertEquals(payloadToSent, payload.getJsonObject("payload")); + final JsonObject payloadToSend = transformer.toJsonObject(event); + payloadToSend.put("environment_url", environment.url()); + insightsUrlsBuilder.buildInventoryUrl(payloadToSend) + .ifPresent(url -> payloadToSend.put("inventory_url", url)); + insightsUrlsBuilder.buildApplicationUrl(payloadToSend) + .ifPresent(url -> payloadToSend.put("application_url", url)); + payloadToSend.put("severity", PagerDutySeverity.ERROR); + assertEquals(payloadToSend, payload.getJsonObject("payload")); micrometerAssertionHelper.assertCounterIncrement(PROCESSED_PAGERDUTY_COUNTER, 1); } From 7c24129395315c53b457287f17bda22f88f00bca Mon Sep 17 00:00:00 2001 From: Jessica Rodriguez Date: Wed, 18 Dec 2024 14:23:02 -0500 Subject: [PATCH 4/4] Add host_url handling, proc tests --- .../pagerduty/PagerDutyTestUtils.java | 71 ++++++++++--------- .../pagerduty/PagerDutyTransformerTest.java | 14 +++- .../processors/InsightsUrlsBuilder.java | 68 ++++++++++-------- .../processors/camel/CamelProcessor.java | 2 +- .../pagerduty/PagerDutyProcessor.java | 2 +- .../processors/camel/CamelProcessorTest.java | 41 ++++++++--- .../google/chat/GoogleChatProcessorTest.java | 7 +- .../camel/slack/SlackProcessorTest.java | 12 ++-- .../camel/teams/TeamsProcessorTest.java | 7 +- .../pagerduty/PagerDutyProcessorTest.java | 3 +- 10 files changed, 139 insertions(+), 88 deletions(-) diff --git a/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTestUtils.java b/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTestUtils.java index eecb6584c4..fc00905827 100644 --- a/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTestUtils.java +++ b/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTestUtils.java @@ -92,8 +92,7 @@ static JsonObject createIncomingPayload(JsonObject cloudEventData) { payload.put(ENVIRONMENT_URL, "https://console.redhat.com"); InsightsUrlsBuilder.buildInventoryUrl(payload) .ifPresent(url -> payload.put(INVENTORY_URL, url)); - InsightsUrlsBuilder.buildApplicationUrl(payload) - .ifPresent(url -> payload.put(APPLICATION_URL, url)); + payload.put(APPLICATION_URL, InsightsUrlsBuilder.buildApplicationUrl(payload)); payload.put(SEVERITY, PagerDutySeverity.WARNING); cloudEventData.put(PAYLOAD, payload); @@ -189,8 +188,9 @@ class InsightsUrlsBuilder { *

An inventory URL will only be generated if fields from one of these two formats are present:

* *
    - *
  • {@code { "context": { "display_name": "non_empty_string" } }}
  • + *
  • {@code { "context": { "host_url": "non_empty_string" }}}
  • *
  • {@code { "context": { "inventory_id": "non_empty_string" }}}
  • + *
  • {@code { "context": { "display_name": "non_empty_string" } }}
  • *
* *

If neither field is present, an {@link Optional#empty()} will be returned. If expected fields of @@ -202,23 +202,34 @@ class InsightsUrlsBuilder { static Optional buildInventoryUrl(JsonObject data) { String path; ArrayList queryParamParts = new ArrayList<>(); + JsonObject context = data.getJsonObject("context"); + if (context == null) { + return Optional.empty(); + } - String displayName = data.getString("display_name", ""); - String inventoryId = data.getString("inventory_id", ""); + // A provided host url does not need to be modified + String host_url = context.getString("host_url", ""); + if (!host_url.isEmpty()) { + return Optional.of(host_url); + } - if (!displayName.isEmpty() - && data.getString("bundle", "").equals("openshift") - && data.getString("application", "").equals("advisor")) { - path = String.format("/openshift/insights/advisor/clusters/%s", displayName); - } else { - path = "/insights/inventory/"; - if (!inventoryId.isEmpty()) { - path += inventoryId; - } else if (!displayName.isEmpty()) { - queryParamParts.add(String.format("hostname_or_id=%s", displayName)); + String inventoryId = context.getString("inventory_id", ""); + String displayName = context.getString("display_name", ""); + + if (!displayName.isEmpty()) { + if (data.getString("bundle", "").equals("openshift") + && data.getString("application", "").equals("advisor")) { + path = String.format("/openshift/insights/advisor/clusters/%s", displayName); } else { - return Optional.empty(); + path = "/insights/inventory/"; + if (!inventoryId.isEmpty()) { + path += inventoryId; + } else { + queryParamParts.add(String.format("hostname_or_id=%s", displayName)); + } } + } else { + return Optional.empty(); } if (!queryParamParts.isEmpty()) { @@ -232,34 +243,30 @@ static Optional buildInventoryUrl(JsonObject data) { /** *

Constructs an Insights URL corresponding to the specific inventory item which generated the notification.

* - *

If the required field {@link Action#getApplication()} is not present, an - * {@link Optional#empty()} will be returned. If the expected field {@link Action#getBundle()} is not present, an + *

If the expected fields {@link Action#getApplication()} and {@link Action#getBundle()} are not present, an * inaccurate URL may be returned.

* * @param data a payload converted by {@code BaseTransformer#toJsonObject(Event)} - * @return URL to the generating application, if required fields are present + * @return URL to the generating application */ - static Optional buildApplicationUrl(JsonObject data) { + static String buildApplicationUrl(JsonObject data) { String path = ""; String bundle = data.getString("bundle", ""); - String application; + String application = data.getString("application", ""); - if (data.containsKey("application") && !data.getString("application", "").isEmpty()) { - application = data.getString("application"); - } else { - return Optional.empty(); + if (bundle.equals("openshift")) { + path = "openshift/"; } - if (bundle.equals("application-services") && application.equals("rhosak")) { - path = "application-services/streams"; + if (application.equals("integrations")) { + path += "settings/"; } else { - if (bundle.equals("openshift")) { - path = "openshift/"; - } - path += "insights/" + application; + path += "insights/"; } - return Optional.of(String.format("%s/%s", PagerDutyTestUtils.DEFAULT_ENVIRONMENT_URL, path)); + path += application; + + return String.format("%s/%s", PagerDutyTestUtils.DEFAULT_ENVIRONMENT_URL, path); } } diff --git a/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformerTest.java b/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformerTest.java index e910e53e3b..edf02b455e 100644 --- a/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformerTest.java +++ b/connector-pagerduty/src/test/java/com/redhat/cloud/notifications/connector/pagerduty/PagerDutyTransformerTest.java @@ -115,8 +115,7 @@ void testSuccessfulTestMessage() { cloudEventPayload.put("environment_url", "https://console.redhat.com"); InsightsUrlsBuilder.buildInventoryUrl(cloudEventPayload) .ifPresent(url -> cloudEventPayload.put("inventory_url", url)); - InsightsUrlsBuilder.buildApplicationUrl(cloudEventPayload) - .ifPresent(url -> cloudEventPayload.put("application_url", url)); + cloudEventPayload.put("application_url", InsightsUrlsBuilder.buildApplicationUrl(cloudEventPayload)); cloudEventPayload.put("severity", "warning"); cloudEventData.put(PAYLOAD, cloudEventPayload); @@ -191,6 +190,17 @@ void testWithClientDisplayName() { validatePayloadTransform(cloudEventData, expectedPayload); } + @Test + void testWithHostUrl() { + JsonObject cloudEventData = createIncomingPayload(TEST_URL); + JsonObject cloudPayload = cloudEventData.getJsonObject(PAYLOAD); + JsonObject context = cloudPayload.getJsonObject(CONTEXT); + context.put("host_url", "https://console.redhat.com/insights/inventory/8a4a4f75-5319-4255-9eb5-1ee5a92efd7f"); + + JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData); + validatePayloadTransform(cloudEventData, expectedPayload); + } + @Test void testWithMissingClientDisplayName() { JsonObject cloudEventData = createIncomingPayload(TEST_URL); diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java index 1bc08d55d2..751bbda907 100644 --- a/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java +++ b/engine/src/main/java/com/redhat/cloud/notifications/processors/InsightsUrlsBuilder.java @@ -22,8 +22,9 @@ public class InsightsUrlsBuilder { *

An inventory URL will only be generated if fields from one of these two formats are present:

* *
    - *
  • {@code { "context": { "display_name": "non_empty_string" } }}
  • + *
  • {@code { "context": { "host_url": "non_empty_string" } }}
  • *
  • {@code { "context": { "inventory_id": "non_empty_string" }}}
  • + *
  • {@code { "context": { "display_name": "non_empty_string" } }}
  • *
* *

If neither field is present, an {@link Optional#empty()} will be returned. If expected fields of @@ -36,24 +37,35 @@ public class InsightsUrlsBuilder { public Optional buildInventoryUrl(JsonObject data) { String path; ArrayList queryParamParts = new ArrayList<>(); + JsonObject context = data.getJsonObject("context"); + if (context == null) { + return Optional.empty(); + } + + // A provided host url does not need to be modified + String host_url = context.getString("host_url", ""); + if (!host_url.isEmpty()) { + return Optional.of(host_url); + } String environmentUrl = environment.url(); - String displayName = data.getString("display_name", ""); - String inventoryId = data.getString("inventory_id", ""); + String inventoryId = context.getString("inventory_id", ""); + String displayName = context.getString("display_name", ""); - if (!displayName.isEmpty() - && data.getString("bundle", "").equals("openshift") - && data.getString("application", "").equals("advisor")) { - path = String.format("/openshift/insights/advisor/clusters/%s", displayName); - } else { - path = "/insights/inventory/"; - if (!inventoryId.isEmpty()) { - path += inventoryId; - } else if (!displayName.isEmpty()) { - queryParamParts.add(String.format("hostname_or_id=%s", displayName)); + if (!displayName.isEmpty()) { + if (data.getString("bundle", "").equals("openshift") + && data.getString("application", "").equals("advisor")) { + path = String.format("/openshift/insights/advisor/clusters/%s", displayName); } else { - return Optional.empty(); + path = "/insights/inventory/"; + if (!inventoryId.isEmpty()) { + path += inventoryId; + } else { + queryParamParts.add(String.format("hostname_or_id=%s", displayName)); + } } + } else { + return Optional.empty(); } if (!queryParamParts.isEmpty()) { @@ -67,36 +79,32 @@ public Optional buildInventoryUrl(JsonObject data) { /** *

Constructs an Insights URL corresponding to the specific inventory item which generated the notification.

* - *

If the required field {@link Action#getApplication()} is not present, an - * {@link Optional#empty()} will be returned. If the expected field {@link Action#getBundle()} is not present, an + *

If the expected fields {@link Action#getApplication()} and {@link Action#getBundle()} are not present, an * inaccurate URL may be returned.

* * @param data a payload converted by * {@link com.redhat.cloud.notifications.transformers.BaseTransformer#toJsonObject(Event) BaseTransformer#toJsonObject(Event)} - * @return URL to the generating application, if required fields are present + * @return URL to the generating application */ - public Optional buildApplicationUrl(JsonObject data) { + public String buildApplicationUrl(JsonObject data) { String path = ""; String environmentUrl = environment.url(); String bundle = data.getString("bundle", ""); - String application; + String application = data.getString("application", ""); - if (data.containsKey("application") && !data.getString("application", "").isEmpty()) { - application = data.getString("application"); - } else { - return Optional.empty(); + if (bundle.equals("openshift")) { + path = "openshift/"; } - if (bundle.equals("application-services") && application.equals("rhosak")) { - path = "application-services/streams"; + if (application.equals("integrations")) { + path += "settings/"; } else { - if (bundle.equals("openshift")) { - path = "openshift/"; - } - path += "insights/" + application; + path += "insights/"; } - return Optional.of(String.format("%s/%s", environmentUrl, path)); + path += application; + + return String.format("%s/%s", environmentUrl, path); } } diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/camel/CamelProcessor.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/camel/CamelProcessor.java index 89271d8ece..57a4f9547c 100644 --- a/engine/src/main/java/com/redhat/cloud/notifications/processors/camel/CamelProcessor.java +++ b/engine/src/main/java/com/redhat/cloud/notifications/processors/camel/CamelProcessor.java @@ -81,7 +81,7 @@ protected String buildNotificationMessage(Event event) { JsonObject data = baseTransformer.toJsonObject(event); data.put("environment_url", environment.url()); insightsUrlsBuilder.buildInventoryUrl(data).ifPresent(url -> data.put("inventory_url", url)); - insightsUrlsBuilder.buildApplicationUrl(data).ifPresent(url -> data.put("application_url", url)); + data.put("application_url", insightsUrlsBuilder.buildApplicationUrl(data)); Map dataAsMap; try { diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessor.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessor.java index ef41598b62..4f5331568b 100644 --- a/engine/src/main/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessor.java +++ b/engine/src/main/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessor.java @@ -79,7 +79,7 @@ private void process(Event event, Endpoint endpoint) { JsonObject transformedEvent = transformer.toJsonObject(event); transformedEvent.put("environment_url", environment.url()); insightsUrlsBuilder.buildInventoryUrl(transformedEvent).ifPresent(url -> transformedEvent.put("inventory_url", url)); - insightsUrlsBuilder.buildApplicationUrl(transformedEvent).ifPresent(url -> transformedEvent.put("application_url", url)); + transformedEvent.put("application_url", insightsUrlsBuilder.buildApplicationUrl(transformedEvent)); transformedEvent.put("severity", properties.getSeverity()); connectorData.put(PAYLOAD, transformedEvent); diff --git a/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/CamelProcessorTest.java b/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/CamelProcessorTest.java index 665c66fd99..19bbbf985c 100644 --- a/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/CamelProcessorTest.java +++ b/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/CamelProcessorTest.java @@ -15,6 +15,7 @@ import com.redhat.cloud.notifications.models.IntegrationTemplate; import com.redhat.cloud.notifications.models.NotificationHistory; import com.redhat.cloud.notifications.models.Template; +import com.redhat.cloud.notifications.templates.models.EnvironmentTest; import io.micrometer.core.instrument.MeterRegistry; import io.quarkus.test.InjectMock; import io.smallrye.reactive.messaging.ce.CloudEventMetadata; @@ -53,6 +54,7 @@ public abstract class CamelProcessorTest { private static final String WEBHOOK_URL = "https://foo.bar"; + protected static final String CONTEXT_HOST_URL = EnvironmentTest.expectedTestEnvUrlValue + "/insights/inventory/my-custom-host-url"; @InjectMock TemplateRepository templateRepository; @@ -82,7 +84,7 @@ void clearInMemorySink() { protected abstract String getQuteTemplate(); - protected abstract String getExpectedMessage(); + protected abstract String getExpectedMessage(boolean withHostUrl); protected abstract String getSubType(); @@ -90,17 +92,30 @@ void clearInMemorySink() { @Test void testProcess() { + testProcessInternal(false); + } + + /** + * An additional test where the field {@code host_url} is added to {@link Context}, overriding the typically + * generated value. + */ + @Test + void testProcessWithHostUrl() { + testProcessInternal(true); + } + + private void testProcessInternal(boolean withHostUrl) { mockTemplate(); - Event event = buildEvent(); + Event event = buildEvent(withHostUrl); Endpoint endpoint = buildEndpoint(); getCamelProcessor().process(event, List.of(endpoint)); verify(templateRepository, times(1)).findIntegrationTemplate(any(), any(), any(), any(), any()); verify(notificationHistoryRepository, times(1)).createNotificationHistory(any(NotificationHistory.class)); - verifyKafkaMessage(); + verifyKafkaMessage(withHostUrl); } - protected void verifyKafkaMessage() { + protected void verifyKafkaMessage(boolean withHostUrl) { await().until(() -> inMemorySink.received().size() == 1); Message message = inMemorySink.received().get(0); @@ -115,7 +130,7 @@ protected void verifyKafkaMessage() { assertEquals(DEFAULT_ORG_ID, notification.getString("org_id")); assertEquals(WEBHOOK_URL, notification.getString("webhookUrl")); - assertEquals(getExpectedMessage(), notification.getString("message")); + assertEquals(getExpectedMessage(withHostUrl), notification.getString("message")); } protected void assertNotificationsConnectorHeader(Message message) { @@ -137,18 +152,22 @@ protected void mockTemplate() { when(templateRepository.findIntegrationTemplate(any(), any(), any(), any(), any())).thenReturn(Optional.of(integrationTemplate)); } - protected static Event buildEvent() { + protected static Event buildEvent(boolean withHostUrl) { + Context.ContextBuilderBase contextBuilder = new Context.ContextBuilder() + .withAdditionalProperty("inventory_id", "6ad30f3e-0497-4e74-99f1-b3f9a6120a6f") + .withAdditionalProperty("display_name", "my-computer"); + + if (withHostUrl) { + contextBuilder.withAdditionalProperty("host_url", CONTEXT_HOST_URL); + } + Action action = new Action.ActionBuilder() .withBundle("rhel") .withApplication("policies") .withEventType("policy-triggered") .withOrgId(DEFAULT_ORG_ID) .withTimestamp(LocalDateTime.now(UTC)) - .withContext(new Context.ContextBuilder() - .withAdditionalProperty("inventory_id", "6ad30f3e-0497-4e74-99f1-b3f9a6120a6f") - .withAdditionalProperty("display_name", "my-computer") - .build() - ) + .withContext(contextBuilder.build()) .withEvents(List.of( new com.redhat.cloud.notifications.ingress.Event.EventBuilder() .withMetadata(new Metadata.MetadataBuilder().build()) diff --git a/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/google/chat/GoogleChatProcessorTest.java b/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/google/chat/GoogleChatProcessorTest.java index 0786dbb48e..daf76a1ea4 100644 --- a/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/google/chat/GoogleChatProcessorTest.java +++ b/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/google/chat/GoogleChatProcessorTest.java @@ -24,6 +24,9 @@ public class GoogleChatProcessorTest extends CamelProcessorTest { private static final String GOOGLE_CHAT_EXPECTED_MSG = "{\"text\":\"<" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/inventory/6ad30f3e-0497-4e74-99f1-b3f9a6120a6f|my-computer> " + "triggered 1 event from rhel/policies. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open policies>\"}"; + private static final String GOOGLE_CHAT_EXPECTED_MSG_WITH_HOST_URL = "{\"text\":\"<" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/inventory/6ad30f3e-0497-4e74-99f1-b3f9a6120a6f|my-computer> " + + "triggered 1 event from rhel/policies. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open policies>\"}"; + @Inject GoogleChatProcessor googleSpacesProcessor; @@ -33,8 +36,8 @@ protected String getQuteTemplate() { } @Override - protected String getExpectedMessage() { - return GOOGLE_CHAT_EXPECTED_MSG; + protected String getExpectedMessage(boolean withHostUrl) { + return withHostUrl ? GOOGLE_CHAT_EXPECTED_MSG_WITH_HOST_URL : GOOGLE_CHAT_EXPECTED_MSG; } @Override diff --git a/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/slack/SlackProcessorTest.java b/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/slack/SlackProcessorTest.java index b16be33b35..e36e18247d 100644 --- a/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/slack/SlackProcessorTest.java +++ b/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/slack/SlackProcessorTest.java @@ -36,6 +36,8 @@ public class SlackProcessorTest extends CamelProcessorTest { "<{data.environment_url}/insights/{data.application}|Open {data.application}>"; private static final String SLACK_EXPECTED_MSG = "<" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/inventory/6ad30f3e-0497-4e74-99f1-b3f9a6120a6f|my-computer> " + "triggered 1 event from rhel/policies. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open policies>"; + private static final String SLACK_EXPECTED_MSG_WITH_HOST_URL = "<" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/inventory/6ad30f3e-0497-4e74-99f1-b3f9a6120a6f|my-computer> " + + "triggered 1 event from rhel/policies. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open policies>"; @Inject SlackProcessor slackProcessor; @@ -46,8 +48,8 @@ protected String getQuteTemplate() { } @Override - protected String getExpectedMessage() { - return SLACK_EXPECTED_MSG; + protected String getExpectedMessage(boolean withHostUrl) { + return withHostUrl ? SLACK_EXPECTED_MSG_WITH_HOST_URL : SLACK_EXPECTED_MSG; } @Override @@ -61,7 +63,7 @@ protected CamelProcessor getCamelProcessor() { } @Override - protected void verifyKafkaMessage() { + protected void verifyKafkaMessage(boolean withHostUrl) { await().until(() -> inMemorySink.received().size() == 1); Message message = inMemorySink.received().get(0); @@ -77,7 +79,7 @@ protected void verifyKafkaMessage() { assertEquals(DEFAULT_ORG_ID, notification.getString("org_id")); assertEquals(WEBHOOK_URL, notification.getString("webhookUrl")); assertEquals(CHANNEL, notification.getString("channel")); - assertEquals(SLACK_EXPECTED_MSG, notification.getString("message")); + assertEquals(getExpectedMessage(withHostUrl), notification.getString("message")); } @Override @@ -102,7 +104,7 @@ void testEmptyExtrasSendsSlackMessage() { this.mockTemplate(); // Build the required data. - final Event event = buildEvent(); + final Event event = buildEvent(false); final Endpoint endpoint = this.buildEndpoint(); // Remove the "extras" object from the endpoint. final CamelProperties camelProperties = endpoint.getProperties(CamelProperties.class); diff --git a/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/teams/TeamsProcessorTest.java b/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/teams/TeamsProcessorTest.java index 44e58ecea7..1cd8e19ca6 100644 --- a/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/teams/TeamsProcessorTest.java +++ b/engine/src/test/java/com/redhat/cloud/notifications/processors/camel/teams/TeamsProcessorTest.java @@ -24,6 +24,9 @@ public class TeamsProcessorTest extends CamelProcessorTest { private static final String TEAMS_EXPECTED_MSG = "<" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/inventory/6ad30f3e-0497-4e74-99f1-b3f9a6120a6f|my-computer> " + "triggered 1 event from rhel/policies. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open policies>"; + private static final String TEAMS_EXPECTED_MSG_WITH_HOST_URL = "<" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/inventory/6ad30f3e-0497-4e74-99f1-b3f9a6120a6f|my-computer> " + + "triggered 1 event from rhel/policies. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open policies>"; + @Inject TeamsProcessor teamsProcessor; @@ -33,8 +36,8 @@ protected String getQuteTemplate() { } @Override - protected String getExpectedMessage() { - return TEAMS_EXPECTED_MSG; + protected String getExpectedMessage(boolean withHostUrl) { + return withHostUrl ? TEAMS_EXPECTED_MSG_WITH_HOST_URL : TEAMS_EXPECTED_MSG; } @Override diff --git a/engine/src/test/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessorTest.java b/engine/src/test/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessorTest.java index 1067db67d1..229d13df58 100644 --- a/engine/src/test/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessorTest.java +++ b/engine/src/test/java/com/redhat/cloud/notifications/processors/pagerduty/PagerDutyProcessorTest.java @@ -130,8 +130,7 @@ void testPagerDutyUsingConnector() { payloadToSend.put("environment_url", environment.url()); insightsUrlsBuilder.buildInventoryUrl(payloadToSend) .ifPresent(url -> payloadToSend.put("inventory_url", url)); - insightsUrlsBuilder.buildApplicationUrl(payloadToSend) - .ifPresent(url -> payloadToSend.put("application_url", url)); + payloadToSend.put("application_url", insightsUrlsBuilder.buildApplicationUrl(payloadToSend)); payloadToSend.put("severity", PagerDutySeverity.ERROR); assertEquals(payloadToSend, payload.getJsonObject("payload"));