From 3458bf0859f93e5c39db2a6245e29516c04a3d20 Mon Sep 17 00:00:00 2001 From: Gwenneg Lepage Date: Sat, 28 Oct 2023 13:46:46 +0200 Subject: [PATCH] RHCLOUD-28942 --- .rhcicd/clowdapp-connector-email.yaml | 5 ++ .rhcicd/clowdapp-engine.yaml | 5 ++ .../notifications/config/FeatureFlipper.java | 13 ++++ .../connector/email/EmailRouteBuilder.java | 17 ++--- .../aggregation/UserAggregationStrategy.java | 5 +- .../email/config/EmailConnectorConfig.java | 9 +++ .../email/constants/ExchangeProperty.java | 4 +- .../connector/email/model/bop/Emails.java | 27 -------- .../email/model/bop/SendEmailsRequest.java | 25 ++++++++ .../connector/email/model/settings/User.java | 62 +++++++++++++++++++ .../processors/bop/BOPRequestPreparer.java | 28 ++++++--- .../processors/it/ITResponseProcessor.java | 38 +++++++++++- .../processors/rbac/RBACUsersProcessor.java | 15 ++++- .../recipients/RecipientsFilter.java | 11 ++-- .../email/EmailRouteBuilderTest.java | 2 +- .../UserAggregationStrategyTest.java | 8 +-- .../bop/BOPRequestPreparerTest.java | 17 +++-- .../it/ITResponseProcessorTest.java | 8 +-- .../rbac/RBACUsersProcessorTest.java | 12 ++-- .../recipients/RecipientsFilterTest.java | 12 ++-- .../processors/email/EmailSender.java | 22 ++++--- .../processors/email/Emails.java | 24 ------- .../processors/email/SendEmailsRequest.java | 22 +++++++ .../src/main/resources/application.properties | 2 +- .../notifications/recipients/model/User.java | 9 +++ .../FetchUsersFromExternalServices.java | 9 +++ 26 files changed, 294 insertions(+), 117 deletions(-) delete mode 100644 connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/bop/Emails.java create mode 100644 connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/bop/SendEmailsRequest.java create mode 100644 connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/settings/User.java delete mode 100644 engine/src/main/java/com/redhat/cloud/notifications/processors/email/Emails.java create mode 100644 engine/src/main/java/com/redhat/cloud/notifications/processors/email/SendEmailsRequest.java diff --git a/.rhcicd/clowdapp-connector-email.yaml b/.rhcicd/clowdapp-connector-email.yaml index 4f6aadbbd9..f43eba4020 100644 --- a/.rhcicd/clowdapp-connector-email.yaml +++ b/.rhcicd/clowdapp-connector-email.yaml @@ -70,6 +70,8 @@ objects: env: - name: ENV_NAME value: ${ENV_NAME} + - name: NOTIFICATIONS_CONNECTOR_BOP_SKIP_USERS_RESOLUTION_ENABLED + value: ${NOTIFICATIONS_CONNECTOR_BOP_SKIP_USERS_RESOLUTION_ENABLED} - name: NOTIFICATIONS_CONNECTOR_ENDPOINT_CACHE_MAX_SIZE value: ${NOTIFICATIONS_CONNECTOR_ENDPOINT_CACHE_MAX_SIZE} - name: NOTIFICATIONS_CONNECTOR_FETCH_USERS_RBAC_ENABLED @@ -205,6 +207,9 @@ parameters: - name: MIN_REPLICAS value: "3" +- name: NOTIFICATIONS_CONNECTOR_BOP_SKIP_USERS_RESOLUTION_ENABLED + description: Should BOP transform usernames from our payload into email addresses using the IT Users Service? + value: "false" - name: NOTIFICATIONS_CONNECTOR_ENDPOINT_CACHE_MAX_SIZE description: Maximum size of the Camel endpoints cache value: "100" diff --git a/.rhcicd/clowdapp-engine.yaml b/.rhcicd/clowdapp-engine.yaml index cc6213e45d..59232d63fc 100644 --- a/.rhcicd/clowdapp-engine.yaml +++ b/.rhcicd/clowdapp-engine.yaml @@ -150,6 +150,8 @@ objects: key: client-id - name: PROCESSOR_EMAIL_BOP_ENV value: ${BACKOFFICE_CLIENT_ENV} + - name: PROCESSOR_EMAIL_BOP_SKIP_USERS_RESOLUTION_ENABLED + value: ${PROCESSOR_EMAIL_BOP_SKIP_USERS_RESOLUTION_ENABLED} - name: PROCESSOR_EMAIL_BOP_URL value: ${BACKOFFICE_SCHEME}://${BACKOFFICE_HOST}:${BACKOFFICE_PORT}/v1/sendEmails - name: PROCESSOR_EMAIL_NO_REPLY @@ -330,6 +332,9 @@ parameters: - name: NOTIFICATIONS_LOG_LEVEL description: Log level for com.redhat.cloud.notifications value: INFO +- name: PROCESSOR_EMAIL_BOP_SKIP_USERS_RESOLUTION_ENABLED + description: Should BOP transform usernames from our payload into email addresses using the IT Users Service? + value: "false" - name: QUARKUS_HIBERNATE_ORM_LOG_SQL value: "false" - name: QUARKUS_LOG_CLOUDWATCH_API_CALL_TIMEOUT diff --git a/common/src/main/java/com/redhat/cloud/notifications/config/FeatureFlipper.java b/common/src/main/java/com/redhat/cloud/notifications/config/FeatureFlipper.java index dcde47bdfa..e6dbdf7389 100644 --- a/common/src/main/java/com/redhat/cloud/notifications/config/FeatureFlipper.java +++ b/common/src/main/java/com/redhat/cloud/notifications/config/FeatureFlipper.java @@ -98,6 +98,9 @@ public class FeatureFlipper { @ConfigProperty(name = "notifications.async-aggregation.enabled", defaultValue = "true") boolean asyncAggregation; + @ConfigProperty(name = "notifications.email.send-emails-to-bop", defaultValue = "false") + boolean sendEmailstoBop; + void logFeaturesStatusAtStartup(@Observes StartupEvent event) { Log.infof("=== %s startup status ===", FeatureFlipper.class.getSimpleName()); Log.infof("The behavior groups unique name constraint is %s", enforceBehaviorGroupNameUnicity ? "enabled" : "disabled"); @@ -120,6 +123,7 @@ void logFeaturesStatusAtStartup(@Observes StartupEvent event) { Log.infof("The email connector is %s", emailConnectorEnabled ? "enabled" : "disabled"); Log.infof("The drawer connector is %s", drawerConnectorEnabled ? "enabled" : "disabled"); Log.infof("The async aggregation is %s", asyncAggregation ? "enabled" : "disabled"); + Log.infof("Send emails to BOP is %s", sendEmailstoBop ? "enabled" : "disabled"); } public boolean isEnforceBehaviorGroupNameUnicity() { @@ -298,6 +302,15 @@ public void setAsyncAggregation(boolean asyncAggregation) { this.asyncAggregation = asyncAggregation; } + public boolean isSendEmailstoBop() { + return sendEmailstoBop; + } + + public void setSendEmailstoBop(boolean sendEmailstoBop) { + checkTestLaunchMode(); + this.sendEmailstoBop = sendEmailstoBop; + } + /** * This method throws an {@link IllegalStateException} if it is invoked with a launch mode different from * {@link io.quarkus.runtime.LaunchMode#TEST TEST}. It should be added to methods that allow overriding a diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/EmailRouteBuilder.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/EmailRouteBuilder.java index de9fd60282..f864ab3cd9 100644 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/EmailRouteBuilder.java +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/EmailRouteBuilder.java @@ -7,6 +7,7 @@ import com.redhat.cloud.notifications.connector.email.config.Environment; import com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty; import com.redhat.cloud.notifications.connector.email.constants.Routes; +import com.redhat.cloud.notifications.connector.email.model.settings.User; import com.redhat.cloud.notifications.connector.email.predicates.NotFinishedFetchingAllPages; import com.redhat.cloud.notifications.connector.email.predicates.rbac.StatusCodeNotFound; import com.redhat.cloud.notifications.connector.email.processors.bop.BOPRequestPreparer; @@ -156,7 +157,7 @@ public void configureRoute() throws Exception { .routeId(this.connectorConfig.getConnectorName()) // Initialize the usernames hash set, where we will gather the // fetched users from the user providers. - .process(exchange -> exchange.setProperty(ExchangeProperty.USERNAMES, new HashSet())) + .process(exchange -> exchange.setProperty(ExchangeProperty.USERS, new HashSet())) // Split each recipient setting and aggregate the usernames to end // up with a single exchange. .split(simpleF("${exchangeProperty.%s}", ExchangeProperty.RECIPIENT_SETTINGS), this.userAggregationStrategy).stopOnException() @@ -201,7 +202,7 @@ public void configureRoute() throws Exception { // The cache engine leaves the usernames in the body of the // exchange, that is why we need to set them back in the // property that the subsequent processors expect to find them. - .setProperty(ExchangeProperty.USERNAMES, body()) + .setProperty(ExchangeProperty.USERS, body()) .otherwise() // Clear all the headers that may come from the previous route. .removeHeaders("*") @@ -220,7 +221,7 @@ public void configureRoute() throws Exception { // Store all the received recipients in the cache. .setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_PUT)) .setHeader(CaffeineConstants.KEY, this.computeCacheKey()) - .setHeader(CaffeineConstants.VALUE, exchangeProperty(ExchangeProperty.USERNAMES)) + .setHeader(CaffeineConstants.VALUE, exchangeProperty(ExchangeProperty.USERS)) .to(caffeineCache(Routes.FETCH_USERS_RBAC)) .endChoice() .end() @@ -249,7 +250,7 @@ public void configureRoute() throws Exception { // The cache engine leaves the usernames in the body of the // exchange, that is why we need to set them back in the // property that the subsequent processors expect to find them. - .setProperty(ExchangeProperty.USERNAMES, body()) + .setProperty(ExchangeProperty.USERS, body()) .otherwise() // Clear all the headers that may come from the previous route. .removeHeaders("*") @@ -266,7 +267,7 @@ public void configureRoute() throws Exception { // Store all the received recipients in the cache. .setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_PUT)) .setHeader(CaffeineConstants.KEY, this.computeCacheKey()) - .setHeader(CaffeineConstants.VALUE, exchangeProperty(ExchangeProperty.USERNAMES)) + .setHeader(CaffeineConstants.VALUE, exchangeProperty(ExchangeProperty.USERS)) .to(caffeineCache(Routes.FETCH_USERS_IT)) .endChoice() .end() @@ -312,7 +313,7 @@ public void configureRoute() throws Exception { // The cache engine leaves the usernames in the body of the // exchange, that is why we need to set them back in the // property that the subsequent processors expect to find them. - .setProperty(ExchangeProperty.USERNAMES, body()) + .setProperty(ExchangeProperty.USERS, body()) .otherwise() // Clear all the headers that may come from the previous route. .removeHeaders("*") @@ -328,7 +329,7 @@ public void configureRoute() throws Exception { // Store all the received recipients in the cache. .setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_PUT)) .setHeader(CaffeineConstants.KEY, this.computeGroupPrincipalsCacheKey()) - .setHeader(CaffeineConstants.VALUE, exchangeProperty(ExchangeProperty.USERNAMES)) + .setHeader(CaffeineConstants.VALUE, exchangeProperty(ExchangeProperty.USERS)) .to(caffeineCache(Routes.FETCH_GROUP_USERS)) .endChoice() .end() @@ -366,7 +367,7 @@ public void configureRoute() throws Exception { .routeId(Routes.SEND_EMAIL_BOP_SINGLE_PER_USER) // Clear all the headers that may come from the previous route. .removeHeaders("*") - .split(simpleF("${exchangeProperty.%s}", ExchangeProperty.FILTERED_USERNAMES)) + .split(simpleF("${exchangeProperty.%s}", ExchangeProperty.FILTERED_USERS)) .setProperty(ExchangeProperty.SINGLE_EMAIL_PER_USER, constant(true)) .to(direct(Routes.SEND_EMAIL_BOP)) .end(); diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/aggregation/UserAggregationStrategy.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/aggregation/UserAggregationStrategy.java index 6e6be6ed0a..354a5b34ed 100644 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/aggregation/UserAggregationStrategy.java +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/aggregation/UserAggregationStrategy.java @@ -1,6 +1,7 @@ package com.redhat.cloud.notifications.connector.email.aggregation; import com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty; +import com.redhat.cloud.notifications.connector.email.model.settings.User; import jakarta.enterprise.context.ApplicationScoped; import org.apache.camel.AggregationStrategy; import org.apache.camel.Exchange; @@ -24,8 +25,8 @@ public Exchange aggregate(final Exchange oldExchange, final Exchange newExchange return newExchange; } - final Set oldFilteredUsers = oldExchange.getProperty(ExchangeProperty.FILTERED_USERNAMES, Set.class); - final Set newFilteredUsers = newExchange.getProperty(ExchangeProperty.FILTERED_USERNAMES, Set.class); + final Set oldFilteredUsers = oldExchange.getProperty(ExchangeProperty.FILTERED_USERS, Set.class); + final Set newFilteredUsers = newExchange.getProperty(ExchangeProperty.FILTERED_USERS, Set.class); if (newFilteredUsers != null) { oldFilteredUsers.addAll(newFilteredUsers); diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/config/EmailConnectorConfig.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/config/EmailConnectorConfig.java index 21c9422601..8baf1ac7a1 100644 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/config/EmailConnectorConfig.java +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/config/EmailConnectorConfig.java @@ -27,6 +27,7 @@ public class EmailConnectorConfig extends ConnectorConfig { private static final String RBAC_APPLICATION_KEY = "notifications.connector.user-provider.rbac.application-key"; private static final String RBAC_ELEMENTS_PAGE = "notifications.connector.user-provider.rbac.elements-per-page"; private static final String RBAC_URL = "notifications.connector.user-provider.rbac.url"; + private static final String SKIP_BOP_USERS_RESOLUTION = "notifications.connector.bop.skip-users-resolution.enabled"; @Deprecated(forRemoval = true) public static final String SINGLE_EMAIL_PER_USER = "notifications.connector.single-email-per-user.enabled"; @@ -97,6 +98,9 @@ public class EmailConnectorConfig extends ConnectorConfig { @ConfigProperty(name = USER_PROVIDER_CACHE_EXPIRE_AFTER_WRITE, defaultValue = "600") int userProviderCacheExpireAfterWrite; + @ConfigProperty(name = SKIP_BOP_USERS_RESOLUTION, defaultValue = "false") + boolean skipBopUsersResolution; + @Override public void log() { final Map additionalEntries = new HashMap<>(); @@ -115,6 +119,7 @@ public void log() { additionalEntries.put(RBAC_URL, this.rbacURL); additionalEntries.put(SINGLE_EMAIL_PER_USER, this.singleEmailPerUserEnabled); additionalEntries.put(USER_PROVIDER_CACHE_EXPIRE_AFTER_WRITE, this.userProviderCacheExpireAfterWrite); + additionalEntries.put(SKIP_BOP_USERS_RESOLUTION, skipBopUsersResolution); log(additionalEntries); } @@ -219,4 +224,8 @@ public boolean isSingleEmailPerUserEnabled() { public int getUserProviderCacheExpireAfterWrite() { return userProviderCacheExpireAfterWrite; } + + public boolean isSkipBopUsersResolution() { + return skipBopUsersResolution; + } } diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/constants/ExchangeProperty.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/constants/ExchangeProperty.java index 67212bbf52..4d10229f73 100644 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/constants/ExchangeProperty.java +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/constants/ExchangeProperty.java @@ -15,7 +15,7 @@ public class ExchangeProperty { * Holds the filtered usernames. It is used in order to avoid the set of * cached usernames from being modified. */ - public static final String FILTERED_USERNAMES = "usernames_filtered"; + public static final String FILTERED_USERS = "users_filtered"; /** * Used to hold the received RBAC group's UUID. */ @@ -55,5 +55,5 @@ public class ExchangeProperty { * notification through email. Since only usernames are required in order * to send the emails, we will only grab those. */ - public static final String USERNAMES = "usernames"; + public static final String USERS = "users"; } diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/bop/Emails.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/bop/Emails.java deleted file mode 100644 index 5767da6305..0000000000 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/bop/Emails.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.redhat.cloud.notifications.connector.email.model.bop; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.HashSet; -import java.util.Set; - -/** - * Represents the payload to be sent to BOP/MBOP. - */ -public class Emails { - - @JsonProperty("emails") - private final Set emails; - - public Emails() { - this.emails = new HashSet<>(); - } - - public void addEmail(final Email email) { - this.emails.add(email); - } - - public Set getEmails() { - return this.emails; - } -} diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/bop/SendEmailsRequest.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/bop/SendEmailsRequest.java new file mode 100644 index 0000000000..722b2919b3 --- /dev/null +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/bop/SendEmailsRequest.java @@ -0,0 +1,25 @@ +package com.redhat.cloud.notifications.connector.email.model.bop; + +import java.util.HashSet; +import java.util.Set; + +/** + * Represents the payload to be sent to BOP/MBOP. + */ +public class SendEmailsRequest { + + private final Set emails = new HashSet<>(); + private final boolean skipUsersResolution; + + public SendEmailsRequest(boolean skipUsersResolution) { + this.skipUsersResolution = skipUsersResolution; + } + + public Set getEmails() { + return emails; + } + + public boolean isSkipUsersResolution() { + return skipUsersResolution; + } +} diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/settings/User.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/settings/User.java new file mode 100644 index 0000000000..155de1de92 --- /dev/null +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/model/settings/User.java @@ -0,0 +1,62 @@ +package com.redhat.cloud.notifications.connector.email.model.settings; + +import java.util.Objects; + +public class User { + + private String id; + private String username; + private String email; + private boolean admin; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public boolean isAdmin() { + return admin; + } + + public void setAdmin(boolean admin) { + this.admin = admin; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof User)) { + return false; + } + + User user = (User) o; + return Objects.equals(username, user.username); + } + + @Override + public int hashCode() { + return Objects.hash(username); + } +} diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/bop/BOPRequestPreparer.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/bop/BOPRequestPreparer.java index e7db8b6e37..2732c593d1 100644 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/bop/BOPRequestPreparer.java +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/bop/BOPRequestPreparer.java @@ -3,7 +3,8 @@ import com.redhat.cloud.notifications.connector.email.config.EmailConnectorConfig; import com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty; import com.redhat.cloud.notifications.connector.email.model.bop.Email; -import com.redhat.cloud.notifications.connector.email.model.bop.Emails; +import com.redhat.cloud.notifications.connector.email.model.bop.SendEmailsRequest; +import com.redhat.cloud.notifications.connector.email.model.settings.User; import io.vertx.core.json.JsonObject; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -11,9 +12,11 @@ import org.apache.camel.Processor; import org.apache.camel.component.http.HttpMethods; -import java.util.HashSet; +import java.util.Collections; import java.util.Set; +import static java.util.stream.Collectors.toSet; + @ApplicationScoped public class BOPRequestPreparer implements Processor { @Inject @@ -27,18 +30,23 @@ public class BOPRequestPreparer implements Processor { public void process(final Exchange exchange) { final String subject = exchange.getProperty(ExchangeProperty.RENDERED_SUBJECT, String.class); final String body = exchange.getProperty(ExchangeProperty.RENDERED_BODY, String.class); - final Set recipients = new HashSet<>(); + final Set recipients; // We still need to support sending individual emails per user for a // while. However, that will go away soon, so we can consider the // following code block very much deprecated. final Boolean singleEmailPerUser = exchange.getProperty(ExchangeProperty.SINGLE_EMAIL_PER_USER, Boolean.class); if (singleEmailPerUser != null && singleEmailPerUser) { - recipients.add(exchange.getMessage().getBody(String.class)); + recipients = Collections.singleton(exchange.getMessage().getBody(String.class)); } else { - final Set usernames = exchange.getProperty(ExchangeProperty.FILTERED_USERNAMES, Set.class); - - recipients.addAll(usernames); + final Set users = exchange.getProperty(ExchangeProperty.FILTERED_USERS, Set.class); + recipients = users.stream().map(user -> { + if (emailConnectorConfig.isSkipBopUsersResolution()) { + return user.getEmail(); + } else { + return user.getUsername(); + } + }).collect(toSet()); } final Email email = new Email( @@ -47,11 +55,11 @@ public void process(final Exchange exchange) { recipients ); - final Emails emails = new Emails(); - emails.addEmail(email); + final SendEmailsRequest request = new SendEmailsRequest(emailConnectorConfig.isSkipBopUsersResolution()); + request.getEmails().add(email); // Specify the message's payload in JSON. - exchange.getMessage().setBody(JsonObject.mapFrom(emails).encode()); + exchange.getMessage().setBody(JsonObject.mapFrom(request).encode()); // Specify the request's method. exchange.getMessage().setHeader(Exchange.HTTP_METHOD, HttpMethods.POST); diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/it/ITResponseProcessor.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/it/ITResponseProcessor.java index 9ede1ad574..a832875304 100644 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/it/ITResponseProcessor.java +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/it/ITResponseProcessor.java @@ -3,7 +3,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty; +import com.redhat.cloud.notifications.connector.email.model.settings.User; +import com.redhat.cloud.notifications.connector.email.processors.it.pojo.response.AccountRelationship; +import com.redhat.cloud.notifications.connector.email.processors.it.pojo.response.Email; import com.redhat.cloud.notifications.connector.email.processors.it.pojo.response.ITUserResponse; +import com.redhat.cloud.notifications.connector.email.processors.it.pojo.response.Permission; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import org.apache.camel.Exchange; @@ -13,6 +17,8 @@ import java.util.List; import java.util.Set; +import static com.redhat.cloud.notifications.connector.email.processors.it.ITConstants.ORG_ADMIN_PERMISSION; + @ApplicationScoped public class ITResponseProcessor implements Processor { @@ -33,10 +39,11 @@ public void process(final Exchange exchange) throws JsonProcessingException { // Get the list of usernames we will fill with the extracted usernames // from IT's response. - final Set usernames = exchange.getProperty(ExchangeProperty.USERNAMES, Set.class); + final Set users = exchange.getProperty(ExchangeProperty.USERS, Set.class); for (final ITUserResponse itUserResponse : itUserResponses) { - usernames.add(itUserResponse.authentications.get(0).principal); + User user = toUser(itUserResponse); + users.add(user); } final int count = itUserResponses.size(); @@ -49,4 +56,31 @@ public void process(final Exchange exchange) throws JsonProcessingException { exchange.setProperty(ExchangeProperty.OFFSET, offset + limit); } } + + private static User toUser(ITUserResponse itUserResponse) { + + User user = new User(); + user.setId(itUserResponse.id); + user.setUsername(itUserResponse.authentications.get(0).principal); + + for (Email email : itUserResponse.accountRelationships.get(0).emails) { + if (email != null && email.isPrimary != null && email.isPrimary) { + user.setEmail(email.address); + } + } + + if (itUserResponse.accountRelationships != null) { + for (AccountRelationship accountRelationship : itUserResponse.accountRelationships) { + if (accountRelationship.permissions != null) { + for (Permission permission : accountRelationship.permissions) { + if (ORG_ADMIN_PERMISSION.equals(permission.permissionCode)) { + user.setAdmin(true); + } + } + } + } + } + + return user; + } } diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/rbac/RBACUsersProcessor.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/rbac/RBACUsersProcessor.java index 7cfe3c5f9f..36e5e5d389 100644 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/rbac/RBACUsersProcessor.java +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/rbac/RBACUsersProcessor.java @@ -2,6 +2,7 @@ import com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty; import com.redhat.cloud.notifications.connector.email.model.settings.RecipientSettings; +import com.redhat.cloud.notifications.connector.email.model.settings.User; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; import jakarta.enterprise.context.ApplicationScoped; @@ -29,7 +30,7 @@ public void process(final Exchange exchange) { // Get the list of usernames we will fill with the extracted usernames // from RBAC's response. - final Set usernames = exchange.getProperty(ExchangeProperty.USERNAMES, Set.class); + final Set users = exchange.getProperty(ExchangeProperty.USERS, Set.class); // In case we are processing the RBAC users from the "get principals // from an RBAC group" call, we need to perform a few more checks @@ -53,7 +54,8 @@ public void process(final Exchange exchange) { } } - usernames.add(rbacUser.getString("username")); + User user = toUser(rbacUser); + users.add(user); } // Store the number of elements that were returned from the page, so @@ -68,4 +70,13 @@ public void process(final Exchange exchange) { exchange.setProperty(ExchangeProperty.OFFSET, offset + limit); } } + + private static User toUser(JsonObject rbacUser) { + + User user = new User(); + user.setUsername(rbacUser.getString("username")); + user.setEmail(rbacUser.getString("email")); + user.setAdmin(rbacUser.getBoolean("is_org_admin")); + return user; + } } diff --git a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/recipients/RecipientsFilter.java b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/recipients/RecipientsFilter.java index 230e5f4324..7ee629b1f1 100644 --- a/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/recipients/RecipientsFilter.java +++ b/connector-email/src/main/java/com/redhat/cloud/notifications/connector/email/processors/recipients/RecipientsFilter.java @@ -2,6 +2,7 @@ import com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty; import com.redhat.cloud.notifications.connector.email.model.settings.RecipientSettings; +import com.redhat.cloud.notifications.connector.email.model.settings.User; import jakarta.enterprise.context.ApplicationScoped; import org.apache.camel.Exchange; import org.apache.camel.Processor; @@ -21,27 +22,27 @@ public void process(final Exchange exchange) { // Fetch the required data to filter the users. final RecipientSettings recipientSettings = exchange.getProperty(ExchangeProperty.CURRENT_RECIPIENT_SETTINGS, RecipientSettings.class); final Set subscribers = (Set) exchange.getProperty(ExchangeProperty.SUBSCRIBERS, Set.class); - final Set usernames = exchange.getProperty(ExchangeProperty.USERNAMES, Set.class); + final Set users = exchange.getProperty(ExchangeProperty.USERS, Set.class); // Use a new hash set to hold the usernames. The "usernames" set that // comes from the user providers' responses is cached, but if we modify // it directly, it also affects the cached list. - final Set filteredUsernames = new HashSet<>(usernames); + final Set filteredUsers = new HashSet<>(users); // If the request settings contains a list of usernames, then the // recipients from RBAC who are not included in the request users list // are filtered out. Otherwise, the full list of recipients from RBAC // will be processed by the next step. if (recipientSettings.getUsers() != null && recipientSettings.getUsers().size() > 0) { - filteredUsernames.retainAll(recipientSettings.getUsers()); + filteredUsers.removeIf(user -> !recipientSettings.getUsers().contains(user.getUsername())); } // If the user preferences should be ignored, then we don't further // filter the recipients. Otherwise, we need to make sure that we only // send the notification to the subscribers of the event type. if (!recipientSettings.isIgnoreUserPreferences()) { - filteredUsernames.retainAll(subscribers); + filteredUsers.removeIf(user -> !subscribers.contains(user.getUsername())); } - exchange.setProperty(ExchangeProperty.FILTERED_USERNAMES, filteredUsernames); + exchange.setProperty(ExchangeProperty.FILTERED_USERS, filteredUsers); } } diff --git a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/EmailRouteBuilderTest.java b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/EmailRouteBuilderTest.java index a215e9265b..8c47b31cb5 100644 --- a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/EmailRouteBuilderTest.java +++ b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/EmailRouteBuilderTest.java @@ -63,7 +63,7 @@ void testIndividualEmailPerUser() throws Exception { final Set usernames = Set.of("a", "b", "c", "d", "e"); final Exchange exchange = this.createExchangeWithBody(""); - exchange.setProperty(ExchangeProperty.FILTERED_USERNAMES, usernames); + exchange.setProperty(ExchangeProperty.FILTERED_USERS, usernames); final MockEndpoint sendEmailBopEndpoint = this.getMockEndpoint(String.format("mock:direct:%s", Routes.SEND_EMAIL_BOP), false); sendEmailBopEndpoint.expectedMessageCount(5); diff --git a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/aggregation/UserAggregationStrategyTest.java b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/aggregation/UserAggregationStrategyTest.java index 805dee3daf..9b2bb5582f 100644 --- a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/aggregation/UserAggregationStrategyTest.java +++ b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/aggregation/UserAggregationStrategyTest.java @@ -52,7 +52,7 @@ void testAggregation() { // Prepare an old exchange to simulate the aggregation process. final Exchange oldExchange = this.createExchangeWithBody(""); - oldExchange.setProperty(ExchangeProperty.FILTERED_USERNAMES, users); + oldExchange.setProperty(ExchangeProperty.FILTERED_USERS, users); // Call the aggregator under test. final Exchange resultExchangeTwo = this.userAggregationStrategy.aggregate(oldExchange, newExchange); @@ -60,20 +60,20 @@ void testAggregation() { // Check that since the new exchange didn't have any new users, the old // exchange should contain the original ones. - final List resultUsers = resultExchangeTwo.getProperty(ExchangeProperty.FILTERED_USERNAMES, List.class); + final List resultUsers = resultExchangeTwo.getProperty(ExchangeProperty.FILTERED_USERS, List.class); RecipientsFilterTest.assertUsernameCollectionsEqualsIgnoreOrder(users, resultUsers); // Prepare a new exchange with a new list of users final Exchange yetAnotherExchange = this.createExchangeWithBody(""); - yetAnotherExchange.setProperty(ExchangeProperty.FILTERED_USERNAMES, users2); + yetAnotherExchange.setProperty(ExchangeProperty.FILTERED_USERS, users2); // Call the exchange under test. final Exchange finalExchange = this.userAggregationStrategy.aggregate(oldExchange, yetAnotherExchange); Assertions.assertEquals(oldExchange, finalExchange, "on following split iterations, the old exchange should be returned along with the aggregated users"); // Assert that the old exchange contains all the aggregated users. - final List finalUsersList = finalExchange.getProperty(ExchangeProperty.FILTERED_USERNAMES, List.class); + final List finalUsersList = finalExchange.getProperty(ExchangeProperty.FILTERED_USERS, List.class); RecipientsFilterTest.assertUsernameCollectionsEqualsIgnoreOrder(finalExpectedUsers, finalUsersList); } } diff --git a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/bop/BOPRequestPreparerTest.java b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/bop/BOPRequestPreparerTest.java index b1017e873a..daf5b05729 100644 --- a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/bop/BOPRequestPreparerTest.java +++ b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/bop/BOPRequestPreparerTest.java @@ -3,6 +3,7 @@ import com.google.common.io.Resources; import com.redhat.cloud.notifications.connector.email.config.EmailConnectorConfig; import com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty; +import com.redhat.cloud.notifications.connector.email.model.settings.User; import io.quarkus.test.junit.QuarkusTest; import io.vertx.core.json.JsonObject; import jakarta.inject.Inject; @@ -38,15 +39,21 @@ void testProcess() throws IOException { final String emailBody = "this is a fake body"; // Manually create the hash set because the "Set.of" utility doesn't // respect the insertion ordering. - final Set usernames = new HashSet<>(); - usernames.add("a"); - usernames.add("b"); - usernames.add("c"); + final Set users = new HashSet<>(); + User a = new User(); + a.setUsername("a"); + users.add(a); + User b = new User(); + a.setUsername("b"); + users.add(b); + User c = new User(); + a.setUsername("c"); + users.add(c); final Exchange exchange = this.createExchangeWithBody(""); exchange.setProperty(ExchangeProperty.RENDERED_SUBJECT, emailSubject); exchange.setProperty(ExchangeProperty.RENDERED_BODY, emailBody); - exchange.setProperty(ExchangeProperty.FILTERED_USERNAMES, usernames); + exchange.setProperty(ExchangeProperty.FILTERED_USERS, users); // Call the processor under test. this.bopRequestPreparer.process(exchange); diff --git a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/it/ITResponseProcessorTest.java b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/it/ITResponseProcessorTest.java index fa92d83f59..a3c49615c0 100644 --- a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/it/ITResponseProcessorTest.java +++ b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/it/ITResponseProcessorTest.java @@ -44,13 +44,13 @@ void testProcessLessThanLimit() throws IOException { final Exchange exchange = this.createExchangeWithBody(incomingBody); exchange.setProperty(ExchangeProperty.LIMIT, limit); exchange.setProperty(ExchangeProperty.OFFSET, offset); - exchange.setProperty(ExchangeProperty.USERNAMES, new HashSet()); + exchange.setProperty(ExchangeProperty.USERS, new HashSet()); // Call the processor under test. this.itResponseProcessor.process(exchange); // Assert that the grabbed username is correct. - final Set usernames = exchange.getProperty(ExchangeProperty.USERNAMES, Set.class); + final Set usernames = exchange.getProperty(ExchangeProperty.USERS, Set.class); Assertions.assertEquals(1, usernames.size()); Assertions.assertEquals("foo", usernames.iterator().next()); @@ -82,13 +82,13 @@ void testProcessExactAsLimit() throws IOException { final Exchange exchange = this.createExchangeWithBody(incomingBody); exchange.setProperty(ExchangeProperty.LIMIT, limit); exchange.setProperty(ExchangeProperty.OFFSET, offset); - exchange.setProperty(ExchangeProperty.USERNAMES, new HashSet()); + exchange.setProperty(ExchangeProperty.USERS, new HashSet()); // Call the processor under test. this.itResponseProcessor.process(exchange); // Assert that the grabbed username is correct. - final Set usernames = exchange.getProperty(ExchangeProperty.USERNAMES, Set.class); + final Set usernames = exchange.getProperty(ExchangeProperty.USERS, Set.class); Assertions.assertEquals(1, usernames.size()); Assertions.assertEquals("foo", usernames.iterator().next()); diff --git a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/rbac/RBACUsersProcessorTest.java b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/rbac/RBACUsersProcessorTest.java index 97c86dfa78..cafe60d208 100644 --- a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/rbac/RBACUsersProcessorTest.java +++ b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/rbac/RBACUsersProcessorTest.java @@ -47,7 +47,7 @@ void testProcessRegularCall() throws IOException { ); exchange.setProperty(ExchangeProperty.CURRENT_RECIPIENT_SETTINGS, recipientSettings); exchange.setProperty(ExchangeProperty.LIMIT, this.emailConnectorConfig.getRbacElementsPerPage()); - exchange.setProperty(ExchangeProperty.USERNAMES, new HashSet()); + exchange.setProperty(ExchangeProperty.USERS, new HashSet()); // Call the processor under test. this.rbacUsersProcessor.process(exchange); @@ -63,7 +63,7 @@ void testProcessRegularCall() throws IOException { expectedUsernames.add("johndoe"); expectedUsernames.add("janedoe"); - final Set result = exchange.getProperty(ExchangeProperty.USERNAMES, Set.class); + final Set result = exchange.getProperty(ExchangeProperty.USERS, Set.class); Assertions.assertIterableEquals(expectedUsernames, result); } @@ -94,7 +94,7 @@ void testProcessRegularCallCountMatchesLimit() throws IOException { final int limit = 5; exchange.setProperty(ExchangeProperty.OFFSET, offset); exchange.setProperty(ExchangeProperty.LIMIT, limit); - exchange.setProperty(ExchangeProperty.USERNAMES, new HashSet()); + exchange.setProperty(ExchangeProperty.USERS, new HashSet()); // Call the processor under test. this.rbacUsersProcessor.process(exchange); @@ -110,7 +110,7 @@ void testProcessRegularCallCountMatchesLimit() throws IOException { expectedUsernames.add("johndoe"); expectedUsernames.add("janedoe"); - final Set result = exchange.getProperty(ExchangeProperty.USERNAMES, Set.class); + final Set result = exchange.getProperty(ExchangeProperty.USERS, Set.class); Assertions.assertIterableEquals(expectedUsernames, result); // Assert that the offset got updated. @@ -140,7 +140,7 @@ void testProcessGroupCall() throws IOException { ); exchange.setProperty(ExchangeProperty.CURRENT_RECIPIENT_SETTINGS, recipientSettings); exchange.setProperty(ExchangeProperty.LIMIT, this.emailConnectorConfig.getRbacElementsPerPage()); - exchange.setProperty(ExchangeProperty.USERNAMES, new HashSet()); + exchange.setProperty(ExchangeProperty.USERS, new HashSet()); // Call the processor under test. this.rbacUsersProcessor.process(exchange); @@ -153,7 +153,7 @@ void testProcessGroupCall() throws IOException { expectedUsernames.add("foouser"); expectedUsernames.add("baruser"); - final Set result = exchange.getProperty(ExchangeProperty.USERNAMES, Set.class); + final Set result = exchange.getProperty(ExchangeProperty.USERS, Set.class); Assertions.assertIterableEquals(expectedUsernames, result); } } diff --git a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/recipients/RecipientsFilterTest.java b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/recipients/RecipientsFilterTest.java index dd779ea494..c91d404a64 100644 --- a/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/recipients/RecipientsFilterTest.java +++ b/connector-email/src/test/java/com/redhat/cloud/notifications/connector/email/processors/recipients/RecipientsFilterTest.java @@ -52,7 +52,7 @@ void testRecipientSettingsUsersKept() { final Exchange exchange = this.createExchangeWithBody(""); exchange.setProperty(ExchangeProperty.CURRENT_RECIPIENT_SETTINGS, recipientSettings); exchange.setProperty(ExchangeProperty.SUBSCRIBERS, subscribers); - exchange.setProperty(ExchangeProperty.USERNAMES, usernames); + exchange.setProperty(ExchangeProperty.USERS, usernames); // Call the processor under test. this.recipientsFilter.process(exchange); @@ -64,7 +64,7 @@ void testRecipientSettingsUsersKept() { expectedResult.add("a"); expectedResult.add("c"); expectedResult.add("e"); - final Set result = exchange.getProperty(ExchangeProperty.FILTERED_USERNAMES, Set.class); + final Set result = exchange.getProperty(ExchangeProperty.FILTERED_USERS, Set.class); assertUsernameCollectionsEqualsIgnoreOrder(expectedResult, result); } @@ -92,13 +92,13 @@ void testIgnoreUserPreferences() { final Exchange exchange = this.createExchangeWithBody(""); exchange.setProperty(ExchangeProperty.CURRENT_RECIPIENT_SETTINGS, recipientSettings); exchange.setProperty(ExchangeProperty.SUBSCRIBERS, subscribers); - exchange.setProperty(ExchangeProperty.USERNAMES, usernames); + exchange.setProperty(ExchangeProperty.USERS, usernames); // Call the processor under test. this.recipientsFilter.process(exchange); // Assert that the list contains the expected elements. - final Set result = exchange.getProperty(ExchangeProperty.FILTERED_USERNAMES, Set.class); + final Set result = exchange.getProperty(ExchangeProperty.FILTERED_USERS, Set.class); assertUsernameCollectionsEqualsIgnoreOrder(usernames, result); } @@ -132,7 +132,7 @@ void testFilterUnsubscribedUsernames() { final Exchange exchange = this.createExchangeWithBody(""); exchange.setProperty(ExchangeProperty.CURRENT_RECIPIENT_SETTINGS, recipientSettings); exchange.setProperty(ExchangeProperty.SUBSCRIBERS, subscribers); - exchange.setProperty(ExchangeProperty.USERNAMES, usernames); + exchange.setProperty(ExchangeProperty.USERS, usernames); // Call the processor under test. this.recipientsFilter.process(exchange); @@ -144,7 +144,7 @@ void testFilterUnsubscribedUsernames() { expectedResult.add("b"); expectedResult.add("c"); expectedResult.add("e"); - final Set result = exchange.getProperty(ExchangeProperty.FILTERED_USERNAMES, Set.class); + final Set result = exchange.getProperty(ExchangeProperty.FILTERED_USERS, Set.class); assertUsernameCollectionsEqualsIgnoreOrder(expectedResult, result); } diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/email/EmailSender.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/email/EmailSender.java index ad3af78de7..74486b0626 100644 --- a/engine/src/main/java/com/redhat/cloud/notifications/processors/email/EmailSender.java +++ b/engine/src/main/java/com/redhat/cloud/notifications/processors/email/EmailSender.java @@ -188,13 +188,13 @@ private JsonObject getPayload(Set users, EventWrapper eventWrapper, ); throw e; } - Emails emails = new Emails(); - emails.addEmail(buildEmail( + SendEmailsRequest request = new SendEmailsRequest(featureFlipper.isSendEmailstoBop()); + request.getEmails().add(buildEmail( users, renderedSubject, renderedBody )); - return JsonObject.mapFrom(emails); + return JsonObject.mapFrom(request); } @Deprecated(forRemoval = true) @@ -212,13 +212,13 @@ private JsonObject getPayload(User user, EventWrapper eventWrapper, Templa ); throw e; } - Emails emails = new Emails(); - emails.addEmail(buildEmail( - user.getUsername(), + SendEmailsRequest request = new SendEmailsRequest(featureFlipper.isSendEmailstoBop()); + request.getEmails().add(buildEmail( + featureFlipper.isSendEmailstoBop() ? user.getEmail() : user.getUsername(), renderedSubject, renderedBody )); - return JsonObject.mapFrom(emails); + return JsonObject.mapFrom(request); } protected HttpRequest buildBOPHttpRequest() { @@ -240,7 +240,13 @@ protected Email buildEmail(String recipient, String subject, String body) { } protected Email buildEmail(Set recipients, String subject, String body) { - Set usersEmail = recipients.stream().map(User::getUsername).collect(Collectors.toSet()); + Set usersEmail; + if (featureFlipper.isSendEmailstoBop()) { + usersEmail = recipients.stream().map(User::getEmail).collect(Collectors.toSet()); + } else { + usersEmail = recipients.stream().map(User::getUsername).collect(Collectors.toSet()); + } + Email email = new Email(); email.setBodyType(BODY_TYPE_HTML); if (featureFlipper.isAddDefaultRecipientOnSingleEmail()) { diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/email/Emails.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/email/Emails.java deleted file mode 100644 index be8fbcf3fe..0000000000 --- a/engine/src/main/java/com/redhat/cloud/notifications/processors/email/Emails.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.redhat.cloud.notifications.processors.email; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.HashSet; -import java.util.Set; - -public class Emails { - - @JsonProperty("emails") - private final Set emails; - - Emails() { - this.emails = new HashSet<>(); - } - - void addEmail(final Email email) { - this.emails.add(email); - } - - Set getEmails() { - return emails; - } -} diff --git a/engine/src/main/java/com/redhat/cloud/notifications/processors/email/SendEmailsRequest.java b/engine/src/main/java/com/redhat/cloud/notifications/processors/email/SendEmailsRequest.java new file mode 100644 index 0000000000..317fd67342 --- /dev/null +++ b/engine/src/main/java/com/redhat/cloud/notifications/processors/email/SendEmailsRequest.java @@ -0,0 +1,22 @@ +package com.redhat.cloud.notifications.processors.email; + +import java.util.HashSet; +import java.util.Set; + +public class SendEmailsRequest { + + private final Set emails = new HashSet<>(); + private final boolean skipUsersResolution; + + public SendEmailsRequest(boolean skipUsersResolution) { + this.skipUsersResolution = skipUsersResolution; + } + + public Set getEmails() { + return emails; + } + + public boolean isSkipUsersResolution() { + return skipUsersResolution; + } +} diff --git a/engine/src/main/resources/application.properties b/engine/src/main/resources/application.properties index 59e4a437c7..b0cb058542 100644 --- a/engine/src/main/resources/application.properties +++ b/engine/src/main/resources/application.properties @@ -141,7 +141,7 @@ quarkus.log.cloudwatch.access-key-secret=placeholder quarkus.log.category."com.redhat.cloud.notifications.health.KafkaConsumedTotalChecker".level=DEBUG -# Should messages about failed injections be delivered as new events (and thus emails to admins) +# Should messages about failed injections be delivered as new events (and thus sendEmailsRequest to admins) reinject.enabled=false # Use this property to load the templates from the DB. Temp, to be removed soon. diff --git a/recipients-resolver/src/main/java/com/redhat/cloud/notifications/recipients/model/User.java b/recipients-resolver/src/main/java/com/redhat/cloud/notifications/recipients/model/User.java index a765bce957..5174ff03cf 100644 --- a/recipients-resolver/src/main/java/com/redhat/cloud/notifications/recipients/model/User.java +++ b/recipients-resolver/src/main/java/com/redhat/cloud/notifications/recipients/model/User.java @@ -6,6 +6,7 @@ public class User { private String id; private String username; + private String email; private boolean admin; public String getId() { @@ -24,6 +25,14 @@ public void setUsername(String username) { this.username = username; } + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + public boolean isAdmin() { return admin; } diff --git a/recipients-resolver/src/main/java/com/redhat/cloud/notifications/recipients/resolver/FetchUsersFromExternalServices.java b/recipients-resolver/src/main/java/com/redhat/cloud/notifications/recipients/resolver/FetchUsersFromExternalServices.java index 4fab774e62..0479399cb5 100644 --- a/recipients-resolver/src/main/java/com/redhat/cloud/notifications/recipients/resolver/FetchUsersFromExternalServices.java +++ b/recipients-resolver/src/main/java/com/redhat/cloud/notifications/recipients/resolver/FetchUsersFromExternalServices.java @@ -5,6 +5,7 @@ import com.redhat.cloud.notifications.recipients.resolver.itservice.ITUserService; import com.redhat.cloud.notifications.recipients.resolver.itservice.pojo.request.ITUserRequest; import com.redhat.cloud.notifications.recipients.resolver.itservice.pojo.response.AccountRelationship; +import com.redhat.cloud.notifications.recipients.resolver.itservice.pojo.response.Email; import com.redhat.cloud.notifications.recipients.resolver.itservice.pojo.response.ITUserResponse; import com.redhat.cloud.notifications.recipients.resolver.itservice.pojo.response.Permission; import com.redhat.cloud.notifications.recipients.resolver.mbop.MBOPService; @@ -177,6 +178,12 @@ List transformItUserToUser(List itUserResponses) { user.setId(itUserResponse.id); user.setUsername(itUserResponse.authentications.get(0).principal); + for (Email email : itUserResponse.accountRelationships.get(0).emails) { + if (email != null && email.isPrimary != null && email.isPrimary) { + user.setEmail(email.address); + } + } + if (itUserResponse.accountRelationships != null) { for (AccountRelationship accountRelationship : itUserResponse.accountRelationships) { if (accountRelationship.permissions != null) { @@ -255,6 +262,7 @@ private List getWithPagination(Function> fetcher) if (rbacUser.getActive()) { User user = new User(); user.setUsername(rbacUser.getUsername()); + user.setEmail(rbacUser.getEmail()); user.setAdmin(TRUE.equals(rbacUser.getOrgAdmin())); users.add(user); } @@ -272,6 +280,7 @@ List transformMBOPUserToUser(final List mbopUsers) { user.setId(mbopUser.id()); user.setUsername(mbopUser.username()); + user.setEmail(mbopUser.email()); user.setAdmin(mbopUser.isOrgAdmin()); users.add(user);