Skip to content

Commit

Permalink
[RHCLOUD-36917] add Kessel error details into notifications history (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
g-duval authored Dec 24, 2024
1 parent bf71508 commit eaa1569
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.apache.camel.Exchange;
import org.apache.camel.Message;

import static com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty.ADDITIONAL_ERROR_DETAILS;

@ApplicationScoped
@Alternative
@Priority(0) // The value doesn't matter.
Expand All @@ -25,7 +27,18 @@ public void process(Exchange exchange) throws Exception {
JsonObject data = new JsonObject(cloudEvent.getString("data"));
data.getJsonObject("details").put(TOTAL_RECIPIENTS_KEY, totalRecipients);

if (exchange.getProperties().containsKey(ADDITIONAL_ERROR_DETAILS)) {
data.getJsonObject("details").put(ADDITIONAL_ERROR_DETAILS, getErrorDetail(exchange));
}
cloudEvent.put("data", data.encode());
in.setBody(cloudEvent.encode());
}

private Object getErrorDetail(final Exchange exchange) {
try {
return new JsonObject(exchange.getProperty(ADDITIONAL_ERROR_DETAILS, String.class));
} catch (Exception e) {
return exchange.getProperty(ADDITIONAL_ERROR_DETAILS, String.class);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.redhat.cloud.notifications.connector.email;

import com.redhat.cloud.notifications.connector.http.HttpExceptionProcessor;
import jakarta.annotation.Priority;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Alternative;
import org.apache.camel.Exchange;
import org.apache.camel.http.base.HttpOperationFailedException;

import static com.redhat.cloud.notifications.connector.email.constants.ExchangeProperty.ADDITIONAL_ERROR_DETAILS;

@ApplicationScoped
@Alternative
@Priority(0) // The value doesn't matter.
public class EmailExceptionProcessor extends HttpExceptionProcessor {

@Override
protected void process(Throwable t, Exchange exchange) {
super.process(t, exchange);
if (t instanceof HttpOperationFailedException e) {
exchange.setProperty(ADDITIONAL_ERROR_DETAILS, e.getResponseBody());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,6 @@ public class ExchangeProperty {
public static final String USE_EMAIL_BOP_V1_SSL = "use_email_bop_V1_ssl";

public static final String RECIPIENTS_AUTHORIZATION_CRITERION = "recipients_authorization_criterion";

public static final String ADDITIONAL_ERROR_DETAILS = "additionalErrorDetails";
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ public Set<String> lookupSubjects(RecipientsAuthorizationCriterion recipientsAut
Set<String> userIds = new HashSet<>();
LookupSubjectsRequest request = getLookupSubjectsRequest(recipientsAuthorizationCriterion);

final String kesselAdditionalDomainName = String.format("%s/", recipientsResolverConfig.getKesselDomain());
for (Iterator<LookupSubjectsResponse> it = lookupClient.lookupSubjects(request); it.hasNext();) {
LookupSubjectsResponse response = it.next();
Log.infof("Kessel response: %s", response);

userIds.add(response.getSubject().getSubject().getId().replaceAll(recipientsResolverConfig.getKesselDomain(), ""));
userIds.add(response.getSubject().getSubject().getId().replaceAll(kesselAdditionalDomainName, ""));
}
Log.infof("Kessel returned %d user(s) for request %s", userIds.size(), request);
return userIds;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import com.redhat.cloud.notifications.recipients.model.User;
import com.redhat.cloud.notifications.recipients.resolver.RecipientsResolver;
import com.redhat.cloud.notifications.recipients.rest.pojo.RecipientsQuery;
import io.grpc.StatusRuntimeException;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.WebApplicationException;
import java.util.Set;


Expand All @@ -25,12 +27,18 @@ public class RecipientsResolverResource {
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Set<User> getRecipients(@NotNull @Valid RecipientsQuery recipientsQuery) {
return recipientsResolver.findRecipients(
recipientsQuery.orgId,
recipientsQuery.recipientSettings,
recipientsQuery.subscribers,
recipientsQuery.unsubscribers,
recipientsQuery.subscribedByDefault,
recipientsQuery.recipientsAuthorizationCriterion);
try {
return recipientsResolver.findRecipients(
recipientsQuery.orgId,
recipientsQuery.recipientSettings,
recipientsQuery.subscribers,
recipientsQuery.unsubscribers,
recipientsQuery.subscribedByDefault,
recipientsQuery.recipientsAuthorizationCriterion);
} catch (StatusRuntimeException e) {
throw new WebApplicationException(String.format("Kessel error: %s", e.getMessage()));
} catch (Exception e) {
throw new WebApplicationException(e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.redhat.cloud.notifications.recipients.rest;

import com.fasterxml.jackson.core.JsonParseException;
import io.quarkus.logging.Log;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;

import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;

@Provider
public class WebApplicationExceptionMapper implements ExceptionMapper<WebApplicationException> {


/**
* Map thrown Exceptions to Responses with appropriate status codes
*/
@Override
public Response toResponse(WebApplicationException exception) {
Log.error(exception);
if (exception instanceof BadRequestException) {
return Response.status(BAD_REQUEST).entity(exception.getMessage()).build();
}
if (exception.getCause() != null && exception.getCause() instanceof JsonParseException) {
JsonParseException jsonParseException = (JsonParseException) exception.getCause();
return Response.status(BAD_REQUEST).entity(jsonParseException.getMessage()).build();
}
return Response.status(exception.getResponse().getStatus()).entity(exception.getMessage()).build();
}
}

0 comments on commit eaa1569

Please sign in to comment.