diff --git a/annotation-service/annotation/pom.xml b/annotation-service/annotation/pom.xml index b596dc8cd..21f9e9d62 100644 --- a/annotation-service/annotation/pom.xml +++ b/annotation-service/annotation/pom.xml @@ -52,7 +52,7 @@ gr.cite data-tools - 2.1.4 + 2.1.5 gr.cite diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/QueueOutboxEntity.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/QueueOutboxEntity.java index b25ca4edb..58ac5950d 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/QueueOutboxEntity.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/QueueOutboxEntity.java @@ -71,6 +71,7 @@ public class QueueOutboxEntity implements QueueOutbox { public static final String _createdAt = "createdAt"; @Column(name = "\"updated_at\"", nullable = false) + @Version private Instant updatedAt; public static final String _updatedAt = "updatedAt"; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/TenantEntityManager.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/TenantEntityManager.java index 438d5fcc9..5d51df90c 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/TenantEntityManager.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/TenantEntityManager.java @@ -21,7 +21,7 @@ public class TenantEntityManager { private EntityManager entityManager; private final TenantScope tenantScope; private final ErrorThesaurusProperties errors; - + boolean tenantFiltersDisabled; public TenantEntityManager(TenantScope tenantScope, ErrorThesaurusProperties errors) { @@ -95,6 +95,8 @@ public class TenantEntityManager { } public void reloadTenantFilters() throws InvalidApplicationException { + if (!this.entityManager.isOpen()) return; + this.disableTenantFilters(); if (!this.tenantScope.isSet()) return; @@ -113,6 +115,8 @@ public class TenantEntityManager { } public void loadExplictTenantFilters() throws InvalidApplicationException { + if (!this.entityManager.isOpen()) return; + this.disableTenantFilters(); if (!this.tenantScope.isSet()) return; @@ -131,6 +135,8 @@ public class TenantEntityManager { } public void disableTenantFilters() { + if (!this.entityManager.isOpen()) return; + this.entityManager .unwrap(Session.class) .disableFilter(TenantScopedBaseEntity.TENANT_FILTER); @@ -146,7 +152,7 @@ public class TenantEntityManager { } public boolean isTenantFiltersDisabled() { - return tenantFiltersDisabled; + return this.tenantFiltersDisabled; } public EntityManager getEntityManager() { diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/InboxIntegrationEventConfigurer.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/InboxIntegrationEventConfigurer.java index f8fa89d4b..8a86462bc 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/InboxIntegrationEventConfigurer.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/InboxIntegrationEventConfigurer.java @@ -4,7 +4,6 @@ import gr.cite.annotation.integrationevent.inbox.InboxProperties; import gr.cite.annotation.integrationevent.inbox.InboxRepositoryImpl; import gr.cite.queueinbox.InboxConfigurer; import gr.cite.queueinbox.repository.InboxRepository; -import jakarta.persistence.EntityManagerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; @@ -20,16 +19,14 @@ public class InboxIntegrationEventConfigurer extends InboxConfigurer { private final InboxProperties inboxProperties; - private final EntityManagerFactory entityManagerFactory; - public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties, EntityManagerFactory entityManagerFactory) { + public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties) { this.applicationContext = applicationContext; this.inboxProperties = inboxProperties; - this.entityManagerFactory = entityManagerFactory; } @Bean public InboxRepository inboxRepositoryCreator() { - return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties, this.entityManagerFactory); + return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties); } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/OutboxIntegrationEventConfigurer.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/OutboxIntegrationEventConfigurer.java index 15a0bed4e..6f035d511 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/OutboxIntegrationEventConfigurer.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/OutboxIntegrationEventConfigurer.java @@ -9,7 +9,6 @@ import gr.cite.queueoutbox.repository.OutboxRepository; import gr.cite.rabbitmq.IntegrationEventMessageConstants; import gr.cite.rabbitmq.RabbitProperties; import gr.cite.rabbitmq.broker.MessageHydrator; -import jakarta.persistence.EntityManagerFactory; import org.springframework.amqp.core.MessageProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -27,13 +26,9 @@ import java.util.UUID; @ConditionalOnProperty(prefix = "queue.task.publisher", name = "enable", matchIfMissing = false) public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { private final ApplicationContext applicationContext; - private final OutboxProperties outboxProperties; - private final EntityManagerFactory entityManagerFactory; - public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties, EntityManagerFactory entityManagerFactory) { + public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext) { this.applicationContext = applicationContext; - this.outboxProperties = outboxProperties; - this.entityManagerFactory = entityManagerFactory; } @Bean @@ -69,7 +64,7 @@ public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { @Bean public OutboxRepository outboxRepositoryCreator() { - return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties, this.entityManagerFactory); + return new OutboxRepositoryImpl(this.applicationContext); } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/InboxRepositoryImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/InboxRepositoryImpl.java index b7b88006c..85ae29962 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/InboxRepositoryImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/InboxRepositoryImpl.java @@ -1,11 +1,9 @@ package gr.cite.annotation.integrationevent.inbox; -import gr.cite.annotation.common.JsonHandlingService; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.fake.FakeRequestScope; import gr.cite.annotation.data.QueueInboxEntity; import gr.cite.annotation.data.TenantEntityManager; -import gr.cite.annotation.integrationevent.TrackedEvent; import gr.cite.annotation.integrationevent.inbox.annotationentitiesremoval.AnnotationEntitiesRemovalIntegrationEventHandler; import gr.cite.annotation.integrationevent.inbox.annotationentitiestouch.AnnotationEntitiesTouchedIntegrationEventHandler; import gr.cite.annotation.integrationevent.inbox.tenantremoval.TenantRemovalIntegrationEventHandler; @@ -23,10 +21,7 @@ import gr.cite.rabbitmq.consumer.InboxCreatorParams; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.logging.LoggerService; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.*; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -40,31 +35,30 @@ public class InboxRepositoryImpl implements InboxRepository { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(InboxRepositoryImpl.class)); protected final ApplicationContext applicationContext; - - private final JsonHandlingService jsonHandlingService; - private final InboxProperties inboxProperties; - private final EntityManagerFactory entityManagerFactory; + + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; public InboxRepositoryImpl( - ApplicationContext applicationContext, - InboxProperties inboxProperties, EntityManagerFactory entityManagerFactory + ApplicationContext applicationContext, + InboxProperties inboxProperties ) { this.applicationContext = applicationContext; - this.entityManagerFactory = entityManagerFactory; - this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class); this.inboxProperties = inboxProperties; } @Override public CandidateInfo candidate(Instant lastCandidateCreationTimestamp, MessageOptions options) { EntityTransaction transaction = null; - EntityManager entityManager = null; CandidateInfo candidate = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -103,8 +97,7 @@ public class InboxRepositoryImpl implements InboxRepository { transaction.rollback(); candidate = null; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem getting list of queue inbox. Skipping: {}", ex.getMessage(), ex); @@ -116,12 +109,14 @@ public class InboxRepositoryImpl implements InboxRepository { @Override public Boolean shouldOmit(CandidateInfo candidate, Function shouldOmit) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -148,8 +143,7 @@ public class InboxRepositoryImpl implements InboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -160,12 +154,14 @@ public class InboxRepositoryImpl implements InboxRepository { @Override public boolean shouldWait(CandidateInfo candidate, Function itIsTimeFunc) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -193,8 +189,7 @@ public class InboxRepositoryImpl implements InboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -205,14 +200,16 @@ public class InboxRepositoryImpl implements InboxRepository { @Override public QueueInbox create(InboxCreatorParams inboxCreatorParams) { EntityTransaction transaction = null; - EntityManager entityManager = null; - boolean success = false; + boolean success; QueueInboxEntity queueMessage = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + queueMessage = this.createQueueInboxEntity(inboxCreatorParams); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -221,23 +218,22 @@ public class InboxRepositoryImpl implements InboxRepository { entityManager.flush(); transaction.commit(); + success = true; } catch (Exception ex) { - logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); - if (transaction != null) - transaction.rollback(); success = false; + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); } - return queueMessage; + return success ? queueMessage : null; } private QueueInboxEntity createQueueInboxEntity(InboxCreatorParams inboxCreatorParams) { - QueueInboxEntity queueMessage = new QueueInboxEntity(); queueMessage.setId(UUID.randomUUID()); Object tenantId = inboxCreatorParams.getHeaders() != null ? inboxCreatorParams.getHeaders().getOrDefault(IntegrationEventMessageConstants.TENANT, null) : null; @@ -246,6 +242,7 @@ public class InboxRepositoryImpl implements InboxRepository { try { queueMessage.setTenantId(UUID.fromString((String) tenantId)); } catch (Exception e) { + logger.error(e.getMessage(), e); } } queueMessage.setExchange(this.inboxProperties.getExchange()); @@ -265,28 +262,26 @@ public class InboxRepositoryImpl implements InboxRepository { @Override public Boolean emit(CandidateInfo candidateInfo) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; - + QueueInboxEntity queueInboxMessage; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); + queueInboxMessage = queryFactory.query(QueueInboxQuery.class).ids(candidateInfo.getId()).first(); + } + if (queueInboxMessage == null) { + logger.warn("Could not lookup queue inbox {} to process. Continuing...", candidateInfo.getId()); + } else { + EventProcessingStatus status = this.emitQueueInboxEntity(queueInboxMessage); + try (FakeRequestScope ignored = new FakeRequestScope()) { TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); - tenantEntityManager.setEntityManager(entityManager); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - transaction.begin(); + transaction = entityManager.getTransaction(); - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - QueueInboxEntity queueInboxMessage = queryFactory.query(QueueInboxQuery.class).ids(candidateInfo.getId()).first(); + transaction.begin(); - if (queueInboxMessage == null) { - logger.warn("Could not lookup queue inbox {} to process. Continuing...", candidateInfo.getId()); - } else { - - EventProcessingStatus status = this.processMessage(queueInboxMessage); switch (status) { case Success: { queueInboxMessage.setStatus(QueueInboxStatus.SUCCESSFUL); @@ -311,24 +306,59 @@ public class InboxRepositoryImpl implements InboxRepository { entityManager.merge(queueInboxMessage); entityManager.flush(); - } - transaction.commit(); + transaction.commit(); + } catch (Exception ex) { + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + if (transaction != null) + transaction.rollback(); + success = false; + } finally { + tenantEntityManager.reloadTenantFilters(); + } + } catch (Exception ex) { + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + } + + } + return success; + } + + public EventProcessingStatus emitQueueInboxEntity(QueueInboxEntity queueInboxMessage) { + EntityTransaction transaction = null; + EventProcessingStatus status = EventProcessingStatus.Discard; + try (FakeRequestScope ignored = new FakeRequestScope()) { + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + tenantEntityManager.setEntityManager(entityManager); + + transaction = entityManager.getTransaction(); + + transaction.begin(); + + status = this.processMessage(queueInboxMessage); + + entityManager.flush(); + + switch (status) { + case Error: transaction.rollback(); break; + case Success: + case Postponed: + case Discard: + default: transaction.commit(); break; + } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); if (transaction != null) transaction.rollback(); - success = false; - } finally { - if (entityManager != null) - entityManager.close(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); } - return success; + return status; } + private EventProcessingStatus processMessage(QueueInboxEntity queueInboxMessage) { IntegrationEventHandler handler; logger.debug("Processing message with routing key '{}'", queueInboxMessage.getRoute()); @@ -357,7 +387,7 @@ public class InboxRepositoryImpl implements InboxRepository { properties.setMessageId(queueInboxMessage.getMessageId().toString()); properties.setTenantId(queueInboxMessage.getTenantId()); - TrackedEvent event = this.jsonHandlingService.fromJsonSafe(TrackedEvent.class, queueInboxMessage.getMessage()); +// TrackedEvent event = this.jsonHandlingService.fromJsonSafe(TrackedEvent.class, queueInboxMessage.getMessage()); // using (LogContext.PushProperty(this._logTrackingConfig.LogTrackingContextName, @event.TrackingContextTag)) // { try { diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxRepositoryImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxRepositoryImpl.java index 4ec9735c3..6c39eb75a 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxRepositoryImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxRepositoryImpl.java @@ -4,6 +4,7 @@ import gr.cite.annotation.common.JsonHandlingService; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.fake.FakeRequestScope; import gr.cite.annotation.data.QueueOutboxEntity; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.annotation.query.QueueOutboxQuery; import gr.cite.queueoutbox.entity.QueueOutbox; import gr.cite.queueoutbox.entity.QueueOutboxNotifyStatus; @@ -14,10 +15,7 @@ import gr.cite.rabbitmq.IntegrationEvent; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.logging.LoggerService; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.*; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -33,31 +31,30 @@ public class OutboxRepositoryImpl implements OutboxRepository { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(OutboxRepositoryImpl.class)); - private final OutboxProperties outboxProperties; - private final EntityManagerFactory entityManagerFactory; - + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; + + public OutboxRepositoryImpl( - ApplicationContext applicationContext, - OutboxProperties outboxProperties, EntityManagerFactory entityManagerFactory + ApplicationContext applicationContext ) { this.applicationContext = applicationContext; - this.outboxProperties = outboxProperties; - this.entityManagerFactory = entityManagerFactory; } @Override public CandidateInfo candidate(Instant lastCandidateCreationTimestamp, MessageOptions messageOptions, Function onConfirmTimeout) { EntityTransaction transaction = null; - EntityManager entityManager = null; CandidateInfo candidate = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); transaction = entityManager.getTransaction(); transaction.begin(); + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); QueueOutboxEntity item = queryFactory.query(QueueOutboxQuery.class) .isActives(IsActive.Active) .notifyStatus(QueueOutboxNotifyStatus.PENDING, QueueOutboxNotifyStatus.WAITING_CONFIRMATION, QueueOutboxNotifyStatus.ERROR) @@ -95,8 +92,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); candidate = null; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex); @@ -108,12 +104,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean shouldOmit(CandidateInfo candidate, Function shouldOmit) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -140,8 +138,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -152,12 +149,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean shouldWait(CandidateInfo candidate, Function itIsTimeFunc) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -185,8 +184,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -197,13 +195,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean process(CandidateInfo candidateInfo, Boolean isAutoconfirmOnPublish, Function publish) { EntityTransaction transaction = null; - EntityManager entityManager = null; Boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -240,8 +239,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -252,12 +250,13 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public void handleConfirm(List confirmedMessages) { EntityTransaction transaction = null; - EntityManager entityManager = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -283,8 +282,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -294,12 +292,13 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public void handleNack(List nackedMessages) { EntityTransaction transaction = null; - EntityManager entityManager = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -325,8 +324,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -336,13 +334,15 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public QueueOutbox create(IntegrationEvent item) { EntityTransaction transaction = null; - EntityManager entityManager = null; QueueOutboxEntity queueMessage = null; + boolean success; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - queueMessage = this.mapEvent((OutboxIntegrationEvent) item); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - entityManager = this.entityManagerFactory.createEntityManager(); + queueMessage = this.mapEvent((OutboxIntegrationEvent) item); transaction = entityManager.getTransaction(); transaction.begin(); @@ -351,18 +351,20 @@ public class OutboxRepositoryImpl implements OutboxRepository { entityManager.flush(); transaction.commit(); + success = true; } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); } - return queueMessage; + return success ? queueMessage : null; } private QueueOutboxEntity mapEvent(OutboxIntegrationEvent event) { @@ -373,26 +375,5 @@ public class OutboxRepositoryImpl implements OutboxRepository { return null; } } - -// UUID correlationId = UUID.randomUUID(); -// if (event.getEvent() != null) -// event.getEvent().setTrackingContextTag(correlationId.toString()); -// event.setMessage(this.jsonHandlingService.toJsonSafe(event.getEvent())); -// //this._logTrackingService.Trace(correlationId.ToString(), $"Correlating current tracking context with new correlationId {correlationId}"); -// -// QueueOutboxEntity queueMessage = new QueueOutboxEntity(); -// queueMessage.setId(UUID.randomUUID()); -// queueMessage.setTenantId(event.getTenantId()); -// queueMessage.setExchange(this.outboxProperties.getExchange()); -// queueMessage.setRoute(routingKey); -// queueMessage.setMessageId(event.getMessageId()); -// queueMessage.setMessage(this.jsonHandlingService.toJsonSafe(event)); -// queueMessage.setIsActive(IsActive.Active); -// queueMessage.setNotifyStatus(QueueOutboxNotifyStatus.PENDING); -// queueMessage.setRetryCount(0); -// queueMessage.setCreatedAt(Instant.now()); -// queueMessage.setUpdatedAt(Instant.now()); -// -// return queueMessage; } -} +} \ No newline at end of file diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java index 76546c9e4..e03cad741 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java @@ -7,6 +7,7 @@ import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.user.UserScope; import gr.cite.annotation.data.AnnotationEntity; import gr.cite.annotation.data.EntityUserEntity; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.annotation.model.Annotation; import gr.cite.annotation.query.utils.BuildSubQueryInput; import gr.cite.annotation.query.utils.QueryUtilsService; @@ -14,6 +15,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -53,10 +55,12 @@ public class AnnotationQuery extends QueryBase { private final AuthorizationService authService; - public AnnotationQuery(UserScope userScope, QueryUtilsService queryUtilsService, AuthorizationService authService) { + private final TenantEntityManager tenantEntityManager; + public AnnotationQuery(UserScope userScope, QueryUtilsService queryUtilsService, AuthorizationService authService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.queryUtilsService = queryUtilsService; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public AnnotationQuery like(String value) { @@ -184,6 +188,11 @@ public class AnnotationQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || this.isEmpty(this.excludedIds) || this.isEmpty(this.isActives) || this.isEmpty(this.entityIds); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/EntityUserQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/EntityUserQuery.java index 0b30dfda2..5c40c4788 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/EntityUserQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/EntityUserQuery.java @@ -7,6 +7,7 @@ import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.user.UserScope; import gr.cite.annotation.data.AnnotationEntity; import gr.cite.annotation.data.EntityUserEntity; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.annotation.model.EntityUser; import gr.cite.annotation.query.utils.BuildSubQueryInput; import gr.cite.annotation.query.utils.QueryUtilsService; @@ -14,6 +15,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -37,10 +39,12 @@ public class EntityUserQuery extends QueryBase { private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); - public EntityUserQuery(AuthorizationService authService, UserScope userScope) { + private final TenantEntityManager tenantEntityManager; + public EntityUserQuery(AuthorizationService authService, UserScope userScope, TenantEntityManager tenantEntityManager) { this.authService = authService; this.userScope = userScope; - } + this.tenantEntityManager = tenantEntityManager; + } public EntityUserQuery ids(UUID value) { this.ids = List.of(value); @@ -117,6 +121,11 @@ public class EntityUserQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return false; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueInboxQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueInboxQuery.java index a525c2840..3a94707a2 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueInboxQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueInboxQuery.java @@ -2,11 +2,13 @@ package gr.cite.annotation.query; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.data.QueueInboxEntity; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.queueinbox.entity.QueueInboxStatus; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -30,6 +32,12 @@ public class QueueInboxQuery extends QueryBase { private Collection status; private Integer retryThreshold; + private final TenantEntityManager tenantEntityManager; + + public QueueInboxQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + public QueueInboxQuery ids(UUID value) { this.ids = List.of(value); return this; @@ -130,6 +138,11 @@ public class QueueInboxQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return QueueInboxEntity.class; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueOutboxQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueOutboxQuery.java index e4d100e95..10fd8042d 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueOutboxQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueOutboxQuery.java @@ -2,11 +2,13 @@ package gr.cite.annotation.query; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.data.QueueOutboxEntity; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.queueoutbox.entity.QueueOutboxNotifyStatus; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -30,6 +32,12 @@ public class QueueOutboxQuery extends QueryBase { private Integer retryThreshold; private Integer confirmTimeout; + private final TenantEntityManager tenantEntityManager; + + public QueueOutboxQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + public QueueOutboxQuery ids(UUID value) { this.ids = List.of(value); return this; @@ -135,6 +143,11 @@ public class QueueOutboxQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return QueueOutboxEntity.class; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantQuery.java index 7e85d0c56..abafd5940 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantQuery.java @@ -3,10 +3,12 @@ package gr.cite.annotation.query; import gr.cite.annotation.authorization.AuthorizationFlags; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.data.TenantEntity; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.annotation.model.Tenant; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.Predicate; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -28,7 +30,13 @@ public class TenantQuery extends QueryBase { private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); - public TenantQuery like(String value) { + private final TenantEntityManager tenantEntityManager; + + public TenantQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + + public TenantQuery like(String value) { this.like = value; return this; } @@ -78,6 +86,11 @@ public class TenantQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || this.isEmpty(this.isActives); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantUserQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantUserQuery.java index 3730c57eb..92da4154f 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantUserQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantUserQuery.java @@ -4,6 +4,7 @@ import gr.cite.annotation.authorization.AuthorizationFlags; import gr.cite.annotation.authorization.Permission; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.user.UserScope; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.annotation.data.TenantUserEntity; import gr.cite.annotation.data.UserEntity; import gr.cite.annotation.model.Tenant; @@ -12,6 +13,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -36,12 +38,14 @@ public class TenantUserQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; + private final TenantEntityManager tenantEntityManager; public TenantUserQuery( UserScope userScope, - AuthorizationService authService + AuthorizationService authService, TenantEntityManager tenantEntityManager ) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public TenantUserQuery ids(UUID value) { @@ -124,6 +128,11 @@ public class TenantUserQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return TenantUserEntity.class; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserCredentialQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserCredentialQuery.java index ba8bd1105..41b28e6ed 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserCredentialQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserCredentialQuery.java @@ -1,5 +1,6 @@ package gr.cite.annotation.query; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.annotation.authorization.AuthorizationFlags; import gr.cite.annotation.authorization.Permission; @@ -10,6 +11,7 @@ import gr.cite.annotation.model.UserCredential; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -40,9 +42,11 @@ public class UserCredentialQuery extends QueryBase { private final AuthorizationService authService; - public UserCredentialQuery(UserScope userScope, AuthorizationService authService) { + private final TenantEntityManager tenantEntityManager; + public UserCredentialQuery(UserScope userScope, AuthorizationService authService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserCredentialQuery ids(UUID value) { @@ -135,6 +139,11 @@ public class UserCredentialQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserQuery.java index 5c82f0735..8862cab65 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserQuery.java @@ -4,6 +4,7 @@ import gr.cite.annotation.authorization.AuthorizationFlags; import gr.cite.annotation.authorization.Permission; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.user.UserScope; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.annotation.data.UserEntity; import gr.cite.annotation.model.User; import gr.cite.annotation.model.user.PublicUser; @@ -11,6 +12,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -36,12 +38,14 @@ public class UserQuery extends QueryBase { private final AuthorizationService authService; + private final TenantEntityManager tenantEntityManager; public UserQuery( - UserScope userScope, - AuthorizationService authService + UserScope userScope, + AuthorizationService authService, TenantEntityManager tenantEntityManager ) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserQuery like(String value) { @@ -94,6 +98,11 @@ public class UserQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return UserEntity.class; diff --git a/annotation-service/pom.xml b/annotation-service/pom.xml index 76a693429..23acf8587 100644 --- a/annotation-service/pom.xml +++ b/annotation-service/pom.xml @@ -107,7 +107,7 @@ gr.cite data-tools - 2.1.4 + 2.1.5 diff --git a/backend/core/pom.xml b/backend/core/pom.xml index 5e7ed376c..e5dcf843a 100644 --- a/backend/core/pom.xml +++ b/backend/core/pom.xml @@ -61,7 +61,7 @@ gr.cite data-tools - 2.1.4 + 2.1.5 org.opencdmp diff --git a/backend/core/src/main/java/org/opencdmp/data/QueueOutboxEntity.java b/backend/core/src/main/java/org/opencdmp/data/QueueOutboxEntity.java index 2f4d01326..e0722aeb6 100644 --- a/backend/core/src/main/java/org/opencdmp/data/QueueOutboxEntity.java +++ b/backend/core/src/main/java/org/opencdmp/data/QueueOutboxEntity.java @@ -1,12 +1,12 @@ package org.opencdmp.data; +import gr.cite.queueoutbox.entity.QueueOutbox; +import gr.cite.queueoutbox.entity.QueueOutboxNotifyStatus; +import jakarta.persistence.*; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.data.converters.enums.IsActiveConverter; import org.opencdmp.data.converters.enums.QueueOutboxNotifyStatusConverter; -import gr.cite.queueoutbox.entity.QueueOutbox; -import gr.cite.queueoutbox.entity.QueueOutboxNotifyStatus; -import jakarta.persistence.*; import java.time.Instant; import java.util.UUID; @@ -65,11 +65,12 @@ public class QueueOutboxEntity implements QueueOutbox { public final static String _createdAt = "createdAt"; @Column(name = "\"updated_at\"", nullable = false) + @Version private Instant updatedAt; public final static String _updatedAt = "updatedAt"; public UUID getId() { - return id; + return this.id; } public void setId(UUID id) { @@ -77,7 +78,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public String getExchange() { - return exchange; + return this.exchange; } public void setExchange(String exchange) { @@ -85,7 +86,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public String getRoute() { - return route; + return this.route; } public void setRoute(String route) { @@ -93,7 +94,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public UUID getMessageId() { - return messageId; + return this.messageId; } public void setMessageId(UUID messageId) { @@ -101,7 +102,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public String getMessage() { - return message; + return this.message; } public void setMessage(String message) { @@ -109,7 +110,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public QueueOutboxNotifyStatus getNotifyStatus() { - return notifyStatus; + return this.notifyStatus; } public void setNotifyStatus(QueueOutboxNotifyStatus notifyStatus) { @@ -117,7 +118,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public Integer getRetryCount() { - return retryCount; + return this.retryCount; } public void setRetryCount(Integer retryCount) { @@ -125,7 +126,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public Instant getPublishedAt() { - return publishedAt; + return this.publishedAt; } public void setPublishedAt(Instant publishedAt) { @@ -133,7 +134,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public Instant getConfirmedAt() { - return confirmedAt; + return this.confirmedAt; } public void setConfirmedAt(Instant confirmedAt) { @@ -141,7 +142,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public UUID getTenantId() { - return tenantId; + return this.tenantId; } public void setTenantId(UUID tenantId) { @@ -149,7 +150,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public IsActive getIsActive() { - return isActive; + return this.isActive; } public void setIsActive(IsActive isActive) { @@ -157,7 +158,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public Instant getCreatedAt() { - return createdAt; + return this.createdAt; } public void setCreatedAt(Instant createdAt) { @@ -165,7 +166,7 @@ public class QueueOutboxEntity implements QueueOutbox { } public Instant getUpdatedAt() { - return updatedAt; + return this.updatedAt; } public void setUpdatedAt(Instant updatedAt) { diff --git a/backend/core/src/main/java/org/opencdmp/data/TenantEntityManager.java b/backend/core/src/main/java/org/opencdmp/data/TenantEntityManager.java index 992b2aa8d..867e01576 100644 --- a/backend/core/src/main/java/org/opencdmp/data/TenantEntityManager.java +++ b/backend/core/src/main/java/org/opencdmp/data/TenantEntityManager.java @@ -95,6 +95,8 @@ public class TenantEntityManager { } public void reloadTenantFilters() throws InvalidApplicationException { + if (!this.entityManager.isOpen()) return; + this.disableTenantFilters(); if (!this.tenantScope.isSet()) return; @@ -113,6 +115,8 @@ public class TenantEntityManager { } public void loadExplictTenantFilters() throws InvalidApplicationException { + if (!this.entityManager.isOpen()) return; + this.disableTenantFilters(); if (!this.tenantScope.isSet()) return; @@ -131,6 +135,8 @@ public class TenantEntityManager { } public void disableTenantFilters() { + if (!this.entityManager.isOpen()) return; + this.entityManager .unwrap(Session.class) .disableFilter(TenantScopedBaseEntity.TENANT_FILTER); diff --git a/backend/core/src/main/java/org/opencdmp/elastic/query/DmpElasticQuery.java b/backend/core/src/main/java/org/opencdmp/elastic/query/DmpElasticQuery.java index f83391659..1fa5d9ffb 100644 --- a/backend/core/src/main/java/org/opencdmp/elastic/query/DmpElasticQuery.java +++ b/backend/core/src/main/java/org/opencdmp/elastic/query/DmpElasticQuery.java @@ -20,7 +20,6 @@ import org.opencdmp.commons.enums.DmpStatus; import org.opencdmp.commons.enums.DmpVersionStatus; import org.opencdmp.commons.scope.tenant.TenantScope; import org.opencdmp.commons.scope.user.UserScope; -import org.opencdmp.elastic.data.DescriptionElasticEntity; import org.opencdmp.elastic.data.DmpElasticEntity; import org.opencdmp.elastic.data.nested.NestedDescriptionElasticEntity; import org.opencdmp.service.elastic.AppElasticProperties; @@ -250,7 +249,7 @@ public class DmpElasticQuery extends ElasticQuery { if (!predicates.isEmpty()) { return this.applyTenant(predicates); } else { - return this.equals(this.elasticFieldOf(DescriptionElasticEntity._id), UUID.randomUUID()); + return this.equals(this.elasticFieldOf(DmpElasticEntity._id), UUID.randomUUID()); } } diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/InboxIntegrationEventConfigurer.java b/backend/core/src/main/java/org/opencdmp/integrationevent/InboxIntegrationEventConfigurer.java index 3e9ecc3a2..400d635e5 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/InboxIntegrationEventConfigurer.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/InboxIntegrationEventConfigurer.java @@ -2,7 +2,6 @@ package org.opencdmp.integrationevent; import gr.cite.queueinbox.InboxConfigurer; import gr.cite.queueinbox.repository.InboxRepository; -import jakarta.persistence.EntityManagerFactory; import org.opencdmp.integrationevent.inbox.InboxProperties; import org.opencdmp.integrationevent.inbox.InboxRepositoryImpl; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -17,17 +16,15 @@ import org.springframework.context.annotation.Configuration; public class InboxIntegrationEventConfigurer extends InboxConfigurer { private final ApplicationContext applicationContext; private final InboxProperties inboxProperties; - private final EntityManagerFactory entityManagerFactory; - public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties, EntityManagerFactory entityManagerFactory) { + public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties) { this.applicationContext = applicationContext; this.inboxProperties = inboxProperties; - this.entityManagerFactory = entityManagerFactory; } @Bean public InboxRepository inboxRepositoryCreator() { - return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties, this.entityManagerFactory); + return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties); } } diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/OutboxIntegrationEventConfigurer.java b/backend/core/src/main/java/org/opencdmp/integrationevent/OutboxIntegrationEventConfigurer.java index 3bc62d7b7..2ada96720 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/OutboxIntegrationEventConfigurer.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/OutboxIntegrationEventConfigurer.java @@ -7,7 +7,6 @@ import gr.cite.queueoutbox.repository.OutboxRepository; import gr.cite.rabbitmq.IntegrationEventMessageConstants; import gr.cite.rabbitmq.RabbitProperties; import gr.cite.rabbitmq.broker.MessageHydrator; -import jakarta.persistence.EntityManagerFactory; import org.opencdmp.data.QueueOutboxEntity; import org.opencdmp.integrationevent.outbox.OutboxProperties; import org.opencdmp.integrationevent.outbox.OutboxRepositoryImpl; @@ -29,12 +28,10 @@ import java.util.UUID; public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { private final ApplicationContext applicationContext; private final OutboxProperties outboxProperties; - private final EntityManagerFactory entityManagerFactory; - public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties, EntityManagerFactory entityManagerFactory) { + public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties) { this.applicationContext = applicationContext; this.outboxProperties = outboxProperties; - this.entityManagerFactory = entityManagerFactory; } @Bean @@ -70,7 +67,7 @@ public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { @Bean public OutboxRepository outboxRepositoryCreator() { - return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties, this.entityManagerFactory); + return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties); } } diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxRepositoryImpl.java b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxRepositoryImpl.java index 567ea8219..8136c1e35 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxRepositoryImpl.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxRepositoryImpl.java @@ -10,16 +10,11 @@ import gr.cite.rabbitmq.consumer.InboxCreatorParams; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.logging.LoggerService; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; -import org.opencdmp.commons.JsonHandlingService; +import jakarta.persistence.*; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.fake.FakeRequestScope; import org.opencdmp.data.QueueInboxEntity; import org.opencdmp.data.TenantEntityManager; -import org.opencdmp.integrationevent.TrackedEvent; import org.opencdmp.query.QueueInboxQuery; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -29,34 +24,35 @@ import java.util.List; import java.util.UUID; import java.util.function.Function; -public class InboxRepositoryImpl implements InboxRepository { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(InboxRepositoryImpl.class)); +public class InboxRepositoryImpl implements InboxRepository { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(InboxRepositoryImpl.class)); protected final ApplicationContext applicationContext; - - private final JsonHandlingService jsonHandlingService; - private final InboxProperties inboxProperties; - private final EntityManagerFactory entityManagerFactory; + + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; public InboxRepositoryImpl( - ApplicationContext applicationContext, - InboxProperties inboxProperties, EntityManagerFactory entityManagerFactory + ApplicationContext applicationContext, + InboxProperties inboxProperties ) { this.applicationContext = applicationContext; - this.entityManagerFactory = entityManagerFactory; - this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class); this.inboxProperties = inboxProperties; } @Override public CandidateInfo candidate(Instant lastCandidateCreationTimestamp, MessageOptions options) { EntityTransaction transaction = null; - EntityManager entityManager = null; CandidateInfo candidate = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -95,8 +91,7 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin transaction.rollback(); candidate = null; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem getting list of queue inbox. Skipping: {}", ex.getMessage(), ex); @@ -108,12 +103,14 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin @Override public Boolean shouldOmit(CandidateInfo candidate, Function shouldOmit) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -140,8 +137,7 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -152,12 +148,14 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin @Override public boolean shouldWait(CandidateInfo candidate, Function itIsTimeFunc) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -185,8 +183,7 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -197,13 +194,16 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin @Override public QueueInbox create(InboxCreatorParams inboxCreatorParams) { EntityTransaction transaction = null; - EntityManager entityManager = null; - boolean success = false; + boolean success; QueueInboxEntity queueMessage = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + queueMessage = this.createQueueInboxEntity(inboxCreatorParams); - entityManager = this.entityManagerFactory.createEntityManager(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -212,23 +212,22 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin entityManager.flush(); transaction.commit(); + success = true; } catch (Exception ex) { - logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); - if (transaction != null) - transaction.rollback(); success = false; + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); } - return queueMessage; + return success ? queueMessage : null; } private QueueInboxEntity createQueueInboxEntity(InboxCreatorParams inboxCreatorParams) { - QueueInboxEntity queueMessage = new QueueInboxEntity(); queueMessage.setId(UUID.randomUUID()); Object tenantId = inboxCreatorParams.getHeaders() != null ? inboxCreatorParams.getHeaders().getOrDefault(IntegrationEventMessageConstants.TENANT, null) : null; @@ -237,6 +236,7 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin try { queueMessage.setTenantId(UUID.fromString((String) tenantId)); } catch (Exception e) { + logger.error(e.getMessage(), e); } } queueMessage.setExchange(this.inboxProperties.getExchange()); @@ -256,27 +256,26 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin @Override public Boolean emit(CandidateInfo candidateInfo) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; - + QueueInboxEntity queueInboxMessage; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); + queueInboxMessage = queryFactory.query(QueueInboxQuery.class).ids(candidateInfo.getId()).first(); + } + if (queueInboxMessage == null) { + logger.warn("Could not lookup queue inbox {} to process. Continuing...", candidateInfo.getId()); + } else { + EventProcessingStatus status = this.emitQueueInboxEntity(queueInboxMessage); + try (FakeRequestScope ignored = new FakeRequestScope()) { TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); - tenantEntityManager.setEntityManager(entityManager); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - transaction.begin(); + transaction = entityManager.getTransaction(); - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - QueueInboxEntity queueInboxMessage = queryFactory.query(QueueInboxQuery.class).ids(candidateInfo.getId()).first(); + transaction.begin(); - if (queueInboxMessage == null) { - logger.warn("Could not lookup queue inbox {} to process. Continuing...", candidateInfo.getId()); - } else { - - EventProcessingStatus status = this.processMessage(queueInboxMessage); switch (status) { case Success: { queueInboxMessage.setStatus(QueueInboxStatus.SUCCESSFUL); @@ -301,25 +300,57 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin entityManager.merge(queueInboxMessage); entityManager.flush(); - } - transaction.commit(); + transaction.commit(); + } catch (Exception ex) { + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + if (transaction != null) + transaction.rollback(); + success = false; + } finally { + tenantEntityManager.reloadTenantFilters(); + } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); - if (transaction != null) - transaction.rollback(); - success = false; - } finally { - if (entityManager != null) - entityManager.close(); } - } catch (Exception ex) { - logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + } return success; } + public EventProcessingStatus emitQueueInboxEntity(QueueInboxEntity queueInboxMessage) { + EntityTransaction transaction = null; + EventProcessingStatus status = EventProcessingStatus.Discard; + try (FakeRequestScope ignored = new FakeRequestScope()) { + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + tenantEntityManager.setEntityManager(entityManager); + transaction = entityManager.getTransaction(); + + transaction.begin(); + + status = this.processMessage(queueInboxMessage); + + entityManager.flush(); + + switch (status) { + case Error: transaction.rollback(); break; + case Success: + case Postponed: + case Discard: + default: transaction.commit(); break; + } + } catch (Exception ex) { + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + if (transaction != null) + transaction.rollback(); + } + } catch (Exception ex) { + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + } + return status; + } private EventProcessingStatus processMessage(QueueInboxEntity queueInboxMessage) { IntegrationEventHandler handler = null; @@ -339,13 +370,13 @@ public class InboxRepositoryImpl implements InboxRepository { private static fin properties.setMessageId(queueInboxMessage.getMessageId().toString()); properties.setTenantId(queueInboxMessage.getTenantId()); - TrackedEvent event = this.jsonHandlingService.fromJsonSafe(TrackedEvent.class, queueInboxMessage.getMessage()); +// TrackedEvent event = this.jsonHandlingService.fromJsonSafe(TrackedEvent.class, queueInboxMessage.getMessage()); // using (LogContext.PushProperty(this._logTrackingConfig.LogTrackingContextName, @event.TrackingContextTag)) // { try { return handler.handle(properties, queueInboxMessage.getMessage()); } catch (Exception ex) { - logger.error("problem handling event from routing key " + queueInboxMessage.getRoute() + ". Setting nack and continuing...", ex); + logger.error("problem handling event from routing key {}. Setting nack and continuing...", queueInboxMessage.getRoute(), ex); return EventProcessingStatus.Error; } // } diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxRepositoryImpl.java b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxRepositoryImpl.java index 0ba279b12..72a6c0013 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxRepositoryImpl.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/outbox/OutboxRepositoryImpl.java @@ -9,14 +9,12 @@ import gr.cite.rabbitmq.IntegrationEvent; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.logging.LoggerService; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.*; import org.opencdmp.commons.JsonHandlingService; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.fake.FakeRequestScope; import org.opencdmp.data.QueueOutboxEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.query.QueueOutboxQuery; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -33,17 +31,16 @@ public class OutboxRepositoryImpl implements OutboxRepository { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(OutboxRepositoryImpl.class)); + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; + + private final OutboxProperties outboxProperties; private final JsonHandlingService jsonHandlingService; - private final OutboxProperties outboxProperties; - private final EntityManagerFactory entityManagerFactory; - public OutboxRepositoryImpl( - ApplicationContext applicationContext, - OutboxProperties outboxProperties, EntityManagerFactory entityManagerFactory + ApplicationContext applicationContext, OutboxProperties outboxProperties ) { this.applicationContext = applicationContext; - this.entityManagerFactory = entityManagerFactory; this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class); this.outboxProperties = outboxProperties; } @@ -51,16 +48,17 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public CandidateInfo candidate(Instant lastCandidateCreationTimestamp, MessageOptions messageOptions, Function onConfirmTimeout) { EntityTransaction transaction = null; - EntityManager entityManager = null; CandidateInfo candidate = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); transaction = entityManager.getTransaction(); transaction.begin(); + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); QueueOutboxEntity item = queryFactory.query(QueueOutboxQuery.class) .isActives(IsActive.Active) .notifyStatus(QueueOutboxNotifyStatus.PENDING, QueueOutboxNotifyStatus.WAITING_CONFIRMATION, QueueOutboxNotifyStatus.ERROR) @@ -98,8 +96,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); candidate = null; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex); @@ -111,13 +108,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean shouldOmit(CandidateInfo candidate, Function shouldOmit) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -144,8 +142,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -156,12 +153,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean shouldWait(CandidateInfo candidate, Function itIsTimeFunc) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -189,8 +188,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -201,12 +199,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean process(CandidateInfo candidateInfo, Boolean isAutoconfirmOnPublish, Function publish) { EntityTransaction transaction = null; - EntityManager entityManager = null; Boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -243,8 +243,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -255,11 +254,13 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public void handleConfirm(List confirmedMessages) { EntityTransaction transaction = null; - EntityManager entityManager = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -285,8 +286,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -296,11 +296,13 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public void handleNack(List nackedMessages) { EntityTransaction transaction = null; - EntityManager entityManager = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -326,8 +328,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -337,13 +338,15 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public QueueOutbox create(IntegrationEvent item) { EntityTransaction transaction = null; - EntityManager entityManager = null; QueueOutboxEntity queueMessage = null; + boolean success; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - queueMessage = this.mapEvent((OutboxIntegrationEvent) item); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - entityManager = this.entityManagerFactory.createEntityManager(); + queueMessage = this.mapEvent((OutboxIntegrationEvent) item); transaction = entityManager.getTransaction(); transaction.begin(); @@ -352,18 +355,20 @@ public class OutboxRepositoryImpl implements OutboxRepository { entityManager.flush(); transaction.commit(); + success = true; } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); } - return queueMessage; + return success ? queueMessage : null; } private QueueOutboxEntity mapEvent(OutboxIntegrationEvent event) { diff --git a/backend/core/src/main/java/org/opencdmp/model/builder/dmp/DmpBuilder.java b/backend/core/src/main/java/org/opencdmp/model/builder/dmp/DmpBuilder.java index 745521b8d..a8149da5a 100644 --- a/backend/core/src/main/java/org/opencdmp/model/builder/dmp/DmpBuilder.java +++ b/backend/core/src/main/java/org/opencdmp/model/builder/dmp/DmpBuilder.java @@ -8,8 +8,6 @@ import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.DataLogEntry; import gr.cite.tools.logging.LoggerService; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; import org.opencdmp.authorization.AffiliatedResource; import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.authorization.authorizationcontentresolver.AuthorizationContentResolver; @@ -35,7 +33,6 @@ import org.opencdmp.model.dmpblueprint.DmpBlueprint; import org.opencdmp.model.dmpreference.DmpReference; import org.opencdmp.model.user.User; import org.opencdmp.query.*; -import org.opencdmp.service.externalfetcher.config.entities.SourceBaseConfiguration; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -49,8 +46,6 @@ import java.util.stream.Collectors; @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class DmpBuilder extends BaseBuilder { - @PersistenceContext - private EntityManager entityManager; private final QueryFactory queryFactory; private final BuilderFactory builderFactory; diff --git a/backend/core/src/main/java/org/opencdmp/query/ActionConfirmationQuery.java b/backend/core/src/main/java/org/opencdmp/query/ActionConfirmationQuery.java index 9f1829ace..12cda1aa8 100644 --- a/backend/core/src/main/java/org/opencdmp/query/ActionConfirmationQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/ActionConfirmationQuery.java @@ -3,6 +3,7 @@ package org.opencdmp.query; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -11,6 +12,7 @@ import org.opencdmp.commons.enums.ActionConfirmationStatus; import org.opencdmp.commons.enums.ActionConfirmationType; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.data.ActionConfirmationEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.actionconfirmation.ActionConfirmation; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -44,8 +46,10 @@ public class ActionConfirmationQuery extends QueryBase private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); private final QueryUtilsService queryUtilsService; - public ActionConfirmationQuery(QueryUtilsService queryUtilsService) { + private final TenantEntityManager tenantEntityManager; + public ActionConfirmationQuery(QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } public ActionConfirmationQuery like(String value) { @@ -174,6 +178,11 @@ public class ActionConfirmationQuery extends QueryBase return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/backend/core/src/main/java/org/opencdmp/query/DescriptionQuery.java b/backend/core/src/main/java/org/opencdmp/query/DescriptionQuery.java index 7e6e131cf..e69754815 100644 --- a/backend/core/src/main/java/org/opencdmp/query/DescriptionQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/DescriptionQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -15,6 +16,7 @@ import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DescriptionEntity; import org.opencdmp.data.DmpDescriptionTemplateEntity; import org.opencdmp.data.DmpEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.PublicDescription; import org.opencdmp.model.description.Description; import org.opencdmp.query.utils.QueryUtilsService; @@ -65,10 +67,12 @@ public class DescriptionQuery extends QueryBase { private Collection dmpDescriptionTemplateIds; - public DescriptionQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) { + private final TenantEntityManager tenantEntityManager; + public DescriptionQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } public DescriptionQuery like(String value) { @@ -221,6 +225,11 @@ public class DescriptionQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/backend/core/src/main/java/org/opencdmp/query/DescriptionReferenceQuery.java b/backend/core/src/main/java/org/opencdmp/query/DescriptionReferenceQuery.java index 7c17660bc..9c435a3c7 100644 --- a/backend/core/src/main/java/org/opencdmp/query/DescriptionReferenceQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/DescriptionReferenceQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -12,6 +13,7 @@ import org.opencdmp.authorization.Permission; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DescriptionReferenceEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.descriptionreference.DescriptionReference; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -40,10 +42,12 @@ public class DescriptionReferenceQuery extends QueryBase { this.noTracking = true; return this; } - - - public DescriptionTagQuery() { + + + private final TenantEntityManager tenantEntityManager; + public DescriptionTagQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/DescriptionTemplateQuery.java b/backend/core/src/main/java/org/opencdmp/query/DescriptionTemplateQuery.java index a1b6ad4aa..e81c0c85d 100644 --- a/backend/core/src/main/java/org/opencdmp/query/DescriptionTemplateQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/DescriptionTemplateQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -17,6 +18,7 @@ import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DescriptionTemplateEntity; import org.opencdmp.data.DmpDescriptionTemplateEntity; import org.opencdmp.data.DmpEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.descriptiontemplate.DescriptionTemplate; import org.opencdmp.query.utils.BuildSubQueryInput; import org.opencdmp.query.utils.QueryUtilsService; @@ -227,12 +229,19 @@ public class DescriptionTemplateQuery extends QueryBase entityClass() { return DescriptionTemplateTypeEntity.class; diff --git a/backend/core/src/main/java/org/opencdmp/query/DmpBlueprintQuery.java b/backend/core/src/main/java/org/opencdmp/query/DmpBlueprintQuery.java index 88bce1894..ed3b33f37 100644 --- a/backend/core/src/main/java/org/opencdmp/query/DmpBlueprintQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/DmpBlueprintQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -12,6 +13,7 @@ import org.opencdmp.commons.enums.DmpBlueprintStatus; import org.opencdmp.commons.enums.DmpBlueprintVersionStatus; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.data.DmpBlueprintEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.dmpblueprint.DmpBlueprint; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -168,11 +170,18 @@ public class DmpBlueprintQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public DmpBlueprintQuery( - AuthorizationService authService, QueryUtilsService queryUtilsService + AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager ) { this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/DmpDescriptionTemplateQuery.java b/backend/core/src/main/java/org/opencdmp/query/DmpDescriptionTemplateQuery.java index 5c8346daa..c2be75564 100644 --- a/backend/core/src/main/java/org/opencdmp/query/DmpDescriptionTemplateQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/DmpDescriptionTemplateQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -13,6 +14,7 @@ import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DescriptionTemplateEntity; import org.opencdmp.data.DmpDescriptionTemplateEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.DmpDescriptionTemplate; import org.opencdmp.model.PublicDmpDescriptionTemplate; import org.opencdmp.query.utils.QueryUtilsService; @@ -160,17 +162,24 @@ public class DmpDescriptionTemplateQuery extends QueryBase { private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; - public DmpQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) { + public DmpQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } public DmpQuery like(String value) { @@ -251,6 +254,11 @@ public class DmpQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || this.isEmpty(this.creatorIds) || this.isEmpty(this.isActives) || this.isEmpty(this.versionStatuses) || this.isEmpty(this.excludedIds) || this.isEmpty(this.accessTypes) || this.isEmpty(this.statuses) || this.isFalseQuery(this.dmpDescriptionTemplateQuery) || this.isFalseQuery(this.dmpUserQuery); diff --git a/backend/core/src/main/java/org/opencdmp/query/DmpReferenceQuery.java b/backend/core/src/main/java/org/opencdmp/query/DmpReferenceQuery.java index 764077ff1..cc6905390 100644 --- a/backend/core/src/main/java/org/opencdmp/query/DmpReferenceQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/DmpReferenceQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -14,6 +15,7 @@ import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DmpEntity; import org.opencdmp.data.DmpReferenceEntity; import org.opencdmp.data.ReferenceEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.PublicDmpReference; import org.opencdmp.model.dmpreference.DmpReference; import org.opencdmp.query.utils.QueryUtilsService; @@ -130,14 +132,21 @@ public class DmpReferenceQuery extends QueryBase { private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public DmpReferenceQuery( - UserScope userScope, - AuthorizationService authService, - QueryUtilsService queryUtilsService) { + UserScope userScope, + AuthorizationService authService, + QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/DmpUserQuery.java b/backend/core/src/main/java/org/opencdmp/query/DmpUserQuery.java index 821e92b52..c23b3ef19 100644 --- a/backend/core/src/main/java/org/opencdmp/query/DmpUserQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/DmpUserQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -15,6 +16,7 @@ import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DescriptionEntity; import org.opencdmp.data.DmpUserEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.DmpUser; import org.opencdmp.model.PublicDmpUser; import org.opencdmp.query.utils.BuildSubQueryInput; @@ -177,14 +179,21 @@ public class DmpUserQuery extends QueryBase { private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public DmpUserQuery( - UserScope userScope, - AuthorizationService authService, - QueryUtilsService queryUtilsService) { + UserScope userScope, + AuthorizationService authService, + QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/EntityDoiQuery.java b/backend/core/src/main/java/org/opencdmp/query/EntityDoiQuery.java index 353724b72..bec4b92bc 100644 --- a/backend/core/src/main/java/org/opencdmp/query/EntityDoiQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/EntityDoiQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -14,6 +15,7 @@ import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DmpEntity; import org.opencdmp.data.EntityDoiEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.EntityDoi; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -175,12 +177,19 @@ public class EntityDoiQuery extends QueryBase { private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public EntityDoiQuery( - UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) { + UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/LanguageQuery.java b/backend/core/src/main/java/org/opencdmp/query/LanguageQuery.java index ef7734448..c9b7ac9c2 100644 --- a/backend/core/src/main/java/org/opencdmp/query/LanguageQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/LanguageQuery.java @@ -3,12 +3,14 @@ package org.opencdmp.query; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.data.LanguageEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.Language; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -115,9 +117,16 @@ public class LanguageQuery extends QueryBase { } private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public LanguageQuery( - QueryUtilsService queryUtilsService) { + QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/LockQuery.java b/backend/core/src/main/java/org/opencdmp/query/LockQuery.java index 1c2010f39..1fd1883df 100644 --- a/backend/core/src/main/java/org/opencdmp/query/LockQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/LockQuery.java @@ -3,6 +3,7 @@ package org.opencdmp.query; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -10,6 +11,7 @@ import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.commons.enums.LockTargetType; import org.opencdmp.convention.ConventionService; import org.opencdmp.data.LockEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.Lock; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; @@ -148,8 +150,15 @@ public class LockQuery extends QueryBase { return this; } - public LockQuery(ConventionService conventionService) { + private final TenantEntityManager tenantEntityManager; + public LockQuery(ConventionService conventionService, TenantEntityManager tenantEntityManager) { this.conventionService = conventionService; + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/PrefillingSourceQuery.java b/backend/core/src/main/java/org/opencdmp/query/PrefillingSourceQuery.java index a6db5a2bc..df3bbb8a4 100644 --- a/backend/core/src/main/java/org/opencdmp/query/PrefillingSourceQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/PrefillingSourceQuery.java @@ -3,12 +3,14 @@ package org.opencdmp.query; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.data.PrefillingSourceEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.prefillingsource.PrefillingSource; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -32,6 +34,7 @@ public class PrefillingSourceQuery extends QueryBase { private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + public PrefillingSourceQuery like(String value) { this.like = value; return this; @@ -99,11 +102,18 @@ public class PrefillingSourceQuery extends QueryBase { private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public PrefillingSourceQuery( - QueryUtilsService queryUtilsService) { + TenantEntityManager tenantEntityManager, QueryUtilsService queryUtilsService) { + this.tenantEntityManager = tenantEntityManager; this.queryUtilsService = queryUtilsService; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return PrefillingSourceEntity.class; diff --git a/backend/core/src/main/java/org/opencdmp/query/QueueInboxQuery.java b/backend/core/src/main/java/org/opencdmp/query/QueueInboxQuery.java index e06ba580c..2b0e5a33c 100644 --- a/backend/core/src/main/java/org/opencdmp/query/QueueInboxQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/QueueInboxQuery.java @@ -6,11 +6,13 @@ import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.data.QueueInboxEntity; +import org.opencdmp.data.TenantEntityManager; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -29,6 +31,12 @@ public class QueueInboxQuery extends QueryBase { private Collection routes; private Collection status; private Integer retryThreshold; + + private final TenantEntityManager tenantEntityManager; + + public QueueInboxQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } public QueueInboxQuery ids(UUID value) { this.ids = List.of(value); @@ -130,6 +138,11 @@ public class QueueInboxQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return QueueInboxEntity.class; diff --git a/backend/core/src/main/java/org/opencdmp/query/QueueOutboxQuery.java b/backend/core/src/main/java/org/opencdmp/query/QueueOutboxQuery.java index 8eafb9797..570ebddcd 100644 --- a/backend/core/src/main/java/org/opencdmp/query/QueueOutboxQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/QueueOutboxQuery.java @@ -6,11 +6,13 @@ import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.data.QueueOutboxEntity; +import org.opencdmp.data.TenantEntityManager; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -31,6 +33,12 @@ public class QueueOutboxQuery extends QueryBase { private Integer retryThreshold; private Integer confirmTimeout; + private final TenantEntityManager tenantEntityManager; + + public QueueOutboxQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + public QueueOutboxQuery ids(UUID value) { this.ids = List.of(value); return this; @@ -136,6 +144,11 @@ public class QueueOutboxQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return QueueOutboxEntity.class; diff --git a/backend/core/src/main/java/org/opencdmp/query/ReferenceQuery.java b/backend/core/src/main/java/org/opencdmp/query/ReferenceQuery.java index d0732c9df..2dedd72ab 100644 --- a/backend/core/src/main/java/org/opencdmp/query/ReferenceQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/ReferenceQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -12,10 +13,7 @@ import org.opencdmp.authorization.Permission; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.enums.ReferenceSourceType; import org.opencdmp.commons.scope.user.UserScope; -import org.opencdmp.data.DescriptionReferenceEntity; -import org.opencdmp.data.DmpEntity; -import org.opencdmp.data.DmpReferenceEntity; -import org.opencdmp.data.ReferenceEntity; +import org.opencdmp.data.*; import org.opencdmp.model.PublicReference; import org.opencdmp.model.reference.Reference; import org.opencdmp.query.utils.BuildSubQueryInput; @@ -193,12 +191,19 @@ public class ReferenceQuery extends QueryBase { private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public ReferenceQuery( - UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) { + UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/ReferenceTypeQuery.java b/backend/core/src/main/java/org/opencdmp/query/ReferenceTypeQuery.java index b23487ba1..8500a37f0 100644 --- a/backend/core/src/main/java/org/opencdmp/query/ReferenceTypeQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/ReferenceTypeQuery.java @@ -3,6 +3,7 @@ package org.opencdmp.query; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -10,6 +11,7 @@ import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.data.ReferenceEntity; import org.opencdmp.data.ReferenceTypeEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.referencetype.ReferenceType; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -117,9 +119,16 @@ public class ReferenceTypeQuery extends QueryBase { private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public ReferenceTypeQuery( - QueryUtilsService queryUtilsService) { + QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/StorageFileQuery.java b/backend/core/src/main/java/org/opencdmp/query/StorageFileQuery.java index 2f8b40b1b..44221b782 100644 --- a/backend/core/src/main/java/org/opencdmp/query/StorageFileQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/StorageFileQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -12,6 +13,7 @@ import org.opencdmp.authorization.Permission; import org.opencdmp.commons.enums.StorageType; import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.StorageFileEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.StorageFile; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -36,10 +38,12 @@ public class StorageFileQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; - public StorageFileQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) { + private final TenantEntityManager tenantEntityManager; + public StorageFileQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } public StorageFileQuery like(String value) { @@ -122,6 +126,11 @@ public class StorageFileQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/backend/core/src/main/java/org/opencdmp/query/SupportiveMaterialQuery.java b/backend/core/src/main/java/org/opencdmp/query/SupportiveMaterialQuery.java index ecdd720ea..3f2b6dd4e 100644 --- a/backend/core/src/main/java/org/opencdmp/query/SupportiveMaterialQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/SupportiveMaterialQuery.java @@ -3,6 +3,7 @@ package org.opencdmp.query; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -10,6 +11,7 @@ import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.enums.SupportiveMaterialFieldType; import org.opencdmp.data.SupportiveMaterialEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.SupportiveMaterial; import org.opencdmp.query.utils.QueryUtilsService; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -133,9 +135,16 @@ public class SupportiveMaterialQuery extends QueryBase } private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public SupportiveMaterialQuery( - QueryUtilsService queryUtilsService) { + QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; + } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); } @Override diff --git a/backend/core/src/main/java/org/opencdmp/query/TagQuery.java b/backend/core/src/main/java/org/opencdmp/query/TagQuery.java index 465c53b2f..d519ff765 100644 --- a/backend/core/src/main/java/org/opencdmp/query/TagQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/TagQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -13,6 +14,7 @@ import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DescriptionTagEntity; import org.opencdmp.data.TagEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.Tag; import org.opencdmp.query.utils.BuildSubQueryInput; import org.opencdmp.query.utils.QueryUtilsService; @@ -46,11 +48,13 @@ public class TagQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; - public TagQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) { + public TagQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } public TagQuery like(String value) { @@ -168,6 +172,11 @@ public class TagQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/backend/core/src/main/java/org/opencdmp/query/TenantConfigurationQuery.java b/backend/core/src/main/java/org/opencdmp/query/TenantConfigurationQuery.java index f32a2c14e..e184c6948 100644 --- a/backend/core/src/main/java/org/opencdmp/query/TenantConfigurationQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/TenantConfigurationQuery.java @@ -4,6 +4,7 @@ package org.opencdmp.query; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -11,6 +12,7 @@ import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.enums.TenantConfigurationType; import org.opencdmp.data.TenantConfigurationEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.model.tenantconfiguration.TenantConfiguration; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; @@ -32,7 +34,9 @@ public class TenantConfigurationQuery extends QueryBase authorize = EnumSet.of(AuthorizationFlags.None); - public TenantConfigurationQuery() { + private final TenantEntityManager tenantEntityManager; + public TenantConfigurationQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; } public TenantConfigurationQuery ids(UUID value) { @@ -130,6 +134,11 @@ public class TenantConfigurationQuery extends QueryBase { private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; - public TenantQuery(QueryUtilsService queryUtilsService) { + public TenantQuery(QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } public TenantQuery like(String value) { @@ -117,6 +121,11 @@ public class TenantQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || this.isEmpty(this.codes) ||this.isEmpty(this.isActives); diff --git a/backend/core/src/main/java/org/opencdmp/query/TenantUserQuery.java b/backend/core/src/main/java/org/opencdmp/query/TenantUserQuery.java index 79d7f5b29..5fb834e9f 100644 --- a/backend/core/src/main/java/org/opencdmp/query/TenantUserQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/TenantUserQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -11,6 +12,7 @@ import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.authorization.Permission; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.scope.user.UserScope; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.data.TenantUserEntity; import org.opencdmp.data.UserEntity; import org.opencdmp.model.TenantUser; @@ -33,13 +35,15 @@ public class TenantUserQuery extends QueryBase { private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); private final UserScope userScope; private final AuthorizationService authService; + private final TenantEntityManager tenantEntityManager; public TenantUserQuery( UserScope userScope, - AuthorizationService authService + AuthorizationService authService, TenantEntityManager tenantEntityManager ) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public TenantUserQuery ids(UUID value) { @@ -122,6 +126,11 @@ public class TenantUserQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return TenantUserEntity.class; diff --git a/backend/core/src/main/java/org/opencdmp/query/UserContactInfoQuery.java b/backend/core/src/main/java/org/opencdmp/query/UserContactInfoQuery.java index ca0e6419c..f40423fd6 100644 --- a/backend/core/src/main/java/org/opencdmp/query/UserContactInfoQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/UserContactInfoQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -12,6 +13,7 @@ import org.opencdmp.authorization.Permission; import org.opencdmp.commons.enums.ContactInfoType; import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.data.DmpUserEntity; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.data.UserContactInfoEntity; import org.opencdmp.model.UserContactInfo; import org.opencdmp.query.utils.BuildSubQueryInput; @@ -37,10 +39,12 @@ public class UserContactInfoQuery extends QueryBase { private final QueryUtilsService queryUtilsService; private final UserScope userScope; private final AuthorizationService authService; - public UserContactInfoQuery(QueryUtilsService queryUtilsService, UserScope userScope, AuthorizationService authService) { + private final TenantEntityManager tenantEntityManager; + public UserContactInfoQuery(QueryUtilsService queryUtilsService, UserScope userScope, AuthorizationService authService, TenantEntityManager tenantEntityManager) { this.queryUtilsService = queryUtilsService; this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserContactInfoQuery ids(UUID value) { @@ -147,6 +151,11 @@ public class UserContactInfoQuery extends QueryBase { this.authorize = values; return this; } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } @Override protected Boolean isFalseQuery() { return diff --git a/backend/core/src/main/java/org/opencdmp/query/UserCredentialQuery.java b/backend/core/src/main/java/org/opencdmp/query/UserCredentialQuery.java index 55ca85578..4b8dececf 100644 --- a/backend/core/src/main/java/org/opencdmp/query/UserCredentialQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/UserCredentialQuery.java @@ -4,12 +4,14 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.authorization.Permission; import org.opencdmp.commons.scope.user.UserScope; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.data.UserCredentialEntity; import org.opencdmp.model.usercredential.UserCredential; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -31,9 +33,11 @@ public class UserCredentialQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; - public UserCredentialQuery(UserScope userScope, AuthorizationService authService) { + private final TenantEntityManager tenantEntityManager; + public UserCredentialQuery(UserScope userScope, AuthorizationService authService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserCredentialQuery ids(UUID value) { @@ -111,6 +115,11 @@ public class UserCredentialQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/backend/core/src/main/java/org/opencdmp/query/UserDescriptionTemplateQuery.java b/backend/core/src/main/java/org/opencdmp/query/UserDescriptionTemplateQuery.java index 6e6f738f0..4c5a02d38 100644 --- a/backend/core/src/main/java/org/opencdmp/query/UserDescriptionTemplateQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/UserDescriptionTemplateQuery.java @@ -3,12 +3,14 @@ package org.opencdmp.query; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.enums.UserDescriptionTemplateRole; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.data.UserDescriptionTemplateEntity; import org.opencdmp.model.UserDescriptionTemplate; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -136,9 +138,16 @@ public class UserDescriptionTemplateQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; - public UserQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService) { + private final TenantEntityManager tenantEntityManager; + public UserQuery(UserScope userScope, AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } public UserQuery like(String value) { @@ -140,6 +140,11 @@ public class UserQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/backend/core/src/main/java/org/opencdmp/query/UserRoleQuery.java b/backend/core/src/main/java/org/opencdmp/query/UserRoleQuery.java index 96852d2f6..b53812004 100644 --- a/backend/core/src/main/java/org/opencdmp/query/UserRoleQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/UserRoleQuery.java @@ -4,12 +4,14 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.authorization.Permission; import org.opencdmp.commons.scope.user.UserScope; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.data.UserRoleEntity; import org.opencdmp.model.UserRole; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -33,9 +35,11 @@ public class UserRoleQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; - public UserRoleQuery(UserScope userScope, AuthorizationService authService) { + private final TenantEntityManager tenantEntityManager; + public UserRoleQuery(UserScope userScope, AuthorizationService authService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserRoleQuery ids(UUID value) { @@ -133,6 +137,11 @@ public class UserRoleQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/backend/core/src/main/java/org/opencdmp/query/UserSettingsQuery.java b/backend/core/src/main/java/org/opencdmp/query/UserSettingsQuery.java index e1758be3a..4f7875228 100644 --- a/backend/core/src/main/java/org/opencdmp/query/UserSettingsQuery.java +++ b/backend/core/src/main/java/org/opencdmp/query/UserSettingsQuery.java @@ -4,6 +4,7 @@ import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -11,6 +12,7 @@ import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.authorization.Permission; import org.opencdmp.commons.enums.UserSettingsType; import org.opencdmp.commons.scope.user.UserScope; +import org.opencdmp.data.TenantEntityManager; import org.opencdmp.data.UserSettingsEntity; import org.opencdmp.model.UserSettings; import org.opencdmp.query.utils.QueryUtilsService; @@ -37,13 +39,15 @@ public class UserSettingsQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; private final QueryUtilsService queryUtilsService; + private final TenantEntityManager tenantEntityManager; public UserSettingsQuery( UserScope userScope, - AuthorizationService authService, QueryUtilsService queryUtilsService + AuthorizationService authService, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager ) { this.userScope = userScope; this.authService = authService; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } public UserSettingsQuery like(String like) { @@ -142,6 +146,11 @@ public class UserSettingsQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || this.isEmpty(this.keys) || this.isEmpty(this.types) || this.isEmpty(this.entityIds); diff --git a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java index b97eacc9e..00f0aa0bb 100644 --- a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java @@ -1138,7 +1138,7 @@ public class DescriptionServiceImpl implements DescriptionService { DmpDescriptionTemplateEntity dmpDescriptionTemplateEntity = this.queryFactory.query(DmpDescriptionTemplateQuery.class).disableTracking().ids(data.getDmpDescriptionTemplateId()).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).isActive(IsActive.Active).first(); if (dmpDescriptionTemplateEntity != null) xml.setSectionId(dmpDescriptionTemplateEntity.getSectionId()); - DescriptionTagQuery descriptionTagQuery = new DescriptionTagQuery(); + DescriptionTagQuery descriptionTagQuery = this.queryFactory.query(DescriptionTagQuery.class); descriptionTagQuery.descriptionIds(data.getId()); descriptionTagQuery.isActive(IsActive.Active); diff --git a/backend/core/src/main/java/org/opencdmp/service/lock/LockServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/lock/LockServiceImpl.java index 2d12dc55b..a0eeac010 100644 --- a/backend/core/src/main/java/org/opencdmp/service/lock/LockServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/lock/LockServiceImpl.java @@ -129,7 +129,8 @@ public class LockServiceImpl implements LockService { else { if (new Date().getTime() - Date.from(lock.getTouchedAt()).getTime() > this.lockProperties.getLockInterval()) { lockStatus.setStatus(false); - this.deleteAndSave(lock.getId(), lock.getTarget()); + this.deleterFactory.deleter(LockDeleter.class).deleteAndSaveByIds(List.of(lock.getId())); + //this.deleteAndSave(lock.getId(), lock.getTarget()); } else lockStatus.setStatus(true); } diff --git a/backend/core/src/main/java/org/opencdmp/service/metrics/UpdateMetricsTask.java b/backend/core/src/main/java/org/opencdmp/service/metrics/UpdateMetricsTask.java index 3567b7427..66c48196e 100644 --- a/backend/core/src/main/java/org/opencdmp/service/metrics/UpdateMetricsTask.java +++ b/backend/core/src/main/java/org/opencdmp/service/metrics/UpdateMetricsTask.java @@ -4,6 +4,7 @@ import gr.cite.tools.logging.LoggerService; import io.prometheus.client.Gauge; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.PersistenceUnit; import org.opencdmp.commons.fake.FakeRequestScope; import org.opencdmp.data.TenantEntityManager; import org.slf4j.LoggerFactory; @@ -28,16 +29,17 @@ public class UpdateMetricsTask implements Closeable, ApplicationListener gauges; public UpdateMetricsTask( UpdateMetricsTaskProperties config, - ApplicationContext applicationContext, EntityManagerFactory entityManagerFactory) { + ApplicationContext applicationContext) { this._config = config; this.applicationContext = applicationContext; - this.entityManagerFactory = entityManagerFactory; this.gauges = null; } @@ -71,29 +73,34 @@ public class UpdateMetricsTask implements Closeable, ApplicationListener gr.cite data-tools - 2.1.4 + 2.1.5 gr.cite diff --git a/backend/web/src/main/java/org/opencdmp/interceptors/tenant/TenantScopeHeaderInterceptor.java b/backend/web/src/main/java/org/opencdmp/interceptors/tenant/TenantScopeHeaderInterceptor.java index 772f6b314..d7c14f6c5 100644 --- a/backend/web/src/main/java/org/opencdmp/interceptors/tenant/TenantScopeHeaderInterceptor.java +++ b/backend/web/src/main/java/org/opencdmp/interceptors/tenant/TenantScopeHeaderInterceptor.java @@ -1,21 +1,20 @@ package org.opencdmp.interceptors.tenant; -import org.opencdmp.authorization.ClaimNames; -import org.opencdmp.commons.enums.IsActive; -import org.opencdmp.commons.scope.tenant.TenantScope; -import org.opencdmp.convention.ConventionService; -import org.opencdmp.data.TenantEntity; import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver; import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorContext; import gr.cite.tools.logging.LoggerService; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; -import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Root; import org.jetbrains.annotations.NotNull; +import org.opencdmp.authorization.ClaimNames; +import org.opencdmp.commons.enums.IsActive; +import org.opencdmp.commons.scope.tenant.TenantScope; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.data.TenantEntity; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; diff --git a/notification-service/notification/pom.xml b/notification-service/notification/pom.xml index 978ecf310..388c2108c 100644 --- a/notification-service/notification/pom.xml +++ b/notification-service/notification/pom.xml @@ -53,7 +53,7 @@ gr.cite data-tools - 2.1.4 + 2.1.5 gr.cite diff --git a/notification-service/notification/src/main/java/gr/cite/notification/config/notification/NotificationConfig.java b/notification-service/notification/src/main/java/gr/cite/notification/config/notification/NotificationConfig.java index 38413fef9..c6af9e3bb 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/config/notification/NotificationConfig.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/config/notification/NotificationConfig.java @@ -5,15 +5,12 @@ import gr.cite.notification.schedule.NotificationScheduleTask; import gr.cite.notification.service.message.common.MessageBuilderBase; import gr.cite.notification.service.notificationscheduling.NotificationSchedulingService; import gr.cite.notification.service.notificationscheduling.NotificationSchedulingServiceImpl; -import gr.cite.queueinbox.task.rabbitmq.QueueListenerProperties; -import jakarta.persistence.EntityManagerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.annotation.EnableScheduling; import java.util.ArrayList; import java.util.List; @@ -34,13 +31,11 @@ public class NotificationConfig { } private final ApplicationContext applicationContext; private final NotificationProperties properties; - private final EntityManagerFactory entityManagerFactory; @Autowired - public NotificationConfig(ApplicationContext applicationContext, NotificationProperties properties, EntityManagerFactory entityManagerFactory) { + public NotificationConfig(ApplicationContext applicationContext, NotificationProperties properties) { this.applicationContext = applicationContext; this.properties = properties; - this.entityManagerFactory = entityManagerFactory; } @Bean(BeanQualifier.GLOBAL_POLICIES_MAP) @@ -74,7 +69,7 @@ public class NotificationConfig { @Bean public NotificationSchedulingService notificationSchedulingService() { - return new NotificationSchedulingServiceImpl(this.applicationContext, this.properties, this.entityManagerFactory); + return new NotificationSchedulingServiceImpl(this.applicationContext, this.properties); } @Bean diff --git a/notification-service/notification/src/main/java/gr/cite/notification/data/NotificationEntity.java b/notification-service/notification/src/main/java/gr/cite/notification/data/NotificationEntity.java index 14edc062a..163676aa7 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/data/NotificationEntity.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/data/NotificationEntity.java @@ -96,6 +96,7 @@ public class NotificationEntity extends TenantScopedBaseEntity { public static final String _createdAt = "createdAt"; @Column(name = "\"updated_at\"", nullable = false) + @Version private Instant updatedAt; public static final String _updatedAt = "updatedAt"; diff --git a/notification-service/notification/src/main/java/gr/cite/notification/data/QueueOutboxEntity.java b/notification-service/notification/src/main/java/gr/cite/notification/data/QueueOutboxEntity.java index 232aa169f..ea3470c1c 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/data/QueueOutboxEntity.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/data/QueueOutboxEntity.java @@ -71,6 +71,7 @@ public class QueueOutboxEntity implements QueueOutbox { public static final String _createdAt = "createdAt"; @Column(name = "\"updated_at\"", nullable = false) + @Version private Instant updatedAt; public static final String _updatedAt = "updatedAt"; diff --git a/notification-service/notification/src/main/java/gr/cite/notification/data/TenantEntityManager.java b/notification-service/notification/src/main/java/gr/cite/notification/data/TenantEntityManager.java index f16a8b986..592c331dd 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/data/TenantEntityManager.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/data/TenantEntityManager.java @@ -95,6 +95,7 @@ public class TenantEntityManager { } public void reloadTenantFilters() throws InvalidApplicationException { + if (!this.entityManager.isOpen()) return; this.disableTenantFilters(); if (!this.tenantScope.isSet()) return; @@ -113,6 +114,7 @@ public class TenantEntityManager { } public void loadExplictTenantFilters() throws InvalidApplicationException { + if (!this.entityManager.isOpen()) return; this.disableTenantFilters(); if (!this.tenantScope.isSet()) return; @@ -131,6 +133,7 @@ public class TenantEntityManager { } public void disableTenantFilters() { + if (!this.entityManager.isOpen()) return; this.entityManager .unwrap(Session.class) .disableFilter(TenantScopedBaseEntity.TENANT_FILTER); diff --git a/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/InboxIntegrationEventConfigurer.java b/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/InboxIntegrationEventConfigurer.java index 053d3780d..49a575b3a 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/InboxIntegrationEventConfigurer.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/InboxIntegrationEventConfigurer.java @@ -4,7 +4,6 @@ import gr.cite.notification.integrationevent.inbox.InboxProperties; import gr.cite.notification.integrationevent.inbox.InboxRepositoryImpl; import gr.cite.queueinbox.InboxConfigurer; import gr.cite.queueinbox.repository.InboxRepository; -import jakarta.persistence.EntityManagerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; @@ -19,17 +18,15 @@ public class InboxIntegrationEventConfigurer extends InboxConfigurer { private final ApplicationContext applicationContext; private final InboxProperties inboxProperties; - private final EntityManagerFactory entityManagerFactory; - public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties, EntityManagerFactory entityManagerFactory) { + public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties) { this.applicationContext = applicationContext; this.inboxProperties = inboxProperties; - this.entityManagerFactory = entityManagerFactory; } @Bean public InboxRepository inboxRepositoryCreator() { - return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties, this.entityManagerFactory); + return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties); } } diff --git a/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/OutboxIntegrationEventConfigurer.java b/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/OutboxIntegrationEventConfigurer.java index f3a41cc91..dfcb358b9 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/OutboxIntegrationEventConfigurer.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/OutboxIntegrationEventConfigurer.java @@ -9,7 +9,6 @@ import gr.cite.queueoutbox.repository.OutboxRepository; import gr.cite.rabbitmq.IntegrationEventMessageConstants; import gr.cite.rabbitmq.RabbitProperties; import gr.cite.rabbitmq.broker.MessageHydrator; -import jakarta.persistence.EntityManagerFactory; import org.springframework.amqp.core.MessageProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -27,13 +26,9 @@ import java.util.UUID; @ConditionalOnProperty(prefix = "queue.task.publisher", name = "enable", matchIfMissing = false) public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { private final ApplicationContext applicationContext; - private final OutboxProperties outboxProperties; - private final EntityManagerFactory entityManagerFactory; - public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties, EntityManagerFactory entityManagerFactory) { + public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext) { this.applicationContext = applicationContext; - this.outboxProperties = outboxProperties; - this.entityManagerFactory = entityManagerFactory; } @Bean @@ -69,7 +64,7 @@ public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { @Bean public OutboxRepository outboxRepositoryCreator() { - return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties, this.entityManagerFactory); + return new OutboxRepositoryImpl(this.applicationContext); } } diff --git a/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/inbox/InboxRepositoryImpl.java b/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/inbox/InboxRepositoryImpl.java index 42ea7b9de..6fbaba2f0 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/inbox/InboxRepositoryImpl.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/inbox/InboxRepositoryImpl.java @@ -1,11 +1,9 @@ package gr.cite.notification.integrationevent.inbox; -import gr.cite.notification.common.JsonHandlingService; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.scope.fake.FakeRequestScope; import gr.cite.notification.data.QueueInboxEntity; import gr.cite.notification.data.TenantEntityManager; -import gr.cite.notification.integrationevent.TrackedEvent; import gr.cite.notification.integrationevent.inbox.notify.NotifyIntegrationEventHandler; import gr.cite.notification.integrationevent.inbox.tenantdefaultlocaleremoval.TenantDefaultLocaleRemovalIntegrationEventHandler; import gr.cite.notification.integrationevent.inbox.tenantdefaultlocaletouched.TenantDefaultLocaleTouchedIntegrationEventHandler; @@ -24,10 +22,7 @@ import gr.cite.rabbitmq.consumer.InboxCreatorParams; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.logging.LoggerService; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.*; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -41,29 +36,30 @@ public class InboxRepositoryImpl implements InboxRepository { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(InboxRepositoryImpl.class)); protected final ApplicationContext applicationContext; - private final JsonHandlingService jsonHandlingService; private final InboxProperties inboxProperties; - private final EntityManagerFactory entityManagerFactory; - + + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; + public InboxRepositoryImpl( ApplicationContext applicationContext, - InboxProperties inboxProperties, EntityManagerFactory entityManagerFactory + InboxProperties inboxProperties ) { this.applicationContext = applicationContext; - this.entityManagerFactory = entityManagerFactory; - this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class); this.inboxProperties = inboxProperties; } @Override public CandidateInfo candidate(Instant lastCandidateCreationTimestamp, MessageOptions options) { EntityTransaction transaction = null; - EntityManager entityManager = null; CandidateInfo candidate = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -102,8 +98,7 @@ public class InboxRepositoryImpl implements InboxRepository { transaction.rollback(); candidate = null; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem getting list of queue inbox. Skipping: {}", ex.getMessage(), ex); @@ -115,12 +110,14 @@ public class InboxRepositoryImpl implements InboxRepository { @Override public Boolean shouldOmit(CandidateInfo candidate, Function shouldOmit) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -147,8 +144,7 @@ public class InboxRepositoryImpl implements InboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -159,12 +155,14 @@ public class InboxRepositoryImpl implements InboxRepository { @Override public boolean shouldWait(CandidateInfo candidate, Function itIsTimeFunc) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -192,8 +190,7 @@ public class InboxRepositoryImpl implements InboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -204,14 +201,16 @@ public class InboxRepositoryImpl implements InboxRepository { @Override public QueueInbox create(InboxCreatorParams inboxCreatorParams) { EntityTransaction transaction = null; - EntityManager entityManager = null; - boolean success = false; + boolean success; QueueInboxEntity queueMessage = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + queueMessage = this.createQueueInboxEntity(inboxCreatorParams); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -220,23 +219,22 @@ public class InboxRepositoryImpl implements InboxRepository { entityManager.flush(); transaction.commit(); + success = true; } catch (Exception ex) { - logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); - if (transaction != null) - transaction.rollback(); success = false; + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); } - return queueMessage; + return success ? queueMessage : null; } private QueueInboxEntity createQueueInboxEntity(InboxCreatorParams inboxCreatorParams) { - QueueInboxEntity queueMessage = new QueueInboxEntity(); queueMessage.setId(UUID.randomUUID()); Object tenantId = inboxCreatorParams.getHeaders() != null ? inboxCreatorParams.getHeaders().getOrDefault(IntegrationEventMessageConstants.TENANT, null) : null; @@ -245,6 +243,7 @@ public class InboxRepositoryImpl implements InboxRepository { try { queueMessage.setTenantId(UUID.fromString((String) tenantId)); } catch (Exception e) { + logger.error(e.getMessage(), e); } } queueMessage.setExchange(this.inboxProperties.getExchange()); @@ -264,28 +263,26 @@ public class InboxRepositoryImpl implements InboxRepository { @Override public Boolean emit(CandidateInfo candidateInfo) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; - + QueueInboxEntity queueInboxMessage; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); + queueInboxMessage = queryFactory.query(QueueInboxQuery.class).ids(candidateInfo.getId()).first(); + } + if (queueInboxMessage == null) { + logger.warn("Could not lookup queue inbox {} to process. Continuing...", candidateInfo.getId()); + } else { + EventProcessingStatus status = this.emitQueueInboxEntity(queueInboxMessage); + try (FakeRequestScope ignored = new FakeRequestScope()) { TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); - tenantEntityManager.setEntityManager(entityManager); - - transaction.begin(); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + + transaction = entityManager.getTransaction(); - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - QueueInboxEntity queueInboxMessage = queryFactory.query(QueueInboxQuery.class).ids(candidateInfo.getId()).first(); + transaction.begin(); - if (queueInboxMessage == null) { - logger.warn("Could not lookup queue inbox {} to process. Continuing...", candidateInfo.getId()); - } else { - - EventProcessingStatus status = this.processMessage(queueInboxMessage); switch (status) { case Success: { queueInboxMessage.setStatus(QueueInboxStatus.SUCCESSFUL); @@ -310,22 +307,56 @@ public class InboxRepositoryImpl implements InboxRepository { entityManager.merge(queueInboxMessage); entityManager.flush(); - } - transaction.commit(); + transaction.commit(); + } catch (Exception ex) { + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + if (transaction != null) + transaction.rollback(); + success = false; + } finally { + tenantEntityManager.reloadTenantFilters(); + } + } catch (Exception ex) { + logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); + } + + } + return success; + } + + public EventProcessingStatus emitQueueInboxEntity(QueueInboxEntity queueInboxMessage) { + EntityTransaction transaction = null; + EventProcessingStatus status = EventProcessingStatus.Discard; + try (FakeRequestScope ignored = new FakeRequestScope()) { + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + tenantEntityManager.setEntityManager(entityManager); + + transaction = entityManager.getTransaction(); + + transaction.begin(); + + status = this.processMessage(queueInboxMessage); + + entityManager.flush(); + + switch (status) { + case Error: transaction.rollback(); break; + case Success: + case Postponed: + case Discard: + default: transaction.commit(); break; + } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); if (transaction != null) transaction.rollback(); - success = false; - } finally { - if (entityManager != null) - entityManager.close(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); } - return success; + return status; } private EventProcessingStatus processMessage(QueueInboxEntity queueInboxMessage) { @@ -358,13 +389,13 @@ public class InboxRepositoryImpl implements InboxRepository { properties.setMessageId(queueInboxMessage.getMessageId().toString()); properties.setTenantId(queueInboxMessage.getTenantId()); - TrackedEvent event = this.jsonHandlingService.fromJsonSafe(TrackedEvent.class, queueInboxMessage.getMessage()); +// TrackedEvent event = this.jsonHandlingService.fromJsonSafe(TrackedEvent.class, queueInboxMessage.getMessage()); // using (LogContext.PushProperty(this._logTrackingConfig.LogTrackingContextName, @event.TrackingContextTag)) // { try { return handler.handle(properties, queueInboxMessage.getMessage()); } catch (Exception ex) { - logger.error("problem handling event from routing key " + queueInboxMessage.getRoute() + ". Setting nack and continuing...", ex); + logger.error("problem handling event from routing key {}. Setting nack and continuing...", queueInboxMessage.getRoute(), ex); return EventProcessingStatus.Error; } // } diff --git a/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/outbox/OutboxRepositoryImpl.java b/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/outbox/OutboxRepositoryImpl.java index 51c770647..10848cb41 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/outbox/OutboxRepositoryImpl.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/integrationevent/outbox/OutboxRepositoryImpl.java @@ -1,9 +1,9 @@ package gr.cite.notification.integrationevent.outbox; -import gr.cite.notification.common.JsonHandlingService; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.scope.fake.FakeRequestScope; import gr.cite.notification.data.QueueOutboxEntity; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.query.QueueOutboxQuery; import gr.cite.queueoutbox.entity.QueueOutbox; import gr.cite.queueoutbox.entity.QueueOutboxNotifyStatus; @@ -14,10 +14,7 @@ import gr.cite.rabbitmq.IntegrationEvent; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.logging.LoggerService; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; +import jakarta.persistence.*; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -33,32 +30,30 @@ public class OutboxRepositoryImpl implements OutboxRepository { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(OutboxRepositoryImpl.class)); - private final EntityManagerFactory entityManagerFactory; + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; - private final OutboxProperties outboxProperties; public OutboxRepositoryImpl( - ApplicationContext applicationContext, - OutboxProperties outboxProperties, EntityManagerFactory entityManagerFactory + ApplicationContext applicationContext ) { this.applicationContext = applicationContext; - this.entityManagerFactory = entityManagerFactory; - this.outboxProperties = outboxProperties; } @Override public CandidateInfo candidate(Instant lastCandidateCreationTimestamp, MessageOptions messageOptions, Function onConfirmTimeout) { EntityTransaction transaction = null; - EntityManager entityManager = null; CandidateInfo candidate = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); transaction = entityManager.getTransaction(); transaction.begin(); + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); QueueOutboxEntity item = queryFactory.query(QueueOutboxQuery.class) .isActives(IsActive.Active) .notifyStatus(QueueOutboxNotifyStatus.PENDING, QueueOutboxNotifyStatus.WAITING_CONFIRMATION, QueueOutboxNotifyStatus.ERROR) @@ -96,8 +91,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); candidate = null; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex); @@ -109,12 +103,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean shouldOmit(CandidateInfo candidate, Function shouldOmit) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -141,8 +137,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -153,12 +148,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean shouldWait(CandidateInfo candidate, Function itIsTimeFunc) { EntityTransaction transaction = null; - EntityManager entityManager = null; boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -186,8 +183,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -198,12 +194,14 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public Boolean process(CandidateInfo candidateInfo, Boolean isAutoconfirmOnPublish, Function publish) { EntityTransaction transaction = null; - EntityManager entityManager = null; Boolean success = false; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -240,8 +238,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { transaction.rollback(); success = false; } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -252,11 +249,13 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public void handleConfirm(List confirmedMessages) { EntityTransaction transaction = null; - EntityManager entityManager = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -282,8 +281,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -293,11 +291,13 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public void handleNack(List nackedMessages) { EntityTransaction transaction = null; - EntityManager entityManager = null; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { - entityManager = this.entityManagerFactory.createEntityManager(); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); transaction.begin(); @@ -323,8 +323,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); @@ -334,12 +333,15 @@ public class OutboxRepositoryImpl implements OutboxRepository { @Override public QueueOutbox create(IntegrationEvent item) { EntityTransaction transaction = null; - EntityManager entityManager = null; QueueOutboxEntity queueMessage = null; + boolean success; try (FakeRequestScope ignored = new FakeRequestScope()) { - try { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + queueMessage = this.mapEvent((OutboxIntegrationEvent) item); - entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -348,18 +350,20 @@ public class OutboxRepositoryImpl implements OutboxRepository { entityManager.flush(); transaction.commit(); + success = true; } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); if (transaction != null) transaction.rollback(); } finally { - if (entityManager != null) - entityManager.close(); + tenantEntityManager.reloadTenantFilters(); } } catch (Exception ex) { + success = false; logger.error("Problem executing purge. rolling back any db changes and marking error. Continuing...", ex); } - return queueMessage; + return success ? queueMessage : null; } private QueueOutboxEntity mapEvent(OutboxIntegrationEvent event) { @@ -370,26 +374,5 @@ public class OutboxRepositoryImpl implements OutboxRepository { return null; } } - -// UUID correlationId = UUID.randomUUID(); -// if (event.getEvent() != null) -// event.getEvent().setTrackingContextTag(correlationId.toString()); -// event.setMessage(this.jsonHandlingService.toJsonSafe(event.getEvent())); -// //this._logTrackingService.Trace(correlationId.ToString(), $"Correlating current tracking context with new correlationId {correlationId}"); -// -// QueueOutboxEntity queueMessage = new QueueOutboxEntity(); -// queueMessage.setId(UUID.randomUUID()); -// queueMessage.setTenantId(event.getTenantId()); -// queueMessage.setExchange(this.outboxProperties.getExchange()); -// queueMessage.setRoute(routingKey); -// queueMessage.setMessageId(event.getMessageId()); -// queueMessage.setMessage(this.jsonHandlingService.toJsonSafe(event)); -// queueMessage.setIsActive(IsActive.Active); -// queueMessage.setNotifyStatus(QueueOutboxNotifyStatus.PENDING); -// queueMessage.setRetryCount(0); -// queueMessage.setCreatedAt(Instant.now()); -// queueMessage.setUpdatedAt(Instant.now()); -// -// return queueMessage; } } diff --git a/notification-service/notification/src/main/java/gr/cite/notification/model/deleter/NotificationDeleter.java b/notification-service/notification/src/main/java/gr/cite/notification/model/deleter/NotificationDeleter.java index c5099590a..1a743cc04 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/model/deleter/NotificationDeleter.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/model/deleter/NotificationDeleter.java @@ -68,7 +68,6 @@ public class NotificationDeleter implements Deleter { for (NotificationEntity item : datas) { logger.trace("deleting item {}", item.getId()); item.setIsActive(IsActive.Inactive); - item.setUpdatedAt(now); logger.trace("updating item"); this.entityManager.merge(item); logger.trace("updated item"); diff --git a/notification-service/notification/src/main/java/gr/cite/notification/model/deleter/UserCredentialDeleter.java b/notification-service/notification/src/main/java/gr/cite/notification/model/deleter/UserCredentialDeleter.java index fd9eec69b..a76206d90 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/model/deleter/UserCredentialDeleter.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/model/deleter/UserCredentialDeleter.java @@ -1,6 +1,5 @@ package gr.cite.notification.model.deleter; -import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.data.UserCredentialEntity; import gr.cite.notification.query.UserCredentialQuery; @@ -26,7 +25,7 @@ public class UserCredentialDeleter implements Deleter { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserCredentialDeleter.class)); - private final TenantEntityManager entityManager; + private final TenantEntityManager entityManager; private final QueryFactory queryFactory; @@ -59,8 +58,6 @@ public class UserCredentialDeleter implements Deleter { if (data == null || data.isEmpty()) return; - Instant now = Instant.now(); - for (UserCredentialEntity item : data) { logger.trace("deleting item {}", item.getId()); logger.trace("deleting item"); diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/InAppNotificationQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/InAppNotificationQuery.java index 8f6ae68cd..1548c11cf 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/InAppNotificationQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/InAppNotificationQuery.java @@ -5,10 +5,12 @@ import gr.cite.notification.common.enums.InAppNotificationPriority; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.enums.NotificationInAppTracking; import gr.cite.notification.data.InAppNotificationEntity; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.model.InAppNotification; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.Predicate; import org.springframework.beans.factory.config.BeanDefinition; @@ -46,7 +48,13 @@ public class InAppNotificationQuery extends QueryBase { private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); - public InAppNotificationQuery like(String value) { + private final TenantEntityManager tenantEntityManager; + + public InAppNotificationQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + + public InAppNotificationQuery like(String value) { this.like = value; return this; } @@ -166,6 +174,11 @@ public class InAppNotificationQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isNullOrEmpty(this.ids) diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationQuery.java index 037f28fde..2bf4adfc3 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationQuery.java @@ -3,11 +3,13 @@ package gr.cite.notification.query; import gr.cite.notification.authorization.AuthorizationFlags; import gr.cite.notification.common.enums.*; import gr.cite.notification.data.NotificationEntity; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.model.Notification; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.Predicate; import org.springframework.beans.factory.config.BeanDefinition; @@ -51,7 +53,13 @@ public class NotificationQuery extends QueryBase { private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); - public NotificationQuery ids(UUID value) { + private final TenantEntityManager tenantEntityManager; + + public NotificationQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + + public NotificationQuery ids(UUID value) { this.ids = List.of(value); return this; } @@ -216,6 +224,11 @@ public class NotificationQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isNullOrEmpty(this.ids) diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationTemplateQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationTemplateQuery.java index 02b416f2c..c3eaf35ad 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationTemplateQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationTemplateQuery.java @@ -3,10 +3,12 @@ package gr.cite.notification.query; import gr.cite.notification.authorization.AuthorizationFlags; import gr.cite.notification.common.enums.*; import gr.cite.notification.data.NotificationTemplateEntity; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.model.NotificationTemplate; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -33,6 +35,12 @@ public class NotificationTemplateQuery extends QueryBase kinds; private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + private final TenantEntityManager tenantEntityManager; + + public NotificationTemplateQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + public NotificationTemplateQuery ids(UUID value) { this.ids = List.of(value); return this; @@ -155,6 +163,11 @@ public class NotificationTemplateQuery extends QueryBase { private Collection status; private Integer retryThreshold; + private final TenantEntityManager tenantEntityManager; + + public QueueInboxQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + public QueueInboxQuery ids(UUID value) { this.ids = List.of(value); return this; @@ -130,6 +138,11 @@ public class QueueInboxQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return QueueInboxEntity.class; diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/QueueOutboxQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/QueueOutboxQuery.java index 5b98fbd13..a6fa0f7f0 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/QueueOutboxQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/QueueOutboxQuery.java @@ -3,11 +3,13 @@ package gr.cite.notification.query; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.data.QueueOutboxEntity; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.queueoutbox.entity.QueueOutboxNotifyStatus; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -31,6 +33,12 @@ public class QueueOutboxQuery extends QueryBase { private Integer retryThreshold; private Integer confirmTimeout; + private final TenantEntityManager tenantEntityManager; + + public QueueOutboxQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + public QueueOutboxQuery ids(UUID value) { this.ids = List.of(value); return this; @@ -136,6 +144,11 @@ public class QueueOutboxQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return QueueOutboxEntity.class; diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/TenantConfigurationQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/TenantConfigurationQuery.java index 2fb21fed7..31ac28b50 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/TenantConfigurationQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/TenantConfigurationQuery.java @@ -4,10 +4,12 @@ import gr.cite.notification.authorization.AuthorizationFlags; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.enums.TenantConfigurationType; import gr.cite.notification.data.TenantConfigurationEntity; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.model.tenantconfiguration.TenantConfiguration; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -30,11 +32,13 @@ public class TenantConfigurationQuery extends QueryBase excludedIds; private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + private final TenantEntityManager tenantEntityManager; - public TenantConfigurationQuery() { - } + public TenantConfigurationQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } - public TenantConfigurationQuery ids(UUID value) { + public TenantConfigurationQuery ids(UUID value) { this.ids = List.of(value); return this; } @@ -129,6 +133,11 @@ public class TenantConfigurationQuery extends QueryBase { private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); - public TenantQuery like(String value) { + private final TenantEntityManager tenantEntityManager; + + public TenantQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + + public TenantQuery like(String value) { this.like = value; return this; } @@ -78,6 +86,11 @@ public class TenantQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || this.isEmpty(this.isActives); diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/TenantUserQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/TenantUserQuery.java index 0ff7c1d0d..8439c7886 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/TenantUserQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/TenantUserQuery.java @@ -4,6 +4,7 @@ import gr.cite.notification.authorization.AuthorizationFlags; import gr.cite.notification.authorization.Permission; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.scope.user.UserScope; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.data.UserEntity; import gr.cite.notification.model.Tenant; import gr.cite.notification.model.TenantUser; @@ -12,6 +13,7 @@ import gr.cite.notification.data.TenantUserEntity; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -36,12 +38,15 @@ public class TenantUserQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; + private final TenantEntityManager tenantEntityManager; + public TenantUserQuery( UserScope userScope, - AuthorizationService authService + AuthorizationService authService, TenantEntityManager tenantEntityManager ) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public TenantUserQuery ids(UUID value) { @@ -124,6 +129,11 @@ public class TenantUserQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Class entityClass() { return TenantUserEntity.class; diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/UserContactInfoQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/UserContactInfoQuery.java index 920dd5fb8..7ff5211a9 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/UserContactInfoQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/UserContactInfoQuery.java @@ -6,6 +6,7 @@ import gr.cite.notification.authorization.Permission; import gr.cite.notification.common.enums.ContactInfoType; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.scope.user.UserScope; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.data.UserContactInfoEntity; import gr.cite.notification.data.UserEntity; import gr.cite.notification.model.User; @@ -13,6 +14,7 @@ import gr.cite.notification.model.UserContactInfo; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -46,12 +48,15 @@ public class UserContactInfoQuery extends QueryBase { private final AuthorizationService authService; + private final TenantEntityManager tenantEntityManager; + public UserContactInfoQuery( - UserScope userScope, - AuthorizationService authService + UserScope userScope, + AuthorizationService authService, TenantEntityManager tenantEntityManager ) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserContactInfoQuery ids(UUID value) { @@ -164,6 +169,11 @@ public class UserContactInfoQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.userIds) || this.isEmpty(this.excludedUserIds) || this.isEmpty(this.isActives) diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/UserCredentialQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/UserCredentialQuery.java index d4f800873..2dec5a40c 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/UserCredentialQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/UserCredentialQuery.java @@ -5,11 +5,13 @@ import gr.cite.notification.authorization.AuthorizationFlags; import gr.cite.notification.authorization.Permission; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.scope.user.UserScope; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.data.UserCredentialEntity; import gr.cite.notification.model.UserCredential; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -38,9 +40,12 @@ public class UserCredentialQuery extends QueryBase { private final AuthorizationService authService; - public UserCredentialQuery(UserScope userScope, AuthorizationService authService) { + private final TenantEntityManager tenantEntityManager; + + public UserCredentialQuery(UserScope userScope, AuthorizationService authService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserCredentialQuery ids(UUID value) { @@ -118,6 +123,11 @@ public class UserCredentialQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/UserNotificationPreferenceQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/UserNotificationPreferenceQuery.java index 3a31e03b0..9b4034842 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/UserNotificationPreferenceQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/UserNotificationPreferenceQuery.java @@ -3,12 +3,14 @@ package gr.cite.notification.query; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.enums.NotificationContactType; import gr.cite.notification.data.TenantConfigurationEntity; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.data.UserCredentialEntity; import gr.cite.notification.data.UserNotificationPreferenceEntity; import gr.cite.notification.model.UserNotificationPreference; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -37,7 +39,14 @@ public class UserNotificationPreferenceQuery extends QueryBase tenantIds; private Boolean tenantIsSet; - public UserNotificationPreferenceQuery ids(UUID value) { + + private final TenantEntityManager tenantEntityManager; + + public UserNotificationPreferenceQuery(TenantEntityManager tenantEntityManager) { + this.tenantEntityManager = tenantEntityManager; + } + + public UserNotificationPreferenceQuery ids(UUID value) { this.ids = List.of(value); return this; } @@ -137,6 +146,11 @@ public class UserNotificationPreferenceQuery extends QueryBase { private final UserScope userScope; private final AuthorizationService authService; + private final TenantEntityManager tenantEntityManager; + public UserQuery( UserScope userScope, - AuthorizationService authService + AuthorizationService authService, TenantEntityManager tenantEntityManager ) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserQuery like(String value) { @@ -91,6 +96,11 @@ public class UserQuery extends QueryBase { this.noTracking = false; return this; } + + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } @Override protected Class entityClass() { return UserEntity.class; diff --git a/notification-service/notification/src/main/java/gr/cite/notification/query/UserRoleQuery.java b/notification-service/notification/src/main/java/gr/cite/notification/query/UserRoleQuery.java index bbfa8685d..73cafd744 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/query/UserRoleQuery.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/query/UserRoleQuery.java @@ -5,11 +5,13 @@ import gr.cite.notification.authorization.AuthorizationFlags; import gr.cite.notification.authorization.Permission; import gr.cite.notification.common.enums.IsActive; import gr.cite.notification.common.scope.user.UserScope; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.data.UserRoleEntity; import gr.cite.notification.model.UserRole; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.EntityManager; import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Predicate; @@ -40,9 +42,12 @@ public class UserRoleQuery extends QueryBase { private final AuthorizationService authService; - public UserRoleQuery(UserScope userScope, AuthorizationService authService) { + private final TenantEntityManager tenantEntityManager; + + public UserRoleQuery(UserScope userScope, AuthorizationService authService, TenantEntityManager tenantEntityManager) { this.userScope = userScope; this.authService = authService; + this.tenantEntityManager = tenantEntityManager; } public UserRoleQuery ids(UUID value) { @@ -135,6 +140,11 @@ public class UserRoleQuery extends QueryBase { return this; } + @Override + protected EntityManager entityManager(){ + return this.tenantEntityManager.getEntityManager(); + } + @Override protected Boolean isFalseQuery() { return diff --git a/notification-service/notification/src/main/java/gr/cite/notification/service/notificationscheduling/NotificationSchedulingServiceImpl.java b/notification-service/notification/src/main/java/gr/cite/notification/service/notificationscheduling/NotificationSchedulingServiceImpl.java index 86501d2e5..cf69bb785 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/service/notificationscheduling/NotificationSchedulingServiceImpl.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/service/notificationscheduling/NotificationSchedulingServiceImpl.java @@ -14,206 +14,167 @@ import gr.cite.notification.model.SendNotificationResult; import gr.cite.notification.query.NotificationQuery; import gr.cite.notification.query.TenantQuery; import gr.cite.notification.schedule.model.CandidateInfo; -import gr.cite.notification.schedule.model.MiniTenant; import gr.cite.notification.service.notification.NotificationService; import gr.cite.notification.service.track.TrackingFactory; import gr.cite.notification.service.track.model.TrackerResponse; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; -import gr.cite.tools.fieldset.BaseFieldSet; -import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; +import jakarta.persistence.*; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; import java.time.Instant; -import java.util.List; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.Collectors; public class NotificationSchedulingServiceImpl implements NotificationSchedulingService { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(NotificationSchedulingServiceImpl.class)); private final ApplicationContext applicationContext; private final NotificationProperties properties; - private final EntityManagerFactory entityManagerFactory; + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; - public NotificationSchedulingServiceImpl(ApplicationContext applicationContext, NotificationProperties properties, EntityManagerFactory entityManagerFactory) { + public NotificationSchedulingServiceImpl(ApplicationContext applicationContext, NotificationProperties properties) { this.applicationContext = applicationContext; this.properties = properties; - this.entityManagerFactory = entityManagerFactory; } @Override public CandidateInfo candidateToNotify(Instant lastCandidateNotificationCreationTimestamp) { - EntityManager entityManager = null; EntityTransaction transaction = null; CandidateInfo candidateInfo = null; try (FakeRequestScope fakeRequestScope = new FakeRequestScope()) { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - transaction.begin(); - NotificationQuery notificationQuery = queryFactory.query(NotificationQuery.class); - NotificationEntity candidates; - - notificationQuery = notificationQuery - .isActive(IsActive.Active) - .notifyState(NotificationNotifyState.PENDING, NotificationNotifyState.ERROR) - .retryThreshold(Math.toIntExact(this.properties.getTask().getProcessor().getOptions().getRetryThreshold())) - .createdAfter(lastCandidateNotificationCreationTimestamp) - .ordering(new Ordering().addAscending(NotificationEntity._createdAt)); - candidates = notificationQuery.first(); - if (candidates != null) { - NotificationNotifyState previousState = candidates.getNotifyState(); - candidates.setNotifyState(NotificationNotifyState.PROCESSING); - //candidates.setUpdatedAt(Instant.now()); - TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); - TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - try { - if (candidates.getTenantId() != null) { - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(candidates.getTenantId()).first(); - tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); - } else { - tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); - } + transaction = entityManager.getTransaction(); + transaction.begin(); + + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); + NotificationQuery notificationQuery = queryFactory.query(NotificationQuery.class); + NotificationEntity candidates; + + notificationQuery = notificationQuery + .isActive(IsActive.Active) + .notifyState(NotificationNotifyState.PENDING, NotificationNotifyState.ERROR) + .retryThreshold(Math.toIntExact(this.properties.getTask().getProcessor().getOptions().getRetryThreshold())) + .createdAfter(lastCandidateNotificationCreationTimestamp) + .ordering(new Ordering().addAscending(NotificationEntity._createdAt)); + candidates = notificationQuery.first(); + if (candidates != null) { + NotificationNotifyState previousState = candidates.getNotifyState(); + candidates.setNotifyState(NotificationNotifyState.PROCESSING); + //candidates.setUpdatedAt(Instant.now()); candidates = entityManager.merge(candidates); entityManager.persist(candidates); entityManager.flush(); - } finally { - tenantScope.removeTempTenant(tenantEntityManager); - } - candidateInfo = new CandidateInfo(candidates.getId(), previousState, candidates.getCreatedAt()); + candidateInfo = new CandidateInfo(candidates.getId(), previousState, candidates.getCreatedAt()); + } + transaction.commit(); + } finally { + tenantEntityManager.reloadTenantFilters(); } - transaction.commit(); } catch (OptimisticLockException e) { logger.error("Optimistic Lock Error occurred on Notification persist"); if (transaction != null) transaction.rollback(); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); if (transaction != null) transaction.rollback(); - } finally { - if (entityManager != null) entityManager.close(); } return candidateInfo; } @Override public Boolean shouldWait(CandidateInfo candidateInfo) { - EntityManager entityManager = null; EntityTransaction transaction = null; - Boolean shouldWait = false; + boolean shouldWait = false; try (FakeRequestScope fakeRequestScope = new FakeRequestScope()) { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - transaction.begin(); - NotificationEntity notification = entityManager.find(NotificationEntity.class, candidateInfo.getNotificationId()); - if (notification.getRetryCount() != null && notification.getRetryCount() >= 1) { - int accumulatedRetry = 0; - int pastAccumulateRetry = 0; - NotificationProperties.Task.Processor.Options options = properties.getTask().getProcessor().getOptions(); - for (int i = 1; i <= notification.getRetryCount() + 1; i += 1) - accumulatedRetry += (i * options.getRetryThreshold()); - for (int i = 1; i <= notification.getRetryCount(); i += 1) - pastAccumulateRetry += (i * options.getRetryThreshold()); - int randAccumulatedRetry = ThreadLocalRandom.current().nextInt(accumulatedRetry / 2, accumulatedRetry + 1); - long additionalTime = randAccumulatedRetry > options.getMaxRetryDelaySeconds() ? options.getMaxRetryDelaySeconds() : randAccumulatedRetry; - long retry = pastAccumulateRetry + additionalTime; + transaction = entityManager.getTransaction(); + transaction.begin(); + NotificationEntity notification = entityManager.find(NotificationEntity.class, candidateInfo.getNotificationId()); + if (notification.getRetryCount() != null && notification.getRetryCount() >= 1) { + int accumulatedRetry = 0; + int pastAccumulateRetry = 0; + NotificationProperties.Task.Processor.Options options = properties.getTask().getProcessor().getOptions(); + for (int i = 1; i <= notification.getRetryCount() + 1; i += 1) + accumulatedRetry += (int) (i * options.getRetryThreshold()); + for (int i = 1; i <= notification.getRetryCount(); i += 1) + pastAccumulateRetry += (int) (i * options.getRetryThreshold()); + int randAccumulatedRetry = ThreadLocalRandom.current().nextInt(accumulatedRetry / 2, accumulatedRetry + 1); + long additionalTime = randAccumulatedRetry > options.getMaxRetryDelaySeconds() ? options.getMaxRetryDelaySeconds() : randAccumulatedRetry; + long retry = pastAccumulateRetry + additionalTime; - Instant retryOn = notification.getCreatedAt().plusSeconds(retry); - boolean itIsTime = retryOn.isBefore(Instant.now()); + Instant retryOn = notification.getCreatedAt().plusSeconds(retry); + boolean itIsTime = retryOn.isBefore(Instant.now()); + + if (!itIsTime) { + notification.setNotifyState(candidateInfo.getPreviousState()); + //notification.setUpdatedAt(Instant.now()); - if (!itIsTime) { - notification.setNotifyState(candidateInfo.getPreviousState()); - //notification.setUpdatedAt(Instant.now()); - TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); - TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); - tenantEntityManager.setEntityManager(entityManager); - try { - if (notification.getTenantId() != null) { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(notification.getTenantId()).first(); - tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); - } else { - tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); - } -// notification = entityManager.merge(notification); entityManager.merge(notification); entityManager.flush(); - } finally { - tenantScope.removeTempTenant(tenantEntityManager); } - + shouldWait = !itIsTime; } - shouldWait = !itIsTime; + transaction.commit(); + } finally { + tenantEntityManager.reloadTenantFilters(); } - transaction.commit(); } catch (OptimisticLockException e) { logger.error("Optimistic Lock Error occurred on Notification persist"); if (transaction != null) transaction.rollback(); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); if (transaction != null) transaction.rollback(); - } finally { - if (entityManager != null) entityManager.close(); } return shouldWait; } @Override public Boolean shouldOmitNotify(UUID notificationId) { - EntityManager entityManager = null; EntityTransaction transaction = null; - Boolean shouldOmit = false; + boolean shouldOmit = false; try (FakeRequestScope fakeRequestScope = new FakeRequestScope()) { - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - transaction.begin(); - - NotificationEntity notification = entityManager.find(NotificationEntity.class, notificationId); - long age = Instant.now().getEpochSecond() - notification.getCreatedAt().getEpochSecond(); - long omitSeconds = properties.getTask().getProcessor().getOptions().getTooOldToSendSeconds(); - if (age >= omitSeconds) { - notification.setNotifyState(NotificationNotifyState.OMITTED); - //notification.setUpdatedAt(Instant.now()); - TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); - TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { tenantEntityManager.setEntityManager(entityManager); - try { - if (notification.getTenantId() != null) { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(notification.getTenantId()).first(); - tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); - } else { - tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); - } + tenantEntityManager.disableTenantFilters(); + transaction = entityManager.getTransaction(); + transaction.begin(); + + NotificationEntity notification = entityManager.find(NotificationEntity.class, notificationId); + long age = Instant.now().getEpochSecond() - notification.getCreatedAt().getEpochSecond(); + long omitSeconds = properties.getTask().getProcessor().getOptions().getTooOldToSendSeconds(); + if (age >= omitSeconds) { + notification.setNotifyState(NotificationNotifyState.OMITTED); + //notification.setUpdatedAt(Instant.now()); + notification = entityManager.merge(notification); entityManager.persist(notification); entityManager.flush(); - } finally { - tenantScope.removeTempTenant(tenantEntityManager); + + shouldOmit = true; } - shouldOmit = true; + transaction.commit(); + } finally { + tenantEntityManager.reloadTenantFilters(); } - transaction.commit(); } catch (OptimisticLockException e) { logger.error("Optimistic Lock Error occurred on Notification persist"); if (transaction != null) transaction.rollback(); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); if (transaction != null) transaction.rollback(); - } finally { - if (entityManager != null) entityManager.close(); } return shouldOmit; @@ -221,177 +182,163 @@ public class NotificationSchedulingServiceImpl implements NotificationScheduling @Override public Boolean notify(UUID notificationId) { - EntityManager entityManager = null; - EntityTransaction transaction = null; - Boolean success = null; + boolean success; + NotificationEntity notification; + try (FakeRequestScope fakeRequestScope = new FakeRequestScope()) { - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - transaction.begin(); + EntityTransaction transaction = null; + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); - NotificationQuery notificationQuery = applicationContext.getBean(NotificationQuery.class); - NotificationEntity notification = notificationQuery.ids(notificationId).first(); - if (notification == null) throw new IllegalArgumentException("notification is null"); + transaction = entityManager.getTransaction(); + transaction.begin(); - TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); - TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); - tenantEntityManager.setEntityManager(entityManager); + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); + notification = queryFactory.query(NotificationQuery.class).ids(notificationId).first(); + if (notification == null) throw new IllegalArgumentException("notification is null"); + + TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); + + SendNotificationResult result; + try { + if (notification.getTenantId() != null) { + TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(notification.getTenantId()).first(); + tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); + } else { + tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); + } + tenantEntityManager.reloadTenantFilters(); + + NotificationService notificationService = this.applicationContext.getBean(NotificationService.class); + result = notificationService.doNotify(notification); - SendNotificationResult result = null; - NotificationService notificationService = this.applicationContext.getBean(NotificationService.class); - try { - if (notification.getTenantId() != null) { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(notification.getTenantId()).first(); - tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); - } else { - tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); + if (result != null && result.getSuccess()) { + notification.setNotifyState(NotificationNotifyState.SUCCESSFUL); + notification.setTrackingData(result.getTrackingData()); + notification.setNotifiedWith(result.getContactType()); + notification.setNotifiedAt(Instant.now()); + } else { + notification.setNotifyState(NotificationNotifyState.ERROR); + notification.setRetryCount(notification.getRetryCount() != null ? notification.getRetryCount() + 1 : 0); + notification.setNotifiedWith(null); + notification.setNotifiedAt(null); + } + //notification.setUpdatedAt(Instant.now()); + + NotificationEntity notification1 = entityManager.merge(notification); + entityManager.persist(notification1); + entityManager.flush(); + } finally { + tenantScope.removeTempTenant(tenantEntityManager); + tenantEntityManager.reloadTenantFilters(); } - result = notificationService.doNotify(notification); - - if (result != null && result.getSuccess()) { - notification.setNotifyState(NotificationNotifyState.SUCCESSFUL); - notification.setTrackingData(result.getTrackingData()); - notification.setNotifiedWith(result.getContactType()); - notification.setNotifiedAt(Instant.now()); - } else { - notification.setNotifyState(NotificationNotifyState.ERROR); - notification.setRetryCount(notification.getRetryCount() != null ? notification.getRetryCount() + 1 : 0); - notification.setNotifiedWith(null); - notification.setNotifiedAt(null); - } - //notification.setUpdatedAt(Instant.now()); - - NotificationEntity notification1 = entityManager.merge(notification); - entityManager.persist(notification1); - entityManager.flush(); - } finally { - tenantScope.removeTempTenant(tenantEntityManager); - } - - - - - //we want to return false for notification we want to add in the skip bag - success = result != null && result.getSuccess(); - transaction.commit(); - } catch (OptimisticLockException e) { - logger.error("Optimistic Lock Error occurred on Notification persist"); - if (transaction != null) transaction.rollback(); - } catch (Exception e) { - logger.error(e.getLocalizedMessage(), e); - if (transaction != null) transaction.rollback(); - } finally { - if (entityManager != null) entityManager.close(); + //we want to return false for notification we want to add in the skip bag + success = result != null && result.getSuccess(); + transaction.commit(); + } catch (OptimisticLockException e) { + logger.error("Optimistic Lock Error occurred on Notification persist"); + if (transaction != null) transaction.rollback(); + success = false; + } catch (Exception e) { + logger.error(e.getLocalizedMessage(), e); + if (transaction != null) transaction.rollback(); + success = false; + } } return success; } @Override public CandidateInfo candidateToTrack(Instant lastCandidateNotificationCreationTimestamp) { - EntityManager entityManager = null; EntityTransaction transaction = null; CandidateInfo candidateInfo = null; try (FakeRequestScope fakeRequestScope = new FakeRequestScope()) { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - transaction.begin(); - NotificationQuery notificationQuery = queryFactory.query(NotificationQuery.class); - NotificationEntity candidates; - - notificationQuery = notificationQuery - .isActive(IsActive.Active) - .notifyState(NotificationNotifyState.SUCCESSFUL) - .notifiedWithHasValue() - .notifiedWithHasValue() - .createdAfter(lastCandidateNotificationCreationTimestamp) - .trackingState(NotificationTrackingState.QUEUED, NotificationTrackingState.SENT, NotificationTrackingState.UNDEFINED) - .trackingProgress(NotificationTrackingProcess.PENDING); - candidates = notificationQuery.first(); - if (candidates != null) { - NotificationNotifyState previousState = candidates.getNotifyState(); - candidates.setTrackingProcess(NotificationTrackingProcess.PROCESSING); - //candidates.setUpdatedAt(Instant.now()); - TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); - TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { tenantEntityManager.setEntityManager(entityManager); - try { - if (candidates.getTenantId() != null) { - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(candidates.getTenantId()).first(); - tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); - } else { - tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); - } + tenantEntityManager.disableTenantFilters(); + + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); + + transaction = entityManager.getTransaction(); + transaction.begin(); + NotificationQuery notificationQuery = queryFactory.query(NotificationQuery.class); + NotificationEntity candidates; + + notificationQuery = notificationQuery + .isActive(IsActive.Active) + .notifyState(NotificationNotifyState.SUCCESSFUL) + .notifiedWithHasValue() + .notifiedWithHasValue() + .createdAfter(lastCandidateNotificationCreationTimestamp) + .trackingState(NotificationTrackingState.QUEUED, NotificationTrackingState.SENT, NotificationTrackingState.UNDEFINED) + .trackingProgress(NotificationTrackingProcess.PENDING); + candidates = notificationQuery.first(); + if (candidates != null) { + NotificationNotifyState previousState = candidates.getNotifyState(); + candidates.setTrackingProcess(NotificationTrackingProcess.PROCESSING); + //candidates.setUpdatedAt(Instant.now()); + candidates = entityManager.merge(candidates); entityManager.persist(candidates); entityManager.flush(); - } finally { - tenantScope.removeTempTenant(tenantEntityManager); + + candidateInfo = new CandidateInfo(candidates.getId(), previousState, candidates.getCreatedAt()); } - candidateInfo = new CandidateInfo(candidates.getId(), previousState, candidates.getCreatedAt()); + transaction.commit(); + } finally { + tenantEntityManager.reloadTenantFilters(); } - transaction.commit(); } catch (OptimisticLockException e) { logger.error("Optimistic Lock Error occurred on Notification persist"); if (transaction != null) transaction.rollback(); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); if (transaction != null) transaction.rollback(); - } finally { - if (entityManager != null) entityManager.close(); } return candidateInfo; } @Override public Boolean shouldOmitTracking(UUID notificationId) { - EntityManager entityManager = null; EntityTransaction transaction = null; - Boolean shouldOmit = false; + boolean shouldOmit = false; try (FakeRequestScope fakeRequestScope = new FakeRequestScope()) { - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - transaction.begin(); - - NotificationEntity notification = entityManager.find(NotificationEntity.class, notificationId); - long age = Instant.now().getEpochSecond() - notification.getNotifiedAt().getEpochSecond(); - long omitSeconds = properties.getTask().getProcessor().getOptions().getTooOldToTrackSeconds(); - if (age >= omitSeconds) { - notification.setTrackingProcess(NotificationTrackingProcess.OMITTED); - //notification.setUpdatedAt(Instant.now()); - TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); - TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { tenantEntityManager.setEntityManager(entityManager); - try { - if (notification.getTenantId() != null) { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(notification.getTenantId()).first(); - tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); - } else { - tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); - } + tenantEntityManager.disableTenantFilters(); + + transaction = entityManager.getTransaction(); + transaction.begin(); + + NotificationEntity notification = entityManager.find(NotificationEntity.class, notificationId); + long age = Instant.now().getEpochSecond() - notification.getNotifiedAt().getEpochSecond(); + long omitSeconds = properties.getTask().getProcessor().getOptions().getTooOldToTrackSeconds(); + if (age >= omitSeconds) { + notification.setTrackingProcess(NotificationTrackingProcess.OMITTED); + //notification.setUpdatedAt(Instant.now()); notification = entityManager.merge(notification); entityManager.persist(notification); entityManager.flush(); - } finally { - tenantScope.removeTempTenant(tenantEntityManager); + + shouldOmit = true; } - shouldOmit = true; + transaction.commit(); + } finally { + tenantEntityManager.reloadTenantFilters(); } - transaction.commit(); } catch (OptimisticLockException e) { logger.error("Optimistic Lock Error occurred on Notification persist"); if (transaction != null) transaction.rollback(); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); if (transaction != null) transaction.rollback(); - } finally { - if (entityManager != null) entityManager.close(); } return shouldOmit; @@ -399,75 +346,73 @@ public class NotificationSchedulingServiceImpl implements NotificationScheduling @Override public Boolean track(UUID notificationId) { - EntityManager entityManager = null; EntityTransaction transaction = null; Boolean success = null; try (FakeRequestScope fakeRequestScope = new FakeRequestScope()) { - QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - transaction.begin(); - - NotificationQuery notificationQuery = queryFactory.query(NotificationQuery.class); - NotificationEntity notification = notificationQuery.ids(notificationId).first(); - if (notification == null) throw new IllegalArgumentException("notification is null"); - if (notification.getNotifiedWith() == null) throw new IllegalArgumentException("Notification's Notified With is null"); - if (notification.getNotifiedAt() == null) throw new IllegalArgumentException("Notification's Notified At is null"); - - TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); - tenantEntityManager.setEntityManager(entityManager); - - TrackerResponse result = null; - try { - if (notification.getTenantId() != null) { - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(notification.getTenantId()).first(); - tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); - } else { - tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); - } + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + + transaction = entityManager.getTransaction(); + transaction.begin(); + + QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); + NotificationQuery notificationQuery = queryFactory.query(NotificationQuery.class); + NotificationEntity notification = notificationQuery.ids(notificationId).first(); + if (notification == null) throw new IllegalArgumentException("notification is null"); + if (notification.getNotifiedWith() == null) throw new IllegalArgumentException("Notification's Notified With is null"); + if (notification.getNotifiedAt() == null) throw new IllegalArgumentException("Notification's Notified At is null"); + + TenantScope tenantScope = this.applicationContext.getBean(TenantScope.class); + TrackerResponse result = null; try { - TrackingFactory trackingFactory = applicationContext.getBean(TrackingFactory.class); - result = trackingFactory.fromContactType(notification.getNotifiedWith()).track(notification); - } catch (Exception e) { - logger.error("Could not complete track for notification " + notification.getId(), e); - } + if (notification.getTenantId() != null) { + TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(notification.getTenantId()).first(); + tenantScope.setTempTenant(tenantEntityManager, tenant.getId(), tenant.getCode()); + } else { + tenantScope.setTempTenant(tenantEntityManager, null, tenantScope.getDefaultTenantCode()); + } + tenantEntityManager.reloadTenantFilters(); + + try { + TrackingFactory trackingFactory = applicationContext.getBean(TrackingFactory.class); + result = trackingFactory.fromContactType(notification.getNotifiedWith()).track(notification); + } catch (Exception e) { + logger.error("Could not complete track for notification {}", notification.getId(), e); + } - if (result != null && notification.getTrackingProcess().equals(result.getTrackingProgress()) && notification.getTrackingState().equals(result.getTrackingState())) { - return false; - } + if (result != null && notification.getTrackingProcess().equals(result.getTrackingProgress()) && notification.getTrackingState().equals(result.getTrackingState())) { + return false; + } - if (result != null) { - notification.setTrackingState(result.getTrackingState()); - notification.setTrackingProcess(result.getTrackingProgress()); - notification.setTrackingData(result.getTrackingData()); - } else { - notification.setTrackingProcess(NotificationTrackingProcess.ERROR); - } - //notification.setUpdatedAt(Instant.now()); + if (result != null) { + notification.setTrackingState(result.getTrackingState()); + notification.setTrackingProcess(result.getTrackingProgress()); + notification.setTrackingData(result.getTrackingData()); + } else { + notification.setTrackingProcess(NotificationTrackingProcess.ERROR); + } + //notification.setUpdatedAt(Instant.now()); - NotificationEntity notification1 = entityManager.merge(notification); - entityManager.persist(notification1); - entityManager.flush(); - } finally { - tenantScope.removeTempTenant(tenantEntityManager); + NotificationEntity notification1 = entityManager.merge(notification); + entityManager.persist(notification1); + entityManager.flush(); + + //we want to return false for notification we want to add in the skip bag + success = result != null && !notification.getTrackingProcess().equals(NotificationTrackingProcess.ERROR); + transaction.commit(); + } finally { + tenantScope.removeTempTenant(tenantEntityManager); + tenantEntityManager.reloadTenantFilters(); + } } - - - - - //we want to return false for notification we want to add in the skip bag - success = result != null && !notification.getTrackingProcess().equals(NotificationTrackingProcess.ERROR); - transaction.commit(); } catch (OptimisticLockException e) { logger.error("Optimistic Lock Error occurred on Notification persist"); if (transaction != null) transaction.rollback(); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); if (transaction != null) transaction.rollback(); - } finally { - if (entityManager != null) entityManager.close(); } return success; } diff --git a/notification-service/notification/src/main/java/gr/cite/notification/service/notify/InAppNotifier.java b/notification-service/notification/src/main/java/gr/cite/notification/service/notify/InAppNotifier.java index 313c7f12b..3759c1a99 100644 --- a/notification-service/notification/src/main/java/gr/cite/notification/service/notify/InAppNotifier.java +++ b/notification-service/notification/src/main/java/gr/cite/notification/service/notify/InAppNotifier.java @@ -7,11 +7,13 @@ import gr.cite.notification.common.enums.NotificationInAppTracking; import gr.cite.notification.common.scope.tenant.TenantScope; import gr.cite.notification.common.types.notification.InAppTrackingData; import gr.cite.notification.data.InAppNotificationEntity; +import gr.cite.notification.data.TenantEntityManager; import gr.cite.notification.service.contact.model.Contact; import gr.cite.notification.service.contact.model.InAppContact; import gr.cite.notification.service.message.model.InAppMessage; import gr.cite.notification.service.message.model.Message; import gr.cite.tools.logging.LoggerService; +import jakarta.persistence.PersistenceUnit; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; @@ -20,6 +22,8 @@ import org.springframework.stereotype.Component; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; + +import javax.management.InvalidApplicationException; import java.time.Instant; import java.util.UUID; @@ -28,59 +32,65 @@ public class InAppNotifier implements Notify{ private final static LoggerService logger = new LoggerService(LoggerFactory.getLogger(InAppNotifier.class)); private final JsonHandlingService jsonHandlingService; - private final ApplicationContext applicationContext; - private final EntityManagerFactory entityManagerFactory; + private final ApplicationContext applicationContext; + @PersistenceUnit + private EntityManagerFactory entityManagerFactory; @Autowired - public InAppNotifier(JsonHandlingService jsonHandlingService, ApplicationContext applicationContext, EntityManagerFactory entityManagerFactory) { + public InAppNotifier(JsonHandlingService jsonHandlingService, ApplicationContext applicationContext) { this.jsonHandlingService = jsonHandlingService; this.applicationContext = applicationContext; - this.entityManagerFactory = entityManagerFactory; } @Override public String notify(Contact contact, Message message) { String data = null; - EntityManager entityManager = null; - EntityTransaction transaction = null; - try { - entityManager = this.entityManagerFactory.createEntityManager(); - transaction = entityManager.getTransaction(); - transaction.begin(); - InAppContact inAppContact = (InAppContact) contact; - if (inAppContact == null) throw new IllegalArgumentException("contact not provided"); + EntityTransaction transaction = null; + TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); + try (EntityManager entityManager = this.entityManagerFactory.createEntityManager()) { + tenantEntityManager.setEntityManager(entityManager); + tenantEntityManager.disableTenantFilters(); + + transaction = entityManager.getTransaction(); + transaction.begin(); + InAppContact inAppContact = (InAppContact) contact; + if (inAppContact == null) throw new IllegalArgumentException("contact not provided"); - InAppMessage inAppMessage = (InAppMessage) message; - if (inAppMessage == null) throw new IllegalArgumentException("message not provided"); + InAppMessage inAppMessage = (InAppMessage) message; + if (inAppMessage == null) throw new IllegalArgumentException("message not provided"); - TenantScope tenantScope = applicationContext.getBean(TenantScope.class); - InAppNotificationEntity inApp = new InAppNotificationEntity(); + TenantScope tenantScope = applicationContext.getBean(TenantScope.class); + InAppNotificationEntity inApp = new InAppNotificationEntity(); - inApp.setId(UUID.randomUUID()); - inApp.setUserId(inAppContact.getUserId()); - inApp.setIsActive(IsActive.Active); - inApp.setType(inAppMessage.getType()); - inApp.setTrackingState(NotificationInAppTracking.STORED); - inApp.setPriority(inAppMessage.getPriority()); - inApp.setSubject(inAppMessage.getSubject()); - inApp.setBody(inAppMessage.getBody()); - inApp.setExtraData(inAppMessage.getExtraData() != null ? this.jsonHandlingService.toJsonSafe(inAppMessage.getExtraData()) : null); - inApp.setCreatedAt(Instant.now()); - inApp.setUpdatedAt(Instant.now()); - inApp.setTenantId(tenantScope.getTenant()); + inApp.setId(UUID.randomUUID()); + inApp.setUserId(inAppContact.getUserId()); + inApp.setIsActive(IsActive.Active); + inApp.setType(inAppMessage.getType()); + inApp.setTrackingState(NotificationInAppTracking.STORED); + inApp.setPriority(inAppMessage.getPriority()); + inApp.setSubject(inAppMessage.getSubject()); + inApp.setBody(inAppMessage.getBody()); + inApp.setExtraData(inAppMessage.getExtraData() != null ? this.jsonHandlingService.toJsonSafe(inAppMessage.getExtraData()) : null); + inApp.setCreatedAt(Instant.now()); + inApp.setUpdatedAt(Instant.now()); + inApp.setTenantId(tenantScope.getTenant()); - entityManager.persist(inApp); - entityManager.flush(); + entityManager.persist(inApp); + entityManager.flush(); - InAppTrackingData trackingData = new InAppTrackingData(inApp.getId()); - data = this.jsonHandlingService.toJsonSafe(trackingData); - transaction.commit(); - } catch (Exception e) { - if (transaction != null) transaction.rollback(); - logger.error(e.getMessage(), e); - } finally { - if (entityManager != null) entityManager.close(); - } + InAppTrackingData trackingData = new InAppTrackingData(inApp.getId()); + data = this.jsonHandlingService.toJsonSafe(trackingData); + transaction.commit(); + } catch (Exception e) { + if (transaction != null) transaction.rollback(); + logger.error(e.getMessage(), e); + } finally { + try { + tenantEntityManager.reloadTenantFilters(); + } catch (InvalidApplicationException e) { + logger.error(e.getMessage(), e); + } + } return data; } diff --git a/notification-service/pom.xml b/notification-service/pom.xml index 76f3dc093..4dd88371d 100644 --- a/notification-service/pom.xml +++ b/notification-service/pom.xml @@ -107,7 +107,7 @@ gr.cite data-tools - 2.1.4 + 2.1.5