Skip to content

Commit

Permalink
[RHCLOUD-37252] Update new aggregation logic (#3233)
Browse files Browse the repository at this point in the history
Co-authored-by: Gwenneg Lepage <[email protected]>
  • Loading branch information
g-duval and gwenneg authored Jan 15, 2025
1 parent 712f149 commit 7d7a547
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,19 @@ public List<AggregationCommand> getApplicationsWithPendingAggregationAccordingOr
LocalDateTime currentTimeTwoDaysAgo = now.minusDays(2);
String query = "SELECT DISTINCT ev.orgId, ev.bundleId, ev.applicationId, acp.lastRun, bu.name, ap.name FROM Event ev " +
"join Application ap on ev.applicationId = ap.id join Bundle bu on ev.bundleId = bu.id " +
"join AggregationOrgConfig acp on ev.orgId = acp.orgId " +
"WHERE EXISTS (SELECT 1 FROM EventTypeEmailSubscription es where ev.orgId = es.id.orgId and es.id.subscriptionType='DAILY' and es.subscribed = true) " +
"join AggregationOrgConfig acp on ev.orgId = acp.orgId WHERE " +

// check than a aggregation template exists for the event application
"EXISTS (SELECT 1 FROM AggregationEmailTemplate WHERE application.id = ev.applicationId and subscriptionType = 'DAILY') " +
// After prod validation phase, the previous AggregationEmailTemplate check should be remove in favor of:
// check than at least one user of the org subscribed for daily digest with this event type
//"EXISTS (SELECT 1 FROM EventTypeEmailSubscription es where ev.orgId = es.id.orgId and es.id.subscriptionType='DAILY' and es.eventType = ev.eventType and es.subscribed is true) " + warning: need an new index on EventTypeEmailSubscription before being enabled

// check for linked email integration linked to this event type (to honor legacy mechanism)
"AND EXISTS (SELECT 1 FROM Endpoint ep, EndpointEventType eet where ev.orgId = ep.orgId and ep.compositeType.type = 'EMAIL_SUBSCRIPTION' and eet.eventType = ev.eventType and eet.endpoint = ep) " +
// filter on new events since the latest run of this org aggregation, and not older than two days
"AND ev.created > acp.lastRun AND ev.created > :twoDaysAgo AND ev.created <= :now " +
// filter on org scheduled execution time
"AND :nowTime = acp.scheduledExecutionTime";
Query hqlQuery = entityManager.createQuery(query)
.setParameter("nowTime", now.toLocalTime())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
import com.redhat.cloud.notifications.models.AggregationOrgConfig;
import com.redhat.cloud.notifications.models.Application;
import com.redhat.cloud.notifications.models.EventAggregationCriteria;
import com.redhat.cloud.notifications.models.EventType;
import com.redhat.cloud.notifications.models.SubscriptionType;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Gauge;
import io.quarkus.test.common.QuarkusTestResource;
Expand All @@ -33,7 +31,6 @@
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;

import static com.redhat.cloud.notifications.models.SubscriptionType.DAILY;
Expand Down Expand Up @@ -432,20 +429,7 @@ private com.redhat.cloud.notifications.models.Event addEventEmailAggregation(Str
}

private com.redhat.cloud.notifications.models.Event addEventEmailAggregation(String orgId, String bundleName, String applicationName, String policyId, String inventoryId, LocalDateTime created) {
Application application = resourceHelpers.findOrCreateApplication(bundleName, applicationName);
EventType eventType = resourceHelpers.findOrCreateEventType(application.getId(), "event_type_test");
resourceHelpers.findOrCreateEventTypeEmailSubscription(orgId, "obiwan", eventType, SubscriptionType.DAILY);

com.redhat.cloud.notifications.models.Event event = new com.redhat.cloud.notifications.models.Event();
event.setId(UUID.randomUUID());
event.setOrgId(orgId);
eventType.setApplication(application);
event.setEventType(eventType);
event.setPayload(
TestHelpers.generatePayloadContent(orgId, bundleName, applicationName, policyId, inventoryId).toString()
);
event.setCreated(created);

return resourceHelpers.createEvent(event);
final String payload = TestHelpers.generatePayloadContent(orgId, bundleName, applicationName, policyId, inventoryId).toString();
return resourceHelpers.addEventEmailAggregation(orgId, bundleName, applicationName, created, payload);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
import com.redhat.cloud.notifications.models.EmailAggregationKey;
import com.redhat.cloud.notifications.models.Event;
import com.redhat.cloud.notifications.models.EventAggregationCriteria;
import com.redhat.cloud.notifications.models.EventType;
import com.redhat.cloud.notifications.models.SubscriptionType;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.vertx.core.json.JsonObject;
Expand All @@ -23,7 +21,6 @@
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -101,11 +98,11 @@ private void addEmailAggregation(String orgId, String bundleName, String applica
@Test
void testApplicationsWithPendingAggregationAccordingOrgPref() {
configureTimePref(dailyEmailAggregationJob.computeScheduleExecutionTime());
Event event1 = addEventEmailAggregation(ORG_ID, BUNDLE_NAME, APP_NAME, PAYLOAD1, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5));
Event event2 = addEventEmailAggregation(ORG_ID, BUNDLE_NAME, APP_NAME, PAYLOAD2, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5));
addEventEmailAggregation("other-org-id", BUNDLE_NAME, APP_NAME, PAYLOAD2, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5));
addEventEmailAggregation(ORG_ID, "other-bundle", APP_NAME, PAYLOAD2, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5));
addEventEmailAggregation(ORG_ID, BUNDLE_NAME, "other-app", PAYLOAD2, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5));
Event event1 = resourceHelpers.addEventEmailAggregation(ORG_ID, BUNDLE_NAME, APP_NAME, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5), PAYLOAD1.toString());
Event event2 = resourceHelpers.addEventEmailAggregation(ORG_ID, BUNDLE_NAME, APP_NAME, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5), PAYLOAD2.toString());
resourceHelpers.addEventEmailAggregation("other-org-id", BUNDLE_NAME, APP_NAME, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5), PAYLOAD2.toString());
resourceHelpers.addEventEmailAggregation(ORG_ID, "other-bundle", APP_NAME, dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5), PAYLOAD2.toString());
resourceHelpers.addEventEmailAggregation(ORG_ID, BUNDLE_NAME, "other-app", dailyEmailAggregationJob.computeScheduleExecutionTime().minusMinutes(5), PAYLOAD2.toString());

List<AggregationCommand> keys = emailAggregationResources.getApplicationsWithPendingAggregationAccordingOrgPref(dailyEmailAggregationJob.computeScheduleExecutionTime());
assertEquals(4, keys.size());
Expand All @@ -124,20 +121,4 @@ void testApplicationsWithPendingAggregationAccordingOrgPref() {
matchedKeys = keys.stream().filter(k -> ORG_ID.equals(k.getOrgId())).filter(k -> (((EventAggregationCriteria) k.getAggregationKey()).getApplicationId().equals(application.getId()))).collect(Collectors.toList());
assertEquals(0, matchedKeys.size());
}

private Event addEventEmailAggregation(String orgId, String bundleName, String applicationName, JsonObject payload, LocalDateTime created) {
Application application = resourceHelpers.findOrCreateApplication(bundleName, applicationName);
EventType eventType = resourceHelpers.findOrCreateEventType(application.getId(), "event_type_test");
resourceHelpers.findOrCreateEventTypeEmailSubscription(orgId, "obiwan", eventType, SubscriptionType.DAILY);

Event event = new Event();
event.setId(UUID.randomUUID());
event.setOrgId(orgId);
eventType.setApplication(application);
event.setEventType(eventType);
event.setPayload(payload.toString());
event.setCreated(created);

return resourceHelpers.createEvent(event);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
package com.redhat.cloud.notifications.helpers;

import com.redhat.cloud.notifications.models.AggregationEmailTemplate;
import com.redhat.cloud.notifications.models.AggregationOrgConfig;
import com.redhat.cloud.notifications.models.Application;
import com.redhat.cloud.notifications.models.EmailAggregation;
import com.redhat.cloud.notifications.models.EmailAggregationKey;
import com.redhat.cloud.notifications.models.Endpoint;
import com.redhat.cloud.notifications.models.EndpointType;
import com.redhat.cloud.notifications.models.Event;
import com.redhat.cloud.notifications.models.EventType;
import com.redhat.cloud.notifications.models.SubscriptionType;
import com.redhat.cloud.notifications.models.Template;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.EntityManager;
import jakarta.persistence.NoResultException;
import jakarta.transaction.Transactional;
import org.apache.commons.lang3.RandomStringUtils;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@ApplicationScoped
public class ResourceHelpers extends com.redhat.cloud.notifications.models.ResourceHelpers {
Expand Down Expand Up @@ -75,4 +88,78 @@ public Integer purgeOldAggregation(EmailAggregationKey key, LocalDateTime lastUs
.setParameter("created", lastUsedTime)
.executeUpdate();
}

@Transactional
public Endpoint getOrCreateEmailEndpointAndLinkItToEventType(final String orgId, final EventType eventType) {
Endpoint emailEndpoint;
try {
final String query = "FROM Endpoint WHERE orgId = :orgId AND compositeType.type = :type";
emailEndpoint = entityManager.createQuery(query, Endpoint.class)
.setParameter("orgId", orgId)
.setParameter("type", EndpointType.EMAIL_SUBSCRIPTION)
.getSingleResult();
} catch (NoResultException e) {
emailEndpoint = new Endpoint();
emailEndpoint.setType(EndpointType.EMAIL_SUBSCRIPTION);
emailEndpoint.setOrgId(orgId);
emailEndpoint.setName(RandomStringUtils.secure().nextAlphabetic(10));
emailEndpoint.setDescription(RandomStringUtils.randomAlphabetic(10));
entityManager.persist(emailEndpoint);
}

Set<EventType> linkedEventTypes = emailEndpoint.getEventTypes();
if (linkedEventTypes == null) {
linkedEventTypes = new HashSet<>();
}
linkedEventTypes.add(eventType);
emailEndpoint.setEventTypes(linkedEventTypes);
return entityManager.merge(emailEndpoint);
}

@Transactional
public AggregationEmailTemplate getOrCreateAggregationTemplate(Application application) {
try {
String query = "FROM AggregationEmailTemplate WHERE application.id = :appId";
return entityManager.createQuery(query, AggregationEmailTemplate.class)
.setParameter("appId", application.getId())
.getSingleResult();
} catch (NoResultException e) {
Template emailTemplate = new Template();
emailTemplate.setName(RandomStringUtils.randomAlphabetic(10));
emailTemplate.setData(RandomStringUtils.randomAlphabetic(10));
emailTemplate.setDescription(RandomStringUtils.randomAlphabetic(10));
entityManager.persist(emailTemplate);

AggregationEmailTemplate aggregationEmailTemplate = new AggregationEmailTemplate();
aggregationEmailTemplate.setApplication(application);
aggregationEmailTemplate.setApplicationId(application.getId());
aggregationEmailTemplate.setSubscriptionType(SubscriptionType.DAILY);
aggregationEmailTemplate.setBodyTemplate(emailTemplate);
aggregationEmailTemplate.setBodyTemplateId(emailTemplate.getId());
aggregationEmailTemplate.setSubjectTemplate(emailTemplate);
aggregationEmailTemplate.setSubjectTemplateId(emailTemplate.getId());
aggregationEmailTemplate.setApplication(application);
entityManager.persist(aggregationEmailTemplate);
return aggregationEmailTemplate;
}
}

public Event addEventEmailAggregation(String orgId, String bundleName, String applicationName, LocalDateTime created, String eventPayload) {
Application application = findOrCreateApplication(bundleName, applicationName);
EventType eventType = findOrCreateEventType(application.getId(), "event_type_test");
findOrCreateEventTypeEmailSubscription(orgId, "obiwan", eventType, SubscriptionType.DAILY);

getOrCreateEmailEndpointAndLinkItToEventType(orgId, eventType);
getOrCreateAggregationTemplate(application);

Event event = new Event();
event.setId(UUID.randomUUID());
event.setOrgId(orgId);
eventType.setApplication(application);
event.setEventType(eventType);
event.setCreated(created);
event.setPayload(eventPayload);

return createEvent(event);
}
}

0 comments on commit 7d7a547

Please sign in to comment.