From c4679443830a5d1021766b319e3b6cdcd555ee17 Mon Sep 17 00:00:00 2001 From: Maverick Studer Date: Tue, 27 Aug 2024 13:23:40 +0200 Subject: [PATCH] RED-9331: Explore possibilities for fair upload / analysis processing per tenant --- .../build.gradle.kts | 4 +- .../configuration/MessagingConfiguration.java | 31 ++++----- .../TenantMessagingConfigurationImpl.java | 10 +++ .../ReportMessageReceiver.java | 14 ++-- .../TenantExchangeMessageReceiverImpl.java | 67 +++++++++++++++++++ .../report/v1/server/LifecycleAspectTest.java | 7 +- .../report/v1/server/PlaceholderTest.java | 8 +++ .../RedactionReportIntegrationTest.java | 8 +++ .../RedactionReportV2IntegrationTest.java | 8 +++ .../EntityLogConverterServiceTest.java | 8 +++ .../src/test/resources/application.yml | 2 + 11 files changed, 139 insertions(+), 28 deletions(-) create mode 100644 redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/configuration/TenantMessagingConfigurationImpl.java rename redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/{service => queue}/ReportMessageReceiver.java (78%) create mode 100644 redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/queue/TenantExchangeMessageReceiverImpl.java diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/build.gradle.kts b/redaction-report-service-v1/redaction-report-service-server-v1/build.gradle.kts index ca96f8d..18ee4c0 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/build.gradle.kts +++ b/redaction-report-service-v1/redaction-report-service-server-v1/build.gradle.kts @@ -11,13 +11,13 @@ plugins { description = "redaction-service-server-v1" -val tenantCommonVersion = "0.23.0" +val tenantCommonVersion = "0.28.0" val springCommonsVersion = "2.1.0" val storageCommonsVersion = "2.45.0" val lifecycleCommonsVersion = "0.4.0" val poiVersion = "5.2.3" val metricCommonsVersion = "2.1.0" -val persistenceServiceVersion = "2.522.0" +val persistenceServiceVersion = "2.532.0" val springBootStarterVersion = "3.2.3" configurations { diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/configuration/MessagingConfiguration.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/configuration/MessagingConfiguration.java index bd3dd9a..611b6d7 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/configuration/MessagingConfiguration.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/configuration/MessagingConfiguration.java @@ -1,5 +1,6 @@ package com.iqser.red.service.redaction.report.v1.server.configuration; +import org.springframework.amqp.core.DirectExchange; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.QueueBuilder; import org.springframework.context.annotation.Bean; @@ -11,43 +12,39 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class MessagingConfiguration { - public static final String REPORT_QUEUE = "reportQueue"; - public static final String REPORT_DLQ = "reportDLQ"; + public static final String REPORT_REQUEST_QUEUE_PREFIX = "report_request_queue"; + public static final String REPORT_REQUEST_EXCHANGE = "report_request_exchange"; + public static final String REPORT_REQUEST_DLQ = "report_request_dlq"; - public static final String REPORT_RESULT_QUEUE = "reportResultQueue"; - public static final String REPORT_RESULT_DLQ = "reportResultDLQ"; + public static final String REPORT_RESPONSE_EXCHANGE = "report_response_exchange"; + public static final String REPORT_RESPONSE_DLQ = "report_response_dlq"; @Bean - public Queue reportQueue() { + public DirectExchange reportRequestExchange() { - return QueueBuilder.durable(REPORT_QUEUE) - .withArgument("x-dead-letter-exchange", "") - .withArgument("x-dead-letter-routing-key", REPORT_DLQ) - .withArgument("x-max-priority", 2) - .maxPriority(2) - .build(); + return new DirectExchange(REPORT_REQUEST_EXCHANGE); } @Bean - public Queue reportDeadLetterQueue() { + public Queue reportRequestDLQ() { - return QueueBuilder.durable(REPORT_DLQ).build(); + return QueueBuilder.durable(REPORT_REQUEST_DLQ).build(); } @Bean - public Queue reportResultQueue() { + public DirectExchange reportResponseExchange() { - return QueueBuilder.durable(REPORT_RESULT_QUEUE).withArgument("x-dead-letter-exchange", "").withArgument("x-dead-letter-routing-key", REPORT_RESULT_DLQ).build(); + return new DirectExchange(REPORT_RESPONSE_EXCHANGE); } @Bean - public Queue reportResultDeadLetterQueue() { + public Queue reportResponseDLQ() { - return QueueBuilder.durable(REPORT_RESULT_DLQ).build(); + return QueueBuilder.durable(REPORT_RESPONSE_DLQ).build(); } } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/configuration/TenantMessagingConfigurationImpl.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/configuration/TenantMessagingConfigurationImpl.java new file mode 100644 index 0000000..a8ddeeb --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/configuration/TenantMessagingConfigurationImpl.java @@ -0,0 +1,10 @@ +package com.iqser.red.service.redaction.report.v1.server.configuration; + +import org.springframework.context.annotation.Configuration; + +import com.knecon.fforesight.tenantcommons.queue.TenantMessagingConfiguration; + +@Configuration +public class TenantMessagingConfigurationImpl extends TenantMessagingConfiguration { + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportMessageReceiver.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/queue/ReportMessageReceiver.java similarity index 78% rename from redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportMessageReceiver.java rename to redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/queue/ReportMessageReceiver.java index 0b19d5c..4f726a4 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportMessageReceiver.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/queue/ReportMessageReceiver.java @@ -1,7 +1,6 @@ -package com.iqser.red.service.redaction.report.v1.server.service; +package com.iqser.red.service.redaction.report.v1.server.queue; -import static com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration.REPORT_QUEUE; -import static com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration.REPORT_RESULT_QUEUE; +import static com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration.REPORT_RESPONSE_EXCHANGE; import org.springframework.amqp.AmqpRejectAndDontRequeueException; import org.springframework.amqp.core.Message; @@ -13,7 +12,8 @@ import org.springframework.stereotype.Service; import com.fasterxml.jackson.databind.ObjectMapper; import com.iqser.red.service.redaction.report.v1.api.model.ReportRequestMessage; import com.iqser.red.service.redaction.report.v1.api.model.ReportResultMessage; -import com.knecon.fforesight.lifecyclecommons.LifecycleManager; +import com.iqser.red.service.redaction.report.v1.server.service.ReportGenerationService; +import com.knecon.fforesight.tenantcommons.TenantContext; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; @@ -24,6 +24,8 @@ import lombok.extern.slf4j.Slf4j; @RequiredArgsConstructor public class ReportMessageReceiver { + public static final String REPORT_REQUEST_LISTENER_ID = "report-request-listener"; + private final ObjectMapper objectMapper; private final ReportGenerationService reportGenerationService; private final RabbitTemplate rabbitTemplate; @@ -31,7 +33,7 @@ public class ReportMessageReceiver { @SneakyThrows @RabbitHandler - @RabbitListener(queues = REPORT_QUEUE) + @RabbitListener(id = REPORT_REQUEST_LISTENER_ID) public void receive(Message message) { ReportRequestMessage reportMessage = objectMapper.readValue(message.getBody(), ReportRequestMessage.class); @@ -54,7 +56,7 @@ public class ReportMessageReceiver { private void addToReportResultQueue(String userId, String downloadId, String reportFileInformationStorageId) { - rabbitTemplate.convertAndSend(REPORT_RESULT_QUEUE, new ReportResultMessage(userId, downloadId, reportFileInformationStorageId)); + rabbitTemplate.convertAndSend(REPORT_RESPONSE_EXCHANGE, TenantContext.getTenantId(), new ReportResultMessage(userId, downloadId, reportFileInformationStorageId)); } } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/queue/TenantExchangeMessageReceiverImpl.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/queue/TenantExchangeMessageReceiverImpl.java new file mode 100644 index 0000000..7b98132 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/queue/TenantExchangeMessageReceiverImpl.java @@ -0,0 +1,67 @@ +package com.iqser.red.service.redaction.report.v1.server.queue; + +import static com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration.*; + +import java.util.Map; +import java.util.Set; + +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; + +import com.knecon.fforesight.tenantcommons.TenantProvider; +import com.knecon.fforesight.tenantcommons.model.TenantCreatedEvent; +import com.knecon.fforesight.tenantcommons.model.TenantQueueConfiguration; +import com.knecon.fforesight.tenantcommons.model.TenantResponse; +import com.knecon.fforesight.tenantcommons.queue.RabbitQueueFromExchangeService; +import com.knecon.fforesight.tenantcommons.queue.TenantExchangeMessageReceiver; + +@Service +public class TenantExchangeMessageReceiverImpl extends TenantExchangeMessageReceiver { + + public TenantExchangeMessageReceiverImpl(RabbitQueueFromExchangeService rabbitQueueService, TenantProvider tenantProvider) { + + super(rabbitQueueService, tenantProvider); + } + + + @Override + protected Set getTenantQueueConfigs() { + + return Set.of(TenantQueueConfiguration.builder() + .listenerId(ReportMessageReceiver.REPORT_REQUEST_LISTENER_ID) + .exchangeName(REPORT_REQUEST_EXCHANGE) + .queuePrefix(REPORT_REQUEST_QUEUE_PREFIX) + .dlqName(REPORT_REQUEST_DLQ) + .arguments(Map.of("x-max-priority", 2)) + .build()); + } + + + @EventListener(ApplicationReadyEvent.class) + public void onApplicationReady() { + + System.out.println("application ready invoked"); + super.initializeQueues(); + } + + + @RabbitHandler + @RabbitListener(queues = "#{tenantMessagingConfigurationImpl.getTenantCreatedQueueName()}") + public void reactToTenantCreation(TenantCreatedEvent tenantCreatedEvent) { + + super.reactToTenantCreation(tenantCreatedEvent); + } + + + @RabbitHandler + @RabbitListener(queues = "#{tenantMessagingConfigurationImpl.getTenantDeletedQueueName()}") + public void reactToTenantDeletion(TenantResponse tenantResponse) { + + super.reactToTenantDeletion(tenantResponse); + + } + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/LifecycleAspectTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/LifecycleAspectTest.java index 92337b2..29ca5b5 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/LifecycleAspectTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/LifecycleAspectTest.java @@ -1,6 +1,6 @@ package com.iqser.red.service.redaction.report.v1.server; -import static com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration.REPORT_RESULT_QUEUE; +import static com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration.REPORT_RESPONSE_EXCHANGE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; @@ -38,15 +38,16 @@ import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesCon import com.iqser.red.service.redaction.report.v1.server.client.ReportTemplateClient; import com.iqser.red.service.redaction.report.v1.server.config.AspectTestConfig; import com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration; +import com.iqser.red.service.redaction.report.v1.server.queue.ReportMessageReceiver; import com.iqser.red.service.redaction.report.v1.server.service.EntityLogConverterService; import com.iqser.red.service.redaction.report.v1.server.service.ExcelReportGenerationService; import com.iqser.red.service.redaction.report.v1.server.service.GeneratePlaceholderService; -import com.iqser.red.service.redaction.report.v1.server.service.ReportMessageReceiver; import com.iqser.red.service.redaction.report.v1.server.service.WordReportGenerationService; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; import com.iqser.red.service.redaction.report.v1.server.utils.TestController; import com.iqser.red.storage.commons.service.StorageService; import com.knecon.fforesight.lifecyclecommons.LifecycleManager; +import com.knecon.fforesight.tenantcommons.TenantContext; import com.knecon.fforesight.tenantcommons.TenantsClient; import lombok.SneakyThrows; @@ -148,7 +149,7 @@ public class LifecycleAspectTest { reportMessageReceiver.receive(mockMessage); lifecycleManager.stop(); - verify(rabbitTemplate, times(1)).convertAndSend(eq(REPORT_RESULT_QUEUE), any(ReportResultMessage.class)); + verify(rabbitTemplate, times(1)).convertAndSend(eq(REPORT_RESPONSE_EXCHANGE), eq(TenantContext.getTenantId()), any(ReportResultMessage.class)); } @Test diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java index d48bced..bf00086 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/PlaceholderTest.java @@ -10,7 +10,9 @@ import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; @@ -52,6 +54,12 @@ public class PlaceholderTest { @MockBean private RabbitTemplate rabbitTemplate; + @MockBean + protected RabbitAdmin rabbitAdmin; + + @MockBean + protected RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry; + @MockBean private ReportTemplateClient reportTemplateClient; diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java index afbc2b5..55c1ce3 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java @@ -35,7 +35,9 @@ import org.apache.poi.xwpf.usermodel.XWPFRun; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; +import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; @@ -99,6 +101,12 @@ public class RedactionReportIntegrationTest { @MockBean private RabbitTemplate rabbitTemplate; + @MockBean + protected RabbitAdmin rabbitAdmin; + + @MockBean + protected RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry; + @MockBean private ReportStorageService reportStorageService; diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportV2IntegrationTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportV2IntegrationTest.java index 527a784..1321dd7 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportV2IntegrationTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportV2IntegrationTest.java @@ -35,7 +35,9 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; @@ -75,6 +77,12 @@ public class RedactionReportV2IntegrationTest { @MockBean private RabbitTemplate rabbitTemplate; + @MockBean + protected RabbitAdmin rabbitAdmin; + + @MockBean + protected RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry; + @MockBean private ReportTemplateClient reportTemplateClient; diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/service/EntityLogConverterServiceTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/service/EntityLogConverterServiceTest.java index b3656ee..7a9ab45 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/service/EntityLogConverterServiceTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/service/EntityLogConverterServiceTest.java @@ -12,6 +12,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.springframework.amqp.rabbit.core.RabbitAdmin; +import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -43,6 +45,12 @@ public class EntityLogConverterServiceTest { private static final String DOSSIER_ID = "DossierId"; private static final String FILE_ID = "FileId"; + @MockBean + protected RabbitAdmin rabbitAdmin; + + @MockBean + protected RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry; + @MockBean TenantsClient tenantsClient; diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml index 733d497..feae69b 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml @@ -25,3 +25,5 @@ spring: password: ${MONGODB_PASSWORD} persistence-service.url: "http://mock.url" + +POD_NAME: "redaction-report-service"