Skip to content

Commit

Permalink
Add host_url handling, db migration, proc tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jessicarod7 committed Dec 19, 2024
1 parent e3552b1 commit 8f61aa6
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ class InsightsUrlsBuilder {
* <p>An inventory URL will only be generated if fields from one of these two formats are present:</p>
*
* <ul>
* <li>{@code { "context": { "display_name": "non_empty_string" } }}</li>
* <li>{@code { "context": { "host_url": "non_empty_string" }}}</li>
* <li>{@code { "context": { "inventory_id": "non_empty_string" }}}</li>
* <li>{@code { "context": { "display_name": "non_empty_string" } }}</li>
* </ul>
*
* <p>If neither field is present, an {@link Optional#empty()} will be returned. If expected fields of
Expand All @@ -165,9 +166,19 @@ class InsightsUrlsBuilder {
static Optional<String> buildInventoryUrl(JsonObject data) {
String path;
ArrayList<String> 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 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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@ void testMissingEvents() {
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);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
UPDATE template
SET data = '{#if data.context.display_name??}<{data.inventory_url}|{data.context.display_name}> triggered {data.events.size()} event{#if data.events.size() \u003e 1}s{/if}{#else}{data.events.size()} event{#if data.events.size() \u003e 1}s{/if} triggered{/if} from {data.source.application.display_name} - {data.source.bundle.display_name}. <{data.application_url}|Open {data.source.application.display_name}>'
WHERE name = 'generic-slack';

UPDATE template
SET data = '{"text":"{#if data.context.display_name??}[{data.context.display_name}]({data.inventory_url}) triggered {data.events.size()} event{#if data.events.size() \u003e 1}s{/if}{#else}{data.events.size()} event{#if data.events.size() \u003e 1}s{/if} triggered{/if} from {data.source.application.display_name} - {data.source.bundle.display_name}. [Open {data.source.application.display_name}]({data.application_url})"}'
WHERE name = 'generic-teams';

UPDATE template
SET data = '{"text":"{#if data.context.display_name??}<{data.inventory_url}|{data.context.display_name}> triggered {data.events.size()} event{#if data.events.size() \u003e 1}s{/if}{#else}{data.events.size()} event{#if data.events.size() \u003e 1}s{/if} triggered{/if} from {data.source.application.display_name} - {data.source.bundle.display_name}. <{data.application_url}|Open {data.source.application.display_name}>"}'
WHERE name = 'generic-google-chat';
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ public class InsightsUrlsBuilder {
* <p>An inventory URL will only be generated if fields from one of these two formats are present:</p>
*
* <ul>
* <li>{@code { "context": { "display_name": "non_empty_string" } }}</li>
* <li>{@code { "context": { "host_url": "non_empty_string" } }}</li>
* <li>{@code { "context": { "inventory_id": "non_empty_string" }}}</li>
* <li>{@code { "context": { "display_name": "non_empty_string" } }}</li>
* </ul>
*
* <p>If neither field is present, an {@link Optional#empty()} will be returned. If expected fields of
Expand All @@ -36,10 +37,20 @@ public class InsightsUrlsBuilder {
public Optional<String> buildInventoryUrl(JsonObject data) {
String path;
ArrayList<String> 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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -82,25 +84,38 @@ void clearInMemorySink() {

protected abstract String getQuteTemplate();

protected abstract String getExpectedMessage();
protected abstract String getExpectedMessage(boolean withHostUrl);

protected abstract String getSubType();

protected abstract CamelProcessor getCamelProcessor();

@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<JsonObject> message = inMemorySink.received().get(0);
Expand All @@ -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<JsonObject> message) {
Expand All @@ -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())
Expand All @@ -163,7 +182,8 @@ protected static Event buildEvent() {
event.setId(UUID.randomUUID());
event.setOrgId(DEFAULT_ORG_ID);
event.setEventWrapper(new EventWrapperAction(action));
event.setApplicationDisplayName("policies");
event.setBundleDisplayName("Red Hat Enterprise Linux");
event.setApplicationDisplayName("Policies");
Application application = new Application();
application.setName("policies");
EventType eventType = new EventType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
public class GoogleChatProcessorTest extends CamelProcessorTest {

private static final String GOOGLE_CHAT_TEMPLATE = "{\"text\":\"{#if data.context.display_name??}" +
"<{data.environment_url}/insights/inventory/{data.context.inventory_id}|{data.context.display_name}> " +
"<{data.inventory_url}|{data.context.display_name}> " +
"triggered {data.events.size()} event{#if data.events.size() > 1}s{/if}" +
"{#else}{data.events.size()} event{#if data.events.size() > 1}s{/if} triggered{/if} " +
"from {data.bundle}/{data.application}. " +
"<{data.environment_url}/insights/{data.application}|Open {data.application}>\"}";
"{#else}{data.events.size()} event{#if data.events.size() > 1}s{/if} " +
"triggered{/if} from {data.source.application.display_name} - {data.source.bundle.display_name}. " +
"<{data.application_url}|Open {data.source.application.display_name}>\"}";

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>\"}";
"triggered 1 event from Policies - Red Hat Enterprise Linux. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open Policies>\"}";

private static final String GOOGLE_CHAT_EXPECTED_MSG_WITH_HOST_URL = "{\"text\":\"<" + CONTEXT_HOST_URL + "|my-computer> " +
"triggered 1 event from Policies - Red Hat Enterprise Linux. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open Policies>\"}";

@Inject
GoogleChatProcessor googleSpacesProcessor;
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ public class SlackProcessorTest extends CamelProcessorTest {
private static final String WEBHOOK_URL = "https://foo.bar";
private static final String CHANNEL = "#notifications";
private static final String SLACK_TEMPLATE = "{#if data.context.display_name??}" +
"<{data.environment_url}/insights/inventory/{data.context.inventory_id}|{data.context.display_name}> " +
"<{data.inventory_url}|{data.context.display_name}> " +
"triggered {data.events.size()} event{#if data.events.size() > 1}s{/if}" +
"{#else}{data.events.size()} event{#if data.events.size() > 1}s{/if} triggered{/if} " +
"from {data.bundle}/{data.application}. " +
"<{data.environment_url}/insights/{data.application}|Open {data.application}>";
"from {data.source.application.display_name} - {data.source.bundle.display_name}. " +
"<{data.application_url}|Open {data.source.application.display_name}>";
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>";
"triggered 1 event from Policies - Red Hat Enterprise Linux. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open Policies>";
private static final String SLACK_EXPECTED_MSG_WITH_HOST_URL = "<" + CONTEXT_HOST_URL + "|my-computer> " +
"triggered 1 event from Policies - Red Hat Enterprise Linux. <" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies|Open Policies>";

@Inject
SlackProcessor slackProcessor;
Expand All @@ -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
Expand All @@ -61,7 +63,7 @@ protected CamelProcessor getCamelProcessor() {
}

@Override
protected void verifyKafkaMessage() {
protected void verifyKafkaMessage(boolean withHostUrl) {

await().until(() -> inMemorySink.received().size() == 1);
Message<JsonObject> message = inMemorySink.received().get(0);
Expand All @@ -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
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@
@QuarkusTestResource(TestLifecycleManager.class)
public class TeamsProcessorTest extends CamelProcessorTest {

private static final String TEAMS_TEMPLATE = "{#if data.context.display_name??}" +
"<{data.environment_url}/insights/inventory/{data.context.inventory_id}|{data.context.display_name}> " +
private static final String TEAMS_TEMPLATE = "{\"text\":\"{#if data.context.display_name??}" +
"[{data.context.display_name}]({data.inventory_url}) " +
"triggered {data.events.size()} event{#if data.events.size() > 1}s{/if}" +
"{#else}{data.events.size()} event{#if data.events.size() > 1}s{/if} triggered{/if} " +
"from {data.bundle}/{data.application}. " +
"<{data.environment_url}/insights/{data.application}|Open {data.application}>";
"from {data.source.application.display_name} - {data.source.bundle.display_name}. " +
"[Open {data.source.application.display_name}]({data.application_url})\"}";

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 = "{\"text\":\"[my-computer](" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/inventory/6ad30f3e-0497-4e74-99f1-b3f9a6120a6f) " +
"triggered 1 event from Policies - Red Hat Enterprise Linux. [Open Policies](" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies)\"}";

private static final String TEAMS_EXPECTED_MSG_WITH_HOST_URL = "{\"text\":\"[my-computer](" + CONTEXT_HOST_URL + ") " +
"triggered 1 event from Policies - Red Hat Enterprise Linux. [Open Policies](" + EnvironmentTest.expectedTestEnvUrlValue + "/insights/policies)\"}";

@Inject
TeamsProcessor teamsProcessor;
Expand All @@ -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
Expand Down

0 comments on commit 8f61aa6

Please sign in to comment.