Skip to content

Commit

Permalink
[RHCLOUD-22813] Handle provided context.host_url in integration templ…
Browse files Browse the repository at this point in the history
…ates (#3221)

* add inventory uri builder

* add application uri builder

* add Insights URL gen to processors & PD connector

CamelProcessor tests and db migration not completed yet

* Add host_url handling, proc tests

* remove PagerDuty dup of InsightsUrlsBuilder

* InsightsUrlBuilder switch to isBlank

* fix .links in PagerDutyTransformer

added test cases based on IQE input
  • Loading branch information
jessicarod7 authored Jan 24, 2025
1 parent bf30c12 commit 3cb75a0
Show file tree
Hide file tree
Showing 11 changed files with 381 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.redhat.cloud.notifications.connector.pagerduty;

import io.quarkus.logging.Log;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import jakarta.enterprise.context.ApplicationScoped;
import org.apache.camel.Exchange;
Expand All @@ -25,6 +26,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";
Expand All @@ -36,12 +38,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");

Expand All @@ -53,6 +59,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));
Expand Down Expand Up @@ -92,7 +99,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()) {
Expand Down Expand Up @@ -155,7 +164,36 @@ private JsonObject getClientLink(final JsonObject cloudEventPayload, String envi
return clientLink;
}

private JsonObject getSourceNames(final JsonObject cloudSource) {
/**
* Performs the following link conversions:
* <ul>
* <li>{@link #APPLICATION} integrated into {@link #CLIENT}</li>
* <li>{@link #APPLICATION_URL} becomes {@link #CLIENT_URL}</li>
* <li>{@link #INVENTORY_URL}, if present, creates an entry in the {@link #LINKS} object</li>
* </ul>
* <p>
* 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, JsonArray.of(
JsonObject.of(
HREF, inventoryUrl,
TEXT, "Host"
)
));
}

return clientLinks;
}

static JsonObject getSourceNames(final JsonObject cloudSource) {
if (cloudSource != null) {
JsonObject sourceNames = new JsonObject();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,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;
Expand All @@ -23,6 +24,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;
Expand All @@ -31,9 +33,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());
Expand All @@ -56,6 +62,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"),
Expand All @@ -77,6 +87,8 @@ static JsonObject createIncomingPayload(JsonObject cloudEventData) {

payload.put(SOURCE, source);
payload.put(ENVIRONMENT_URL, "https://console.redhat.com");
payload.put(INVENTORY_URL, "https://console.redhat.com/insights/inventory/8a4a4f75-5319-4255-9eb5-1ee5a92efd7f");
payload.put(APPLICATION_URL, "https://console.redhat.com/insights/default-application");
payload.put(SEVERITY, PagerDutySeverity.WARNING);
cloudEventData.put(PAYLOAD, payload);

Expand All @@ -91,6 +103,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));
Expand Down Expand Up @@ -159,29 +172,4 @@ private static JsonObject getClientLink(final JsonObject oldInnerPayload, String

return clientLink;
}

private static JsonObject getSourceNames(final JsonObject oldInnerSourceNames) {
if (oldInnerSourceNames != null) {
JsonObject newInnerSourceNames = new JsonObject();

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));
}

if (!newInnerSourceNames.isEmpty()) {
return newInnerSourceNames;
}
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -108,13 +113,48 @@ void testSuccessfulTestMessage() {
);
cloudEventPayload.put("recipients", JsonArray.of());
cloudEventPayload.put("environment_url", "https://console.redhat.com");
// No inventory_url generated
cloudEventPayload.put("application_url", "https://console.redhat.com/settings/integrations");
cloudEventPayload.put("severity", "warning");
cloudEventData.put(PAYLOAD, cloudEventPayload);

JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData);
validatePayloadTransform(cloudEventData, expectedPayload);
}

@Test
void testSuccessfulIqeTestMessage() {
JsonObject cloudEventData = createIncomingPayload(TEST_URL);
JsonObject cloudEventPayload = JsonObject.of(
"account_id", "default-account-id",
"application", "inventory",
"bundle", "rhel",
"context", JsonObject.of(
"inventory_id", "85094ed1-1c52-4bc5-8e3e-4ea3869a17ce",
"hostname", "rhiqe.2349fj.notif-test",
"display_name", "rhiqe.2349fj.notif-test",
"rhel_version", "8.0"
),
"event_type", "new-system-registered",
"events", JsonArray.of(),
"org_id", "default-org-id",
"timestamp", "2020-10-03T15:22:13.000000025",
"source", JsonObject.of(
"application", JsonObject.of("display_name", "Inventory"),
"bundle", JsonObject.of("display_name", "Red Hat Enterprise Linux"),
"event_type", JsonObject.of("display_name", "New system registered")
),
"environment_url", "https://localhost"
);
cloudEventPayload.put("inventory_url", "https://localhost/insights/inventory/85094ed1-1c52-4bc5-8e3e-4ea3869a17ce");
cloudEventPayload.put("application_url", "https://localhost/insights/inventory");
cloudEventPayload.put("severity", "error");
cloudEventData.put("payload", cloudEventPayload);

JsonObject expectedPayload = buildExpectedOutgoingPayload(cloudEventData);
validatePayloadTransform(cloudEventData, expectedPayload);
}

@Test
void testInvalidTimestampDropped() {
JsonObject cloudEventData = createIncomingPayload(TEST_URL);
Expand All @@ -130,8 +170,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);
Expand All @@ -142,10 +181,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);
Expand All @@ -167,7 +203,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);
Expand All @@ -187,6 +222,28 @@ 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);
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);
Expand All @@ -196,6 +253,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);
Expand All @@ -211,6 +276,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<? extends Throwable> exceptionType, String exceptionMessage) {
Exchange exchange = createExchangeWithBody(context, "I am not used!");

Expand All @@ -219,7 +294,6 @@ void verifyTransformExceptionThrown(JsonObject cloudEventData, Class<? extends T
}

/**
*
* @param cloudEventData the cloud event, as provided to the connector
* @param expectedPayload the PagerDuty payload expected to be sent
*/
Expand Down
Loading

0 comments on commit 3cb75a0

Please sign in to comment.