Skip to content

Commit

Permalink
Add host_url handling, proc tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jessicarod7 committed Jan 7, 2025
1 parent bca2353 commit 7c24129
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -189,8 +188,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 @@ -202,23 +202,34 @@ 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();
}

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()) {
Expand All @@ -232,34 +243,30 @@ static Optional<String> buildInventoryUrl(JsonObject data) {
/**
* <p>Constructs an Insights URL corresponding to the specific inventory item which generated the notification.</p>
*
* <p>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
* <p>If the expected fields {@link Action#getApplication()} and {@link Action#getBundle()} are not present, an
* inaccurate URL may be returned.</p>
*
* @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<String> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down
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,24 +37,35 @@ 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")
&& 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()) {
Expand All @@ -67,36 +79,32 @@ public Optional<String> buildInventoryUrl(JsonObject data) {
/**
* <p>Constructs an Insights URL corresponding to the specific inventory item which generated the notification.</p>
*
* <p>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
* <p>If the expected fields {@link Action#getApplication()} and {@link Action#getBundle()} are not present, an
* inaccurate URL may be returned.</p>
*
* @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<String> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Object, Object> dataAsMap;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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
Loading

0 comments on commit 7c24129

Please sign in to comment.