argos/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/inbox/notify/NotifyIntegrationEventHandl...

141 lines
7.4 KiB
Java

package gr.cite.notification.integrationevent.inbox.notify;
import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver;
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorProperties;
import gr.cite.notification.audit.AuditableAction;
import gr.cite.notification.common.JsonHandlingService;
import gr.cite.notification.common.enums.NotificationNotifyState;
import gr.cite.notification.common.enums.NotificationTrackingProcess;
import gr.cite.notification.common.enums.NotificationTrackingState;
import gr.cite.notification.common.scope.fake.FakeRequestScope;
import gr.cite.notification.common.scope.tenant.TenantScope;
import gr.cite.notification.data.TenantEntity;
import gr.cite.notification.data.TenantEntityManager;
import gr.cite.notification.errorcode.ErrorThesaurusProperties;
import gr.cite.notification.integrationevent.inbox.EventProcessingStatus;
import gr.cite.notification.integrationevent.inbox.InboxPrincipal;
import gr.cite.notification.integrationevent.inbox.IntegrationEventProperties;
import gr.cite.notification.model.Tenant;
import gr.cite.notification.model.persist.NotificationPersist;
import gr.cite.notification.query.TenantQuery;
import gr.cite.notification.service.notification.NotificationService;
import gr.cite.tools.auditing.AuditService;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyValidationException;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.logging.LoggerService;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.OptimisticLockException;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.AbstractMap;
import java.util.Map;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class NotifyIntegrationEventHandlerImpl implements NotifyIntegrationEventHandler {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(NotifyIntegrationEventHandlerImpl.class));
private final JsonHandlingService jsonHandlingService;
private final ErrorThesaurusProperties errors;
private final MessageSource messageSource;
private final QueryFactory queryFactory;
private final TenantScope tenantScope;
private final CurrentPrincipalResolver currentPrincipalResolver;
private final ClaimExtractorProperties claimExtractorProperties;
private final NotifyConsistencyHandler notifyConsistencyHandler;
private final NotificationService notificationService;
private final AuditService auditService;
private final TenantEntityManager tenantEntityManager;
public NotifyIntegrationEventHandlerImpl(JsonHandlingService jsonHandlingService, ErrorThesaurusProperties errors, MessageSource messageSource, QueryFactory queryFactory, TenantScope tenantScope, CurrentPrincipalResolver currentPrincipalResolver, ClaimExtractorProperties claimExtractorProperties, NotifyConsistencyHandler notifyConsistencyHandler, NotificationService notificationService, AuditService auditService, TenantEntityManager tenantEntityManager) {
this.jsonHandlingService = jsonHandlingService;
this.errors = errors;
this.messageSource = messageSource;
this.queryFactory = queryFactory;
this.tenantScope = tenantScope;
this.currentPrincipalResolver = currentPrincipalResolver;
this.claimExtractorProperties = claimExtractorProperties;
this.notifyConsistencyHandler = notifyConsistencyHandler;
this.notificationService = notificationService;
this.auditService = auditService;
this.tenantEntityManager = tenantEntityManager;
}
@Override
public EventProcessingStatus handle(IntegrationEventProperties properties, String message) {
NotifyIntegrationEvent event = this.jsonHandlingService.fromJsonSafe(NotifyIntegrationEvent.class, message);
if (event == null)
return EventProcessingStatus.Error;
if (event.getUserId() == null) {
throw new MyValidationException(this.errors.getModelValidation().getCode(), "userId", messageSource.getMessage("Validation_Required", new Object[]{"userId"}, LocaleContextHolder.getLocale()));
}
logger.debug("Handling {}", NotifyIntegrationEvent.class.getSimpleName());
NotificationPersist model = new NotificationPersist();
model.setType(event.getNotificationType());
model.setUserId(event.getUserId());
model.setContactHint(event.getContactHint());
model.setContactTypeHint(event.getContactTypeHint());
model.setData(event.getData());
model.setNotifyState(NotificationNotifyState.PENDING);
model.setNotifiedWith(event.getContactTypeHint());
model.setRetryCount(0);
model.setTrackingState(NotificationTrackingState.UNDEFINED);
model.setTrackingProcess(NotificationTrackingProcess.PENDING);
model.setTrackingData(null);
model.setProvenanceRef(event.getProvenanceRef());
model.setNotifiedAt(Instant.now());
EventProcessingStatus status = EventProcessingStatus.Success;
try {
if (this.tenantScope.isMultitenant() && properties.getTenantId() != null) {
TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(properties.getTenantId()).firstAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
if (tenant == null) {
logger.error("missing tenant from event message");
return EventProcessingStatus.Error;
}
this.tenantScope.setTempTenant(tenantEntityManager.getEntityManager(), properties.getTenantId(), tenant.getCode());
} else if (this.tenantScope.isMultitenant()) {
// logger.error("missing tenant from event message");
// return EventProcessingStatus.Error;
this.tenantScope.setTempTenant(tenantEntityManager.getEntityManager(), null, this.tenantScope.getDefaultTenantCode());
}
currentPrincipalResolver.push(InboxPrincipal.build(properties, claimExtractorProperties));
if (!(notifyConsistencyHandler.isConsistent(new NotifyConsistencyPredicates(event.getUserId(), event.getContactTypeHint(), event.getContactHint())))) {
status = EventProcessingStatus.Postponed;
currentPrincipalResolver.pop();
tenantScope.removeTempTenant(this.tenantEntityManager.getEntityManager());
return status;
}
notificationService.persist(model, new BaseFieldSet());
auditService.track(AuditableAction.Notification_Persist, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", event.getUserId())
));
} catch (Exception ex) {
status = EventProcessingStatus.Error;
logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex);
} finally {
currentPrincipalResolver.pop();
tenantScope.removeTempTenant(this.tenantEntityManager.getEntityManager());
}
return status;
}
}