From cd6d6f3a3ee1109525c4c47f920bfd39f5e3eb6d Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Thu, 18 Jan 2024 15:59:36 -0500 Subject: [PATCH 01/11] Add CLI capability for enhanced user experience --- .../management/agent/cli/EmaCommandLine.java | 210 ++++++++++++++++++ .../agent/config/ResourceConfig.java | 4 + .../processor/RouteCompleteProcessorImpl.java | 16 +- .../processor/RouteFailedProcessorImpl.java | 29 +++ ...anStatusFailedPersistenceRouteBuilder.java | 26 +++ .../agent/scanManager/ScanResponse.java | 13 ++ .../agent/service/ScanStatusService.java | 25 ++- .../management/agent/ScanTestConfig.java | 41 ++++ .../management/agent/cli/CliScanTest.java | 54 +++++ .../processor/RouteCompleteProcessor.java | 2 +- .../processor/RouteFailedProcessor.java | 7 + .../plugin/processor/RouteStateProcessor.java | 22 ++ .../handler/base/AbstractRouteBuilder.java | 1 + 13 files changed, 432 insertions(+), 18 deletions(-) create mode 100644 service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java create mode 100644 service/application/src/main/java/com/solace/maas/ep/event/management/agent/processor/RouteFailedProcessorImpl.java create mode 100644 service/application/src/main/java/com/solace/maas/ep/event/management/agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java create mode 100644 service/application/src/main/java/com/solace/maas/ep/event/management/agent/scanManager/ScanResponse.java create mode 100644 service/application/src/test/java/com/solace/maas/ep/event/management/agent/ScanTestConfig.java create mode 100644 service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java create mode 100644 service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteFailedProcessor.java create mode 100644 service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteStateProcessor.java diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java new file mode 100644 index 00000000..08f4553a --- /dev/null +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java @@ -0,0 +1,210 @@ +package com.solace.maas.ep.event.management.agent.cli; + +import com.solace.maas.ep.event.management.agent.repository.model.mesagingservice.MessagingServiceEntity; +import com.solace.maas.ep.event.management.agent.repository.model.scan.ScanStatusEntity; +import com.solace.maas.ep.event.management.agent.scanManager.ScanManager; +import com.solace.maas.ep.event.management.agent.scanManager.model.ScanRequestBO; +import com.solace.maas.ep.event.management.agent.scanManager.model.ZipRequestBO; +import com.solace.maas.ep.event.management.agent.service.DataCollectionFileService; +import com.solace.maas.ep.event.management.agent.service.ImportService; +import com.solace.maas.ep.event.management.agent.service.MessagingServiceDelegateServiceImpl; +import com.solace.maas.ep.event.management.agent.service.ScanStatusService; +import com.solace.maas.ep.event.management.agent.util.IDGenerator; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.CommandLineRunner; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +@Component +@Order(1) +@Slf4j +public class EmaCommandLine implements CommandLineRunner { + private final ScanManager scanManager; + private final ImportService importService; + private final ScanStatusService scanStatusService; + private final IDGenerator idGenerator; + private final DataCollectionFileService dataCollectionFileService; + private final MessagingServiceDelegateServiceImpl messagingServiceDelegateService; + + public EmaCommandLine(ScanManager scanManager, + ImportService importService, + ScanStatusService scanStatusService, + IDGenerator idGenerator, + DataCollectionFileService dataCollectionFileService, + MessagingServiceDelegateServiceImpl messagingServiceDelegateService) { + this.scanManager = scanManager; + this.importService = importService; + this.scanStatusService = scanStatusService; + this.idGenerator = idGenerator; + this.dataCollectionFileService = dataCollectionFileService; + this.messagingServiceDelegateService = messagingServiceDelegateService; + } + + @Override + public void run(String... args) throws Exception { + if (args.length > 2) { + + String type = args[0]; + + if ("scan".equals(type)) { + String messagingServiceId = args[1]; + String filePathAndName = args[2]; + + runScan(messagingServiceId, filePathAndName); + } else { + log.error("Unknown command: {}", type); + } + } else { + log.info(" arguments passed to the application."); + } + } + + private void runScan(String messagingServiceId, String filePathAndName) throws InterruptedException, IOException { + MessagingServiceEntity messagingServiceEntity = messagingServiceDelegateService.getMessagingServiceById(messagingServiceId); + + ScanRequestBO scanRequestBO = new ScanRequestBO(); + scanRequestBO.setMessagingServiceId(messagingServiceId); + scanRequestBO.setScanId(idGenerator.generateRandomUniqueId()); + setScanType(messagingServiceEntity, scanRequestBO, messagingServiceId); + scanRequestBO.setDestinations(List.of("FILE_WRITER")); + + log.info("Scan request [{}]: Received, request details: {}", scanRequestBO.getScanId(), scanRequestBO); + String scanId = scanManager.scan(scanRequestBO); + + log.info("Scan request [{}]: Scan started.", scanId); + waitForScanToComplete(scanId); + + if (isCompletedSuccessfully(scanId)) { + writeScanToZipFile(filePathAndName, scanId); + } else { + log.error("Scan request [{}]: Scan did not complete successfully.", scanId); + } + } + + private boolean isCompletedSuccessfully(String scanId) { + List statuses = scanStatusService.getScanStatuses(scanId); + boolean completedSuccessfully = false; + if (dataCollectionFileService.findAllByScanId(scanId).size() >= + statuses.size() && !anyScanStatusesInDesiredState("FAILED", statuses)) { + log.info("Scan request [{}]: Scan completed successfully.", scanId); + completedSuccessfully = true; + } + return completedSuccessfully; + } + + private void setScanType(MessagingServiceEntity messagingServiceEntity, ScanRequestBO scanRequestBO, String messagingServiceId) { + switch (messagingServiceEntity.getType().toLowerCase()) { + case "solace": + scanRequestBO.setScanTypes(List.of("SOLACE_ALL")); + break; + case "kafka": + messagingServiceDelegateService.getMessagingServicesRelations(messagingServiceId).stream() + .findFirst() + .ifPresentOrElse(messagingServiceEntity1 -> scanRequestBO.setScanTypes(List.of("KAFKA_ALL", "CONFLUENT_SCHEMA_REGISTRY_SCHEMA")), + () -> scanRequestBO.setScanTypes(List.of("KAFKA_ALL"))); + break; + case "confluent_schema_registry": + scanRequestBO.setScanTypes(List.of("CONFLUENT_SCHEMA_REGISTRY_SCHEMA")); + break; + default: + throw new RuntimeException("Unsupported messaging service type: " + messagingServiceEntity.getType()); + } + } + + public void waitForScanToComplete(String scanId) throws InterruptedException { + AtomicBoolean scanCompleted = new AtomicBoolean(false); + + // The hard timeout is set to 30 minutes to prevent the scan from running forever + long hardTimeoutMillis = System.currentTimeMillis() + 30 * 60 * 1000; + + // The initiated timout is set to 2 minutes to shortcut a scan that is stuck in the INITIATED state + // This typically occurs if there is an error in the broker URL or credentials + long initiatedTimeoutMillis = System.currentTimeMillis() + 2 * 60 * 1000; + + while (System.currentTimeMillis() < hardTimeoutMillis && !scanCompleted.get()) { + Thread.sleep(2000); + + List statuses = scanStatusService.getScanStatuses(scanId); + + if (scanCompleted(statuses)) { + scanCompleted.set(true); + } else if (System.currentTimeMillis() > initiatedTimeoutMillis && scanInitiated(statuses)) { + throw new RuntimeException("Scan is stuck in INITIATED state. Check broker URL and credentials."); + } else { + log.debug("Waiting for scan to complete..."); + } + } + } + + private void writeScanToZipFile(String filePathAndName, String scanId) throws IOException { + // Use the import service to receive the scan stream and write + // it to a zip file + ZipRequestBO zipRequestBO = new ZipRequestBO(); + zipRequestBO.setScanId(scanId); + log.info("Received zip request for scan id: {}", zipRequestBO.getScanId()); + try (InputStream fileStream = importService.zip(zipRequestBO)) { + + // Write the input stream to a file in the /tmp directory + File file = new File(filePathAndName); + writeInputStreamToFile(fileStream, file); + } + } + + private static void writeInputStreamToFile(InputStream inputStream, File file) { + try { + Files.copy(inputStream, file.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private boolean scanCompleted(List statuses) { + return scanSucceeded(statuses) || scanFailed(statuses); + } + + private boolean scanSucceeded(List statuses) { + return allScanStatusesInDesiredState("COMPLETE", statuses); + } + + private boolean scanFailed(List statuses) { + return anyScanStatusesInDesiredState("FAILED", statuses); + } + + private boolean scanInitiated(List statuses) { + return allScanStatusesInDesiredState("INITIATED", statuses); + } + + private boolean allScanStatusesInDesiredState(String desiredState, List statuses) { + // Check that all the scan types have the desired state + AtomicBoolean allScanTypesDesired = new AtomicBoolean(true); + statuses.forEach(scanStatusEntity -> { + if (!desiredState.equals(scanStatusEntity.getStatus())) { + allScanTypesDesired.set(false); + } + }); + + return allScanTypesDesired.get(); + } + + private boolean anyScanStatusesInDesiredState(String desiredState, List statuses) { + // Check that all the scan types have the desired state + AtomicBoolean anyScanTypesDesired = new AtomicBoolean(false); + statuses.forEach(scanStatusEntity -> { + if (desiredState.equals(scanStatusEntity.getStatus())) { + anyScanTypesDesired.set(true); + } + }); + + return anyScanTypesDesired.get(); + } + +} + diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/config/ResourceConfig.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/config/ResourceConfig.java index 634e1653..ab0454a1 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/config/ResourceConfig.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/config/ResourceConfig.java @@ -12,6 +12,8 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import java.util.List; import java.util.Objects; @@ -24,11 +26,13 @@ @ConfigurationProperties(prefix = "plugins") @Slf4j @Profile("!TEST") +@Order(Ordered.HIGHEST_PRECEDENCE) public class ResourceConfig implements ApplicationRunner { private final MessagingServiceDelegateServiceImpl messagingServiceDelegateService; private List resources; private final MessagingServicePluginPropertyToEventConverter configToEventConverter; + @Override public void run(ApplicationArguments args) { if (Objects.nonNull(resources)) { diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorImpl.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorImpl.java index d3f63335..be836781 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorImpl.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorImpl.java @@ -8,8 +8,6 @@ import org.apache.camel.Exchange; import org.springframework.stereotype.Component; -import java.util.List; - @Slf4j @Component public class RouteCompleteProcessorImpl extends RouteCompleteProcessor { @@ -23,18 +21,8 @@ public RouteCompleteProcessorImpl(ScanStatusService scanStatusService) { @Override public void process(Exchange exchange) throws Exception { exchange.getIn().setHeader(RouteConstants.SCAN_STATUS, ScanStatus.COMPLETE); - String scanId = (String) exchange.getIn().getHeader(RouteConstants.SCAN_ID); - - String scanType; - - if (exchange.getIn().getHeader(RouteConstants.SCAN_TYPE) instanceof List) { - scanType = (String) exchange.getIn().getBody(); - exchange.getIn().setHeader(RouteConstants.SCAN_TYPE, scanType); - } else { - scanType = (String) exchange.getIn().getHeader(RouteConstants.SCAN_TYPE); - } - - scanStatusService.save(scanType, scanId); + String scanType = getScanType(exchange); + scanStatusService.save(scanType, scanId, ScanStatus.COMPLETE); } } diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/processor/RouteFailedProcessorImpl.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/processor/RouteFailedProcessorImpl.java new file mode 100644 index 00000000..20e2abe8 --- /dev/null +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/processor/RouteFailedProcessorImpl.java @@ -0,0 +1,29 @@ +package com.solace.maas.ep.event.management.agent.processor; + +import com.solace.maas.ep.event.management.agent.plugin.constants.RouteConstants; +import com.solace.maas.ep.event.management.agent.plugin.constants.ScanStatus; +import com.solace.maas.ep.event.management.agent.plugin.processor.RouteFailedProcessor; +import com.solace.maas.ep.event.management.agent.service.ScanStatusService; +import lombok.extern.slf4j.Slf4j; +import org.apache.camel.Exchange; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class RouteFailedProcessorImpl extends RouteFailedProcessor { + private final ScanStatusService scanStatusService; + + public RouteFailedProcessorImpl(ScanStatusService scanStatusService) { + super(); + this.scanStatusService = scanStatusService; + } + + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(RouteConstants.SCAN_STATUS, ScanStatus.COMPLETE); + + String scanId = (String) exchange.getIn().getHeader(RouteConstants.SCAN_ID); + String scanType = getScanType(exchange); + scanStatusService.save(scanType, scanId, ScanStatus.FAILED); + } +} diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java new file mode 100644 index 00000000..827fd588 --- /dev/null +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java @@ -0,0 +1,26 @@ +package com.solace.maas.ep.event.management.agent.route.ep; + +import com.solace.maas.ep.event.management.agent.plugin.processor.ScanTypeDescendentsProcessor; +import com.solace.maas.ep.event.management.agent.plugin.route.handler.base.AbstractRouteBuilder; +import com.solace.maas.ep.event.management.agent.processor.RouteFailedProcessorImpl; +import org.springframework.stereotype.Component; + +@Component +public class ScanStatusFailedPersistenceRouteBuilder extends AbstractRouteBuilder { + private final RouteFailedProcessorImpl routeFailedProcessor; + + public ScanStatusFailedPersistenceRouteBuilder(RouteFailedProcessorImpl routeFailedProcessor, + ScanTypeDescendentsProcessor scanTypeDescendentsProcessor) { + super(scanTypeDescendentsProcessor); + this.routeFailedProcessor = routeFailedProcessor; + } + + @Override + public void configure() throws Exception { + super.configure(); + + from("direct:processScanStatusAsFailed") + .process(routeFailedProcessor); + // .to("direct:perRouteScanStatusPublisher?block=false&failIfNoConsumers=false"); + } +} diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/scanManager/ScanResponse.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/scanManager/ScanResponse.java new file mode 100644 index 00000000..8dc77e34 --- /dev/null +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/scanManager/ScanResponse.java @@ -0,0 +1,13 @@ +package com.solace.maas.ep.event.management.agent.scanManager; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +@Data +@Builder +public class ScanResponse { + private String id; + private List scanTypes; +} diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java index f6a72a52..5249e95b 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java @@ -1,6 +1,7 @@ package com.solace.maas.ep.event.management.agent.service; import com.solace.maas.ep.event.management.agent.plugin.constants.ScanStatus; +import com.solace.maas.ep.event.management.agent.repository.model.scan.ScanEntity; import com.solace.maas.ep.event.management.agent.repository.model.scan.ScanStatusEntity; import com.solace.maas.ep.event.management.agent.repository.model.scan.ScanTypeEntity; import com.solace.maas.ep.event.management.agent.repository.scan.ScanStatusRepository; @@ -8,6 +9,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Objects; @Service @@ -15,32 +17,49 @@ public class ScanStatusService { private final ScanStatusRepository repository; private final ScanTypeService scanTypeService; + private final ScanService scanService; private final IDGenerator idGenerator; - public ScanStatusService(ScanStatusRepository repository, ScanTypeService scanTypeService, IDGenerator idGenerator) { + public ScanStatusService(ScanStatusRepository repository, ScanTypeService scanTypeService, ScanService scanService, IDGenerator idGenerator) { this.repository = repository; this.scanTypeService = scanTypeService; + this.scanService = scanService; this.idGenerator = idGenerator; } @Transactional public ScanStatusEntity save(String name, String scanId) { + return save(name, scanId, ScanStatus.COMPLETE); + } + + @Transactional + public ScanStatusEntity save(String name, String scanId, ScanStatus scanStatus) { ScanTypeEntity scanType = scanTypeService.findByNameAndScanId(name, scanId) .orElseThrow(() -> new RuntimeException("Can't apply Scan Status to Scan that doesn't exist!")); ScanStatusEntity scanStatusEntity = scanType.getStatus(); if (Objects.nonNull(scanStatusEntity)) { - scanStatusEntity.setStatus(ScanStatus.COMPLETE.name()); + scanStatusEntity.setStatus(scanStatus.name()); } else { scanStatusEntity = ScanStatusEntity.builder() .id(idGenerator.generateRandomUniqueId()) .scanType(scanType) - .status(ScanStatus.COMPLETE.name()) + .status(scanStatus.name()) .build(); } return repository.save(scanStatusEntity); } + + @Transactional + public List getScanStatuses(String scanId) { + ScanEntity scanEntity = scanService.findById(scanId) + .orElseThrow(() -> new RuntimeException("Scan not found!")); + List scanStatuses = scanEntity.getScanTypes().stream() + .map(ScanTypeEntity::getStatus) + .toList(); + return scanStatuses; + } } diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/ScanTestConfig.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/ScanTestConfig.java new file mode 100644 index 00000000..c28d0bc6 --- /dev/null +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/ScanTestConfig.java @@ -0,0 +1,41 @@ +package com.solace.maas.ep.event.management.agent; + +import com.solace.maas.ep.event.management.agent.service.DataCollectionFileService; +import com.solace.maas.ep.event.management.agent.service.ImportService; +import com.solace.maas.ep.event.management.agent.service.ScanService; +import com.solace.maas.ep.event.management.agent.service.ScanStatusService; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; + +import static org.mockito.Mockito.mock; + +@TestConfiguration +@Profile("SCANTEST") +public class ScanTestConfig { + + @Primary + @Bean + public ScanService getScanService() { + return mock(ScanService.class); + } + + @Primary + @Bean + public ScanStatusService getScanStatusService() { + return mock(ScanStatusService.class); + } + + @Primary + @Bean + public DataCollectionFileService getDataCollectionFileService() { + return mock(DataCollectionFileService.class); + } + + @Primary + @Bean + public ImportService getImportService() { + return mock(ImportService.class); + } +} diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java new file mode 100644 index 00000000..e1918291 --- /dev/null +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java @@ -0,0 +1,54 @@ +package com.solace.maas.ep.event.management.agent.cli; + +import com.solace.maas.ep.event.management.agent.TestConfig; +import com.solace.maas.ep.event.management.agent.repository.model.file.DataCollectionFileEntity; +import com.solace.maas.ep.event.management.agent.repository.model.mesagingservice.MessagingServiceEntity; +import com.solace.maas.ep.event.management.agent.repository.model.scan.ScanEntity; +import com.solace.maas.ep.event.management.agent.service.DataCollectionFileService; +import com.solace.maas.ep.event.management.agent.service.ImportService; +import com.solace.maas.ep.event.management.agent.service.ScanService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@ActiveProfiles({"SCANTEST", "TEST"}) +@SpringBootTest(classes = TestConfig.class) +public class CliScanTest { + + @Autowired + private EmaCommandLine emaCommandLine; + + @Autowired + private ScanService scanService; + + @Autowired + private ImportService importService; + + @Autowired + private DataCollectionFileService dataCollectionFileService; + + @Test + public void testCLICommand() throws Exception { + when(scanService.findById(any())).thenReturn(Optional.of(ScanEntity.builder() + .id("abcdef") + .messagingService(MessagingServiceEntity.builder() + .id("bbbbbb") + .build()) + .build())); + when(dataCollectionFileService.findAllByScanId(any())).thenReturn( + List.of(DataCollectionFileEntity.builder() + .path("a/b/c") + .build())); + when(importService.zip(any())).thenReturn(new ByteArrayInputStream("test".getBytes(StandardCharsets.UTF_8))); + emaCommandLine.run("scan", "abcdef", "/tmp/scan.txt"); + } +} \ No newline at end of file diff --git a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteCompleteProcessor.java b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteCompleteProcessor.java index 8a0972e6..786b4f7a 100644 --- a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteCompleteProcessor.java +++ b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteCompleteProcessor.java @@ -2,6 +2,6 @@ import org.apache.camel.Processor; -public abstract class RouteCompleteProcessor implements Processor { +public abstract class RouteCompleteProcessor extends RouteStateProcessor implements Processor { } diff --git a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteFailedProcessor.java b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteFailedProcessor.java new file mode 100644 index 00000000..ea08d627 --- /dev/null +++ b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteFailedProcessor.java @@ -0,0 +1,7 @@ +package com.solace.maas.ep.event.management.agent.plugin.processor; + +import org.apache.camel.Processor; + +public abstract class RouteFailedProcessor extends RouteStateProcessor implements Processor { + +} diff --git a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteStateProcessor.java b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteStateProcessor.java new file mode 100644 index 00000000..37d3f4de --- /dev/null +++ b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/processor/RouteStateProcessor.java @@ -0,0 +1,22 @@ +package com.solace.maas.ep.event.management.agent.plugin.processor; + +import com.solace.maas.ep.event.management.agent.plugin.constants.RouteConstants; +import org.apache.camel.Exchange; + +import java.util.List; + +public abstract class RouteStateProcessor { + public String getScanType(Exchange exchange) throws Exception { + String scanType; + + if (exchange.getIn().getHeader(RouteConstants.SCAN_TYPE) instanceof List) { + scanType = (String) exchange.getIn().getBody(); + exchange.getIn().setHeader(RouteConstants.SCAN_TYPE, scanType); + } else { + scanType = (String) exchange.getIn().getHeader(RouteConstants.SCAN_TYPE); + } + + return scanType; + } + +} diff --git a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/route/handler/base/AbstractRouteBuilder.java b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/route/handler/base/AbstractRouteBuilder.java index 0cbf5b9c..28618b7e 100644 --- a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/route/handler/base/AbstractRouteBuilder.java +++ b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/route/handler/base/AbstractRouteBuilder.java @@ -59,6 +59,7 @@ public void configure() throws Exception { RouteConstants.TRACE_ID + "}]: The status of [${header." + RouteConstants.SCAN_TYPE + "}]" + " is: [${header." + RouteConstants.SCAN_STATUS + "}].") .to("direct:perRouteScanStatusPublisher?block=false&failIfNoConsumers=false") + .to("direct:processScanStatusAsFailed?block=false") .end() .setHeader(RouteConstants.SCAN_TYPE, simple("${header." + RouteConstants.SCAN_TYPE + "}", String.class)) .to("direct:overallScanStatusPublisher?block=false&failIfNoConsumers=false"); From 3f732bc866352ad3e2d596f594b0dc11be62c14a Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Thu, 18 Jan 2024 17:04:15 -0500 Subject: [PATCH 02/11] Update error handling so that Camel can see client errors and stop processing in failure scenarios --- .../schema/ConfluentSchemaRegistryHttp.java | 4 ++-- .../ConfluentSchemaRegistryClientTests.java | 4 ++-- .../KafkaClusterConfigurationProcessor.java | 2 +- .../client/KafkaClientManagerImpl.java | 19 ++++++++++--------- .../kafka/client/KafkaClientManagerTests.java | 8 ++++---- .../handler/base/AbstractRouteBuilder.java | 4 +++- .../solace/processor/semp/SempException.java | 7 ------- .../solace/processor/semp/SolaceHttpSemp.java | 16 +++++++++------- .../processor/SolaceSempClientTests.java | 6 +++--- 9 files changed, 34 insertions(+), 36 deletions(-) delete mode 100644 service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SempException.java diff --git a/service/confluent-schema-registry-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/confluentSchemaRegistry/processor/schema/ConfluentSchemaRegistryHttp.java b/service/confluent-schema-registry-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/confluentSchemaRegistry/processor/schema/ConfluentSchemaRegistryHttp.java index 28cfcffc..0f82a315 100644 --- a/service/confluent-schema-registry-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/confluentSchemaRegistry/processor/schema/ConfluentSchemaRegistryHttp.java +++ b/service/confluent-schema-registry-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/confluentSchemaRegistry/processor/schema/ConfluentSchemaRegistryHttp.java @@ -3,8 +3,8 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import com.solace.maas.ep.event.management.agent.plugin.confluentSchemaRegistry.exception.ClientException; import com.solace.maas.ep.event.management.agent.plugin.confluentSchemaRegistry.processor.event.ConfluentSchemaRegistrySchemaEvent; +import com.solace.maas.ep.event.management.agent.plugin.exception.PluginClientException; import com.solace.maas.ep.event.management.agent.plugin.jacoco.ExcludeFromJacocoGeneratedReport; import com.solace.maas.ep.event.management.agent.plugin.util.UriUtil; import lombok.Getter; @@ -54,7 +54,7 @@ private String getResponse(URI uri) throws IOException { httpClient.getConnectionUrl() + uri.getPath(), response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()); - throw new ClientException(String.format("Could not fulfill API call for path %s", + throw new PluginClientException(String.format("Could not fulfill API call for path %s", httpClient.getConnectionUrl() + uri.getPath())); } HttpEntity entity = response.getEntity(); diff --git a/service/confluent-schema-registry-plugin/src/test/java/com/solace/maas/ep/event/management/agent/plugin/confluentSchemaRegistry/manager/processor/ConfluentSchemaRegistryClientTests.java b/service/confluent-schema-registry-plugin/src/test/java/com/solace/maas/ep/event/management/agent/plugin/confluentSchemaRegistry/manager/processor/ConfluentSchemaRegistryClientTests.java index 4998ab5b..c2c95a2c 100644 --- a/service/confluent-schema-registry-plugin/src/test/java/com/solace/maas/ep/event/management/agent/plugin/confluentSchemaRegistry/manager/processor/ConfluentSchemaRegistryClientTests.java +++ b/service/confluent-schema-registry-plugin/src/test/java/com/solace/maas/ep/event/management/agent/plugin/confluentSchemaRegistry/manager/processor/ConfluentSchemaRegistryClientTests.java @@ -1,9 +1,9 @@ package com.solace.maas.ep.event.management.agent.plugin.confluentSchemaRegistry.manager.processor; -import com.solace.maas.ep.event.management.agent.plugin.confluentSchemaRegistry.exception.ClientException; import com.solace.maas.ep.event.management.agent.plugin.confluentSchemaRegistry.processor.event.ConfluentSchemaRegistrySchemaEvent; import com.solace.maas.ep.event.management.agent.plugin.confluentSchemaRegistry.processor.schema.ConfluentSchemaRegistryHttp; import com.solace.maas.ep.event.management.agent.plugin.confluentSchemaRegistry.processor.schema.HttpClient; +import com.solace.maas.ep.event.management.agent.plugin.exception.PluginClientException; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import okhttp3.mockwebserver.MockResponse; @@ -100,6 +100,6 @@ void getAllSchemasFailTest() { mockWebServer.enqueue(new MockResponse() .setBody("service unavailable") .setResponseCode(503)); - assertThrows(ClientException.class, () -> confluentSchemaRegistryHttp.getSchemas()); + assertThrows(PluginClientException.class, () -> confluentSchemaRegistryHttp.getSchemas()); } } diff --git a/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/kafka/processor/cluster/KafkaClusterConfigurationProcessor.java b/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/kafka/processor/cluster/KafkaClusterConfigurationProcessor.java index d4df7af2..6558a4e5 100644 --- a/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/kafka/processor/cluster/KafkaClusterConfigurationProcessor.java +++ b/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/kafka/processor/cluster/KafkaClusterConfigurationProcessor.java @@ -2,8 +2,8 @@ import com.solace.maas.ep.event.management.agent.plugin.constants.RouteConstants; import com.solace.maas.ep.event.management.agent.plugin.jacoco.ExcludeFromJacocoGeneratedReport; -import com.solace.maas.ep.event.management.agent.plugin.manager.client.kafkaClient.KafkaClientConfig; import com.solace.maas.ep.event.management.agent.plugin.kafka.processor.event.cluster.KafkaClusterConfigurationEvent; +import com.solace.maas.ep.event.management.agent.plugin.manager.client.kafkaClient.KafkaClientConfig; import com.solace.maas.ep.event.management.agent.plugin.processor.base.ResultProcessorImpl; import com.solace.maas.ep.event.management.agent.plugin.service.MessagingServiceDelegateService; import lombok.extern.slf4j.Slf4j; diff --git a/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/manager/client/KafkaClientManagerImpl.java b/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/manager/client/KafkaClientManagerImpl.java index 5bfd67ef..eb25eef9 100644 --- a/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/manager/client/KafkaClientManagerImpl.java +++ b/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/manager/client/KafkaClientManagerImpl.java @@ -1,5 +1,6 @@ package com.solace.maas.ep.event.management.agent.plugin.manager.client; +import com.solace.maas.ep.event.management.agent.plugin.exception.PluginClientException; import com.solace.maas.ep.event.management.agent.plugin.manager.client.kafkaClient.KafkaClientConfig; import com.solace.maas.ep.event.management.agent.plugin.messagingService.event.AuthenticationDetailsEvent; import com.solace.maas.ep.event.management.agent.plugin.messagingService.event.ConnectionDetailsEvent; @@ -39,17 +40,17 @@ public class KafkaClientManagerImpl implements MessagingServiceClientManager { + Exception exception = assertThrows(PluginClientException.class, () -> { kafkaClientManager.getClient(connectionDetailsEvent); }); - assertTrue(exception.getCause().getMessage().contains("Invalid url")); + assertTrue(exception.getCause().getMessage().contains("Failed to create new KafkaAdminClient")); } private EventProperty buildProperty(String name, String value) { diff --git a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/route/handler/base/AbstractRouteBuilder.java b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/route/handler/base/AbstractRouteBuilder.java index 28618b7e..7d21945f 100644 --- a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/route/handler/base/AbstractRouteBuilder.java +++ b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/route/handler/base/AbstractRouteBuilder.java @@ -1,6 +1,7 @@ package com.solace.maas.ep.event.management.agent.plugin.route.handler.base; import com.solace.maas.ep.event.management.agent.plugin.constants.RouteConstants; +import com.solace.maas.ep.event.management.agent.plugin.exception.PluginClientException; import com.solace.maas.ep.event.management.agent.plugin.processor.ScanTypeDescendentsProcessor; import com.solace.maas.ep.event.management.agent.plugin.route.exceptionhandlers.GeneralExceptionHandler; import com.solace.maas.ep.event.management.agent.plugin.route.exceptionhandlers.ScanDataExceptionHandler; @@ -40,7 +41,8 @@ protected AbstractRouteBuilder(ScanTypeDescendentsProcessor scanTypeDescendentsP public void configure() throws Exception { // NetworkClient Selectable network i/o exception + Kafka Future exceptions - onException(IOException.class, InterruptedException.class, ExecutionException.class, TimeoutException.class) + onException(IOException.class, InterruptedException.class, ExecutionException.class, TimeoutException.class, + PluginClientException.class) .maximumRedeliveries(maximumRedeliveries) .redeliveryDelay(redeliveryDelay) .maximumRedeliveryDelay(maximumRedeliveryDelay) diff --git a/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SempException.java b/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SempException.java deleted file mode 100644 index 52806037..00000000 --- a/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SempException.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.solace.maas.ep.event.management.agent.plugin.solace.processor.semp; - -public class SempException extends RuntimeException { - public SempException(Throwable cause) { - super(cause); - } -} diff --git a/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java b/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java index 4761e17d..9cfd3e51 100644 --- a/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java +++ b/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.solace.maas.ep.event.management.agent.plugin.exception.PluginClientException; import com.solace.maas.ep.event.management.agent.plugin.jacoco.ExcludeFromJacocoGeneratedReport; import com.solace.maas.ep.event.management.agent.plugin.util.UriUtil; import lombok.Getter; @@ -80,7 +81,7 @@ private Map getResultsFlatFromSemp(String uriPath) { return getSempFlatRequest(createFlatUriBuilderFunction(uriPath, Collections.emptyMap())); } catch (IOException ioException) { log.error("Error during SEMP Data Collection", ioException); - throw new SempException(ioException); + throw new PluginClientException("Error during SEMP Data Collection", ioException); } } @@ -101,25 +102,25 @@ private List> getResultsListMapFromSemp(String uriPath, if (ex.getStatusCode() == BAD_REQUEST) { log.error("Error during SEMP Data Collection. Invalid path to data." + " Check that the SEMP URL and protocol are correct.", ex); - throw new SempException(ex); + throw new PluginClientException("Error during SEMP Data Collection.", ex); } else if (ex.getStatusCode() == UNAUTHORIZED) { log.error("Error during SEMP Data Collection. Could not authenticate with the server." + "Check that the SEMP username and password are correct.", ex); - throw new SempException(ex); + throw new PluginClientException("Error during SEMP Data Collection.", ex); } else { log.error("Error during SEMP Data Collection.", ex); - throw new SempException(ex); + throw new PluginClientException("Error during SEMP Data Collection.", ex); } } catch (IOException ioException) { log.error("Error during SEMP Data Collection. The format of the collected data is unexpected.", ioException); - throw new SempException(ioException); + throw new PluginClientException("Error during SEMP Data Collection.", ioException); } catch (WebClientRequestException requestException) { if (requestException.getMessage().startsWith("Failed to resolve")) { log.error("Error connecting to messaging service. Check that the hostname is correct.", requestException); - throw new SempException(requestException); + throw new PluginClientException("Error during SEMP Data Collection.", requestException); } log.error("Error connecting to messaging service. Check that the port is correct", requestException); - throw new SempException(requestException); + throw new PluginClientException("Error during SEMP Data Collection.", requestException); } return sempObject; } @@ -197,6 +198,7 @@ private void handlePagedSempResponse(List> list, private SempListResponse> getSempListResponse(Function uriMethod) throws com.fasterxml.jackson.core.JsonProcessingException { + String rawResponse = sempClient.getWebClient() .get() .uri(uriMethod) diff --git a/service/solace-plugin/src/test/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/SolaceSempClientTests.java b/service/solace-plugin/src/test/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/SolaceSempClientTests.java index c1c3eb03..8492b1c3 100644 --- a/service/solace-plugin/src/test/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/SolaceSempClientTests.java +++ b/service/solace-plugin/src/test/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/SolaceSempClientTests.java @@ -1,8 +1,8 @@ package com.solace.maas.ep.event.management.agent.plugin.solace.processor; +import com.solace.maas.ep.event.management.agent.plugin.exception.PluginClientException; import com.solace.maas.ep.event.management.agent.plugin.solace.SolaceTestConfig; import com.solace.maas.ep.event.management.agent.plugin.solace.processor.semp.SempClient; -import com.solace.maas.ep.event.management.agent.plugin.solace.processor.semp.SempException; import com.solace.maas.ep.event.management.agent.plugin.solace.processor.semp.SolaceHttpSemp; import lombok.SneakyThrows; import org.junit.jupiter.api.Assertions; @@ -153,7 +153,7 @@ public void throwBadRequestExceptionWhileGettingQueues() { .msgVpn("xyz") .build(); SolaceHttpSemp semp = new SolaceHttpSemp(mockSempClient); - SempException ex = Assertions.assertThrows(SempException.class, () -> { + PluginClientException ex = Assertions.assertThrows(PluginClientException.class, () -> { semp.getQueues(); }); assertEquals(400, ((WebClientResponseException) ex.getCause()).getStatusCode().value()); @@ -173,7 +173,7 @@ public void throwUnauthorizedExceptionWhileGettingQueues() { .msgVpn("xyz") .build(); SolaceHttpSemp semp = new SolaceHttpSemp(mockSempClient); - SempException ex = Assertions.assertThrows(SempException.class, () -> { + PluginClientException ex = Assertions.assertThrows(PluginClientException.class, () -> { semp.getQueues(); }); assertEquals(401, ((WebClientResponseException) ex.getCause()).getStatusCode().value()); From e9487b329696adcaeed45a940df462b2ab9ade80 Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Thu, 18 Jan 2024 17:07:11 -0500 Subject: [PATCH 03/11] Minor code cleanup --- .../agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java index 827fd588..5a3bd8eb 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/route/ep/ScanStatusFailedPersistenceRouteBuilder.java @@ -21,6 +21,5 @@ public void configure() throws Exception { from("direct:processScanStatusAsFailed") .process(routeFailedProcessor); - // .to("direct:perRouteScanStatusPublisher?block=false&failIfNoConsumers=false"); } } From ae10ec56af0300bf1e5dd5f85cfa2e1d4dd339fa Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Thu, 18 Jan 2024 17:08:02 -0500 Subject: [PATCH 04/11] Remove unused code --- .../management/agent/scanManager/ScanResponse.java | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 service/application/src/main/java/com/solace/maas/ep/event/management/agent/scanManager/ScanResponse.java diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/scanManager/ScanResponse.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/scanManager/ScanResponse.java deleted file mode 100644 index 8dc77e34..00000000 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/scanManager/ScanResponse.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.solace.maas.ep.event.management.agent.scanManager; - -import lombok.Builder; -import lombok.Data; - -import java.util.List; - -@Data -@Builder -public class ScanResponse { - private String id; - private List scanTypes; -} From e4b598eba1497f9e11a568897548452683cbd5be Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Thu, 18 Jan 2024 17:17:40 -0500 Subject: [PATCH 05/11] Update the way Exceptions are created --- .../agent/service/ScanStatusService.java | 2 +- .../client/KafkaClientManagerImpl.java | 2 +- .../exception/PluginClientException.java | 19 +++++++++++++++++++ .../solace/processor/semp/SolaceHttpSemp.java | 14 +++++++------- 4 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/exception/PluginClientException.java diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java index 5249e95b..c846b2bf 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java @@ -56,7 +56,7 @@ public ScanStatusEntity save(String name, String scanId, ScanStatus scanStatus) @Transactional public List getScanStatuses(String scanId) { ScanEntity scanEntity = scanService.findById(scanId) - .orElseThrow(() -> new RuntimeException("Scan not found!")); + .orElseThrow(() -> new RuntimeException("ScanId " + scanId + " not found!")); List scanStatuses = scanEntity.getScanTypes().stream() .map(ScanTypeEntity::getStatus) .toList(); diff --git a/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/manager/client/KafkaClientManagerImpl.java b/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/manager/client/KafkaClientManagerImpl.java index eb25eef9..8ca3c5e1 100644 --- a/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/manager/client/KafkaClientManagerImpl.java +++ b/service/kafka-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/manager/client/KafkaClientManagerImpl.java @@ -66,7 +66,7 @@ public AdminClient getClient(ConnectionDetailsEvent connectionDetailsEvent) { } catch (KafkaException e) { log.error("Could not create Kafka admin client for messaging service {}. Error: {}, cause: {}", connectionDetailsEvent.getMessagingServiceId(), e.getMessage(), String.valueOf(e.getCause())); - throw new PluginClientException(e.getMessage(), e); + throw new PluginClientException(e); } } diff --git a/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/exception/PluginClientException.java b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/exception/PluginClientException.java new file mode 100644 index 00000000..a7b82292 --- /dev/null +++ b/service/plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/exception/PluginClientException.java @@ -0,0 +1,19 @@ +package com.solace.maas.ep.event.management.agent.plugin.exception; + +public class PluginClientException extends RuntimeException { + public PluginClientException() { + super(); + } + + public PluginClientException(String message, Exception e) { + super(message, e); + } + + public PluginClientException(String message) { + super(message); + } + + public PluginClientException(Exception ex) { + super(ex); + } +} diff --git a/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java b/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java index 9cfd3e51..f9e313dd 100644 --- a/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java +++ b/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java @@ -81,7 +81,7 @@ private Map getResultsFlatFromSemp(String uriPath) { return getSempFlatRequest(createFlatUriBuilderFunction(uriPath, Collections.emptyMap())); } catch (IOException ioException) { log.error("Error during SEMP Data Collection", ioException); - throw new PluginClientException("Error during SEMP Data Collection", ioException); + throw new PluginClientException(ioException); } } @@ -102,25 +102,25 @@ private List> getResultsListMapFromSemp(String uriPath, if (ex.getStatusCode() == BAD_REQUEST) { log.error("Error during SEMP Data Collection. Invalid path to data." + " Check that the SEMP URL and protocol are correct.", ex); - throw new PluginClientException("Error during SEMP Data Collection.", ex); + throw new PluginClientException(ex); } else if (ex.getStatusCode() == UNAUTHORIZED) { log.error("Error during SEMP Data Collection. Could not authenticate with the server." + "Check that the SEMP username and password are correct.", ex); - throw new PluginClientException("Error during SEMP Data Collection.", ex); + throw new PluginClientException(ex); } else { log.error("Error during SEMP Data Collection.", ex); - throw new PluginClientException("Error during SEMP Data Collection.", ex); + throw new PluginClientException(ex); } } catch (IOException ioException) { log.error("Error during SEMP Data Collection. The format of the collected data is unexpected.", ioException); - throw new PluginClientException("Error during SEMP Data Collection.", ioException); + throw new PluginClientException(ioException); } catch (WebClientRequestException requestException) { if (requestException.getMessage().startsWith("Failed to resolve")) { log.error("Error connecting to messaging service. Check that the hostname is correct.", requestException); - throw new PluginClientException("Error during SEMP Data Collection.", requestException); + throw new PluginClientException(requestException); } log.error("Error connecting to messaging service. Check that the port is correct", requestException); - throw new PluginClientException("Error during SEMP Data Collection.", requestException); + throw new PluginClientException(requestException); } return sempObject; } From 24f080db2f9ad7eb989876631f4b40edc8a5ff2a Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Thu, 18 Jan 2024 17:23:10 -0500 Subject: [PATCH 06/11] Additional code cleanup --- .../ep/event/management/agent/service/ScanStatusService.java | 5 ----- .../agent/processor/RouteCompleteProcessorTests.java | 3 ++- .../management/agent/service/ScanStatusServiceTests.java | 4 ++-- .../agent/plugin/solace/processor/semp/SolaceHttpSemp.java | 1 - 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java index c846b2bf..17456ecc 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/service/ScanStatusService.java @@ -28,11 +28,6 @@ public ScanStatusService(ScanStatusRepository repository, ScanTypeService scanTy this.idGenerator = idGenerator; } - @Transactional - public ScanStatusEntity save(String name, String scanId) { - return save(name, scanId, ScanStatus.COMPLETE); - } - @Transactional public ScanStatusEntity save(String name, String scanId, ScanStatus scanStatus) { ScanTypeEntity scanType = scanTypeService.findByNameAndScanId(name, scanId) diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorTests.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorTests.java index 6a72d466..a46d3c5a 100644 --- a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorTests.java +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorTests.java @@ -2,6 +2,7 @@ import com.solace.maas.ep.event.management.agent.TestConfig; import com.solace.maas.ep.event.management.agent.plugin.constants.RouteConstants; +import com.solace.maas.ep.event.management.agent.plugin.constants.ScanStatus; import com.solace.maas.ep.event.management.agent.repository.model.scan.ScanStatusEntity; import com.solace.maas.ep.event.management.agent.service.ScanStatusService; import lombok.SneakyThrows; @@ -52,7 +53,7 @@ public void testRouteCompleteProcessor() { exchange.getIn().setBody("test exchange"); - when(scanStatusService.save(any(String.class), any(String.class))) + when(scanStatusService.save(any(String.class), any(String.class), any(ScanStatus.class))) .thenReturn(ScanStatusEntity.builder().build()); routeCompleteProcessor.process(exchange); diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/service/ScanStatusServiceTests.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/service/ScanStatusServiceTests.java index 7d92bba7..a5a4305b 100644 --- a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/service/ScanStatusServiceTests.java +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/service/ScanStatusServiceTests.java @@ -52,7 +52,7 @@ public void testSaveWithScanStatus() { when(scanStatusRepository.save(any(ScanStatusEntity.class))) .thenReturn(ScanStatusEntity.builder().build()); - scanStatusService.save("name", "scanId"); + scanStatusService.save("name", "scanId", ScanStatus.COMPLETE); assertThatNoException(); } @@ -73,7 +73,7 @@ public void testSaveWithoutScanStatus() { when(scanStatusRepository.save(any(ScanStatusEntity.class))) .thenReturn(ScanStatusEntity.builder().build()); - scanStatusService.save("name", "scanId"); + scanStatusService.save("name", "scanId", ScanStatus.COMPLETE); assertThatNoException(); } diff --git a/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java b/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java index f9e313dd..cbaa914f 100644 --- a/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java +++ b/service/solace-plugin/src/main/java/com/solace/maas/ep/event/management/agent/plugin/solace/processor/semp/SolaceHttpSemp.java @@ -198,7 +198,6 @@ private void handlePagedSempResponse(List> list, private SempListResponse> getSempListResponse(Function uriMethod) throws com.fasterxml.jackson.core.JsonProcessingException { - String rawResponse = sempClient.getWebClient() .get() .uri(uriMethod) From 467f9d3661dd124ba27fa1f7f8bd6be4a6335321 Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Thu, 18 Jan 2024 17:35:01 -0500 Subject: [PATCH 07/11] More code cleanup --- .../maas/ep/event/management/agent/cli/EmaCommandLine.java | 1 - 1 file changed, 1 deletion(-) diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java index 08f4553a..0f7bcaf6 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java @@ -152,7 +152,6 @@ private void writeScanToZipFile(String filePathAndName, String scanId) throws IO log.info("Received zip request for scan id: {}", zipRequestBO.getScanId()); try (InputStream fileStream = importService.zip(zipRequestBO)) { - // Write the input stream to a file in the /tmp directory File file = new File(filePathAndName); writeInputStreamToFile(fileStream, file); } From c82f2fe87ad016e9da03c3be239328b67ef5c0c9 Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Fri, 19 Jan 2024 11:21:56 -0500 Subject: [PATCH 08/11] Improve tests --- .../management/agent/cli/EmaCommandLine.java | 2 +- .../management/agent/cli/CliScanTest.java | 50 +++++++++++++-- .../processor/RouteFailureProcessorTests.java | 64 +++++++++++++++++++ 3 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteFailureProcessorTests.java diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java index 0f7bcaf6..5ec560aa 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java @@ -63,7 +63,7 @@ public void run(String... args) throws Exception { log.error("Unknown command: {}", type); } } else { - log.info(" arguments passed to the application."); + log.error("Not enough arguments passed to the application."); } } diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java index e1918291..1542b5de 100644 --- a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java @@ -1,23 +1,34 @@ package com.solace.maas.ep.event.management.agent.cli; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; import com.solace.maas.ep.event.management.agent.TestConfig; import com.solace.maas.ep.event.management.agent.repository.model.file.DataCollectionFileEntity; import com.solace.maas.ep.event.management.agent.repository.model.mesagingservice.MessagingServiceEntity; import com.solace.maas.ep.event.management.agent.repository.model.scan.ScanEntity; +import com.solace.maas.ep.event.management.agent.scanManager.model.ZipRequestBO; import com.solace.maas.ep.event.management.agent.service.DataCollectionFileService; import com.solace.maas.ep.event.management.agent.service.ImportService; import com.solace.maas.ep.event.management.agent.service.ScanService; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; import java.util.Optional; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; @ActiveProfiles({"SCANTEST", "TEST"}) @@ -36,19 +47,50 @@ public class CliScanTest { @Autowired private DataCollectionFileService dataCollectionFileService; + private ListAppender listAppender; + + @BeforeEach + + public void setUp() { + Logger logger = (Logger) LoggerFactory.getLogger(EmaCommandLine.class); + listAppender = new ListAppender<>(); + listAppender.start(); + logger.addAppender(listAppender); + } + @Test public void testCLICommand() throws Exception { - when(scanService.findById(any())).thenReturn(Optional.of(ScanEntity.builder() + when(scanService.singleScan(any(), any(), any(), any(), any(), any(MessagingServiceEntity.class), anyString())).thenReturn("xyz"); + when(scanService.findById(anyString())).thenReturn(Optional.of(ScanEntity.builder() .id("abcdef") .messagingService(MessagingServiceEntity.builder() .id("bbbbbb") .build()) .build())); - when(dataCollectionFileService.findAllByScanId(any())).thenReturn( + when(dataCollectionFileService.findAllByScanId(anyString())).thenReturn( List.of(DataCollectionFileEntity.builder() .path("a/b/c") .build())); - when(importService.zip(any())).thenReturn(new ByteArrayInputStream("test".getBytes(StandardCharsets.UTF_8))); - emaCommandLine.run("scan", "abcdef", "/tmp/scan.txt"); + String fileContent = "test"; + when(importService.zip(any(ZipRequestBO.class))).thenReturn(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8))); + + String scanOutputFile = "/tmp/scan.txt"; + emaCommandLine.run("scan", "abcdef", scanOutputFile); + + List logsList = listAppender.list; + assertTrue(logsList.get(1).getFormattedMessage().contains("Scan request [xyz]: Scan started.")); + assertTrue(logsList.get(2).getFormattedMessage().contains("Scan request [xyz]: Scan completed successfully.")); + assertTrue(logsList.get(3).getFormattedMessage().contains("Received zip request for scan id: xyz")); + + String content = Files.readString(Path.of(scanOutputFile), StandardCharsets.UTF_8); + assertEquals(fileContent, content); + } + + @Test + public void testCLICommandMissingParams() throws Exception { + when(scanService.findById(any())).thenReturn(Optional.empty()); + emaCommandLine.run("scan", "abcdef"); + + assertTrue(listAppender.list.get(0).getFormattedMessage().contains("Not enough arguments passed to the application.")); } } \ No newline at end of file diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteFailureProcessorTests.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteFailureProcessorTests.java new file mode 100644 index 00000000..19863f7f --- /dev/null +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteFailureProcessorTests.java @@ -0,0 +1,64 @@ +package com.solace.maas.ep.event.management.agent.processor; + +import com.solace.maas.ep.event.management.agent.TestConfig; +import com.solace.maas.ep.event.management.agent.plugin.constants.RouteConstants; +import com.solace.maas.ep.event.management.agent.plugin.constants.ScanStatus; +import com.solace.maas.ep.event.management.agent.repository.model.scan.ScanStatusEntity; +import com.solace.maas.ep.event.management.agent.service.ScanStatusService; +import lombok.SneakyThrows; +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.support.DefaultExchange; +import org.junit.Rule; +import org.junit.jupiter.api.Test; +import org.junit.rules.ExpectedException; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@ActiveProfiles("TEST") +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = TestConfig.class) +public class RouteFailureProcessorTests { + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Autowired + CamelContext camelContext; + + @Mock + ScanStatusService scanStatusService; + + @InjectMocks + RouteFailedProcessorImpl routeFailedProcessor; + + @SneakyThrows + @Test + public void testRouteCompleteProcessor() { + Exchange exchange = new DefaultExchange(camelContext); + exchange.getIn().setHeader(RouteConstants.SCAN_ID, "scanId"); + exchange.getIn().setHeader(RouteConstants.SCAN_TYPE, "scanType"); + exchange.getIn().setHeader(RouteConstants.SCHEDULE_ID, "groupId"); + exchange.getIn().setHeader(RouteConstants.MESSAGING_SERVICE_ID, "messagingServiceId"); + + exchange.getIn().setBody("test exchange"); + + when(scanStatusService.save(any(String.class), any(String.class), any(ScanStatus.class))) + .thenReturn(ScanStatusEntity.builder().build()); + + routeFailedProcessor.process(exchange); + + assertThatNoException(); + + exchange.setProperty(Exchange.EXCEPTION_CAUGHT, new Exception()); + routeFailedProcessor.process(exchange); + + exception.expect(Exception.class); + } +} \ No newline at end of file From 78bdb5868294fce60b6ea26f464bd91207263903 Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Fri, 19 Jan 2024 11:46:05 -0500 Subject: [PATCH 09/11] Suppress duplicate warnings in tests --- .../management/agent/processor/RouteCompleteProcessorTests.java | 1 + .../management/agent/processor/RouteFailureProcessorTests.java | 1 + 2 files changed, 2 insertions(+) diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorTests.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorTests.java index a46d3c5a..ca30bd57 100644 --- a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorTests.java +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteCompleteProcessorTests.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.when; @ActiveProfiles("TEST") +@SuppressWarnings("CPD-START") @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = TestConfig.class) public class RouteCompleteProcessorTests { diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteFailureProcessorTests.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteFailureProcessorTests.java index 19863f7f..68ad3dd4 100644 --- a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteFailureProcessorTests.java +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/processor/RouteFailureProcessorTests.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.when; @ActiveProfiles("TEST") +@SuppressWarnings("CPD-START") @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = TestConfig.class) public class RouteFailureProcessorTests { From 6a19782dc7e3878847df46f7855c3e2e40e78658 Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Fri, 19 Jan 2024 16:56:58 -0500 Subject: [PATCH 10/11] Make sure the EmaCommandLine is only run when the web server is turned off --- .../maas/ep/event/management/agent/cli/EmaCommandLine.java | 2 ++ .../solace/maas/ep/event/management/agent/cli/CliScanTest.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java index 5ec560aa..f39c7d7a 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java @@ -12,6 +12,7 @@ import com.solace.maas.ep.event.management.agent.util.IDGenerator; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -25,6 +26,7 @@ @Component @Order(1) +@ConditionalOnProperty(name = "spring.main.web-application-type", havingValue = "none") @Slf4j public class EmaCommandLine implements CommandLineRunner { private final ScanManager scanManager; diff --git a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java index 1542b5de..c523b08c 100644 --- a/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java +++ b/service/application/src/test/java/com/solace/maas/ep/event/management/agent/cli/CliScanTest.java @@ -32,7 +32,8 @@ import static org.mockito.Mockito.when; @ActiveProfiles({"SCANTEST", "TEST"}) -@SpringBootTest(classes = TestConfig.class) +@SpringBootTest(classes = TestConfig.class, properties = {"spring.main.web-application-type=none", + "springdoc.api-docs.enabled=false"}) public class CliScanTest { @Autowired From ba06537c8d8a7b06c1b336fb0a8de5d591e70d06 Mon Sep 17 00:00:00 2001 From: Greg Meldrum Date: Fri, 19 Jan 2024 17:12:10 -0500 Subject: [PATCH 11/11] Address PR comment for using builder pattern --- .../ep/event/management/agent/cli/EmaCommandLine.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java index f39c7d7a..71368ec8 100644 --- a/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java +++ b/service/application/src/main/java/com/solace/maas/ep/event/management/agent/cli/EmaCommandLine.java @@ -72,11 +72,12 @@ public void run(String... args) throws Exception { private void runScan(String messagingServiceId, String filePathAndName) throws InterruptedException, IOException { MessagingServiceEntity messagingServiceEntity = messagingServiceDelegateService.getMessagingServiceById(messagingServiceId); - ScanRequestBO scanRequestBO = new ScanRequestBO(); - scanRequestBO.setMessagingServiceId(messagingServiceId); - scanRequestBO.setScanId(idGenerator.generateRandomUniqueId()); + ScanRequestBO scanRequestBO = ScanRequestBO.builder() + .messagingServiceId(messagingServiceId) + .scanId(idGenerator.generateRandomUniqueId()) + .destinations(List.of("FILE_WRITER")) + .build(); setScanType(messagingServiceEntity, scanRequestBO, messagingServiceId); - scanRequestBO.setDestinations(List.of("FILE_WRITER")); log.info("Scan request [{}]: Received, request details: {}", scanRequestBO.getScanId(), scanRequestBO); String scanId = scanManager.scan(scanRequestBO);