diff --git a/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java b/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java index a5056754a9c4164f4e86bca353aea208fdb9f259..21b0b117a60d998a3dede794eacc7799d58f6ce7 100644 --- a/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java +++ b/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java @@ -20,6 +20,7 @@ import de.ozgcloud.processor.vorgang.VorgangId; import de.ozgcloud.processor.vorgang.VorgangService; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; +import reactor.core.publisher.Mono; @Component("processorVorgangEventListener") @ConditionalOnProperty(prefix = "ozgcloud.processors[0]", name = "address") @@ -46,12 +47,10 @@ class ProcessorEventListener { .doOnError(cause -> handleError(cause, event.getSource())).onErrorComplete() .map(result -> addVorgangId(result, event.getSource())) .subscribe(resultService::processResult)); - } catch (RuntimeException e) { + } catch (RuntimeException e) { //TODO Test handleError(e, event.getSource()); } } - - private void handleError(Throwable cause, String vorgangId) { LOG.error("Error on procession Vorgang {} externally", vorgangId, cause); @@ -60,12 +59,20 @@ class ProcessorEventListener { @EventListener(condition = IS_EXECUTE_PROCESSOR) public void onCommandExecuteProcessor(CommandCreatedEvent event) { - var vorgang = getVorgang(event.getSource().getVorgangId()); - processorService.processVorgang(vorgang, getProcessorNames(event.getSource())).forEach(processorResultMono -> processorResultMono - .doOnError(cause -> publishCommandFailedEvent(cause, event.getSource().getId())).onErrorComplete() - .map(result -> addVorgangId(result, event.getSource().getVorgangId())) - .subscribe(resultService::processResult)); - publishCommandProcessedEvent(event.getSource()); + try { + var vorgang = getVorgang(event.getSource().getVorgangId()); + processorService.processVorgang(vorgang, getProcessorNames(event.getSource())) + .forEach(processorResultMono -> processResult(processorResultMono, event.getSource().getVorgangId())); + publishCommandProcessedEvent(event.getSource()); + } catch(Exception e) { + handleError(e, event.getSource().getVorgangId()); + publishCommandFailedEvent(e.getCause(), event.getSource().getId()); + } + } + + void processResult(Mono<ProcessorResult> processorResultMono, String vorgangId) { + var blockedResult = processorResultMono.map(result -> addVorgangId(result, vorgangId)).block(); + resultService.processResult(blockedResult); } private Vorgang getVorgang(String vorgangId) { @@ -81,11 +88,11 @@ class ProcessorEventListener { return result.toBuilder().vorgangId(VorgangId.from(vorgangId)).build(); } - private void publishCommandFailedEvent(Throwable e, String commandId) { + void publishCommandFailedEvent(Throwable e, String commandId) { publisher.publishEvent(new CommandFailedEvent(commandId, e.getMessage())); } - private void publishCommandProcessedEvent(Command command) { + void publishCommandProcessedEvent(Command command) { publisher.publishEvent(new CommandProcessedEvent(command)); } } \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerITCase.java b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerITCase.java index 4af9233cf8f5a6c413fbf9fa0b8698f6f3c0c0a7..2534b6e80ae3317e6c4ef24b558eea507f614688 100644 --- a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerITCase.java +++ b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerITCase.java @@ -50,15 +50,11 @@ class ProcessorEventListenerITCase { @Test void shouldTriggerForExecuteProcessor() { - publishCommandCreatedEvent(ProcessorEventListener.EXECUTE_PROCESS_ORDER); + var command = CommandTestFactory.createBuilder().order(ProcessorEventListener.EXECUTE_PROCESS_ORDER).build(); + + publisher.publishEvent(new CommandCreatedEvent(command)); verify(service).getVorgang(VorgangId.from(OzgCloudVorgangTestFactory.ID.toString())); } } - - private void publishCommandCreatedEvent(String order) { - var command = CommandTestFactory.createBuilder().order(order).build(); - - publisher.publishEvent(new CommandCreatedEvent(command)); - } } diff --git a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java index 47553f7bc314796602317b36eafe69dcaebc5fee..49ebd9fccf6809860c2967b97b9493786c5c1b09 100644 --- a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java +++ b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java @@ -33,7 +33,7 @@ import de.ozgcloud.processor.vorgang.Vorgang; import de.ozgcloud.processor.vorgang.VorgangId; import de.ozgcloud.processor.vorgang.VorgangService; import de.ozgcloud.processor.vorgang.VorgangTestFactory; -import lombok.SneakyThrows; +import jakarta.validation.ConstraintViolationException; import reactor.core.publisher.Mono; class ProcessorEventListenerTest { @@ -109,8 +109,7 @@ class ProcessorEventListenerTest { @Test void shouldCallConsumeUnexpectedExceptionType() { - var vorgang = VorgangTestFactory.create(); - when(vorgangService.getVorgang(any())).thenReturn(vorgang); + when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.create()); when(processorService.processVorgang(any())).thenReturn(Stream.of(Mono.error(new Exception()))); vorgangEventListener.triggerNewVorgangProcessors(EVENT); @@ -121,7 +120,7 @@ class ProcessorEventListenerTest { @DisplayName("On command executeProcessor") @Nested - class TestOnCommandExecuteProcessor{ + class TestOnCommandExecuteProcessor { @Mock private Throwable exception; @@ -135,51 +134,165 @@ class ProcessorEventListenerTest { private final Command command = CommandTestFactory.createBuilder().bodyObject(Map.of(ProcessorEventListener.COMMAND_PROCESSOR_NAMES_KEY, processorNames)).build(); private final CommandCreatedEvent event = new CommandCreatedEvent(command); - @BeforeEach - void init() { - when(vorgangService.getVorgang(any())).thenReturn(vorgang); + @DisplayName("process flow") + @Nested + class TestProcessFlow { + + private final Mono<ProcessorResult> processorResults = Mono.just(ProcessorResultTestFactory.create()); + private final Stream<Mono<ProcessorResult>> monoStream = Stream.of(processorResults); + + @BeforeEach + void init() { + when(vorgangService.getVorgang(any())).thenReturn(vorgang); + when(processorService.processVorgang(any(), any())).thenReturn(monoStream); + } + + @Test + void shouldGetVorgang() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(vorgangService).getVorgang(VorgangTestFactory.ID); + } + + @Test + void shouldCallService() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(processorService).processVorgang(vorgang, processorNames); + } + + @Test + void shouldProcessResult() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(vorgangEventListener).processResult(any(), eq(VorgangTestFactory.ID.toString())); + } + + @Test + void shouldPublishCommandProcessedEvent() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(vorgangEventListener).publishCommandProcessedEvent(event.getSource()); + } } - @Test - void shouldGetVorgang() { - vorgangEventListener.onCommandExecuteProcessor(event); + @DisplayName("publish command processed event") + @Nested + class TestPublishCommandProcessedEvent { + + @BeforeEach + void init(){ + when(processorService.processVorgang(any(), any())).thenReturn(Stream.empty()); + } - verify(vorgangService).getVorgang(VorgangTestFactory.ID); + @Test + void shouldPublishEventBeClassOf() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); + assertThat(commandSuccessEventCaptor.getValue().getClass()).isEqualTo(CommandProcessedEvent.class); + } + + @Test + void shouldPublishEventHasCommanIdAsSource() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); + assertThat(commandSuccessEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); + } + + @Test + void shouldPublishEventHasCommand() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); + assertThat(commandSuccessEventCaptor.getValue().getCommand()).isEqualTo(command); + } } - @Test - void shouldCallService() { - vorgangEventListener.onCommandExecuteProcessor(event); + @Disabled("FIXME: Er geht nicht in den catch block rein") + @DisplayName("On ViolationConstraint exception") + @Nested + class TestOnViolationConstraintException { + + @BeforeEach + void init(){ + doThrow(ConstraintViolationException.class).when(resultService).processResult(any()); + } - verify(processorService).processVorgang(vorgang, processorNames); + @Test + void shouldProcessError() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(resultService).processError(any(), eq(VorgangTestFactory.ID.toString())); + } + + @Test + void shouldPublishEventOnConstraintException() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(vorgangEventListener).publishCommandFailedEvent(any(), any()); + } } - @Test - @SneakyThrows - void shouldPublishCommandFailedEvent() { - var errorMsg = "ErrorMsg"; - when(exception.getMessage()).thenReturn(errorMsg); - when(processorService.processVorgang(any(), any())).thenReturn(Stream.of(Mono.error(exception))); - - vorgangEventListener.onCommandExecuteProcessor(event); - - verify(publisher).publishEvent(commandFailedEventCaptor.capture()); - assertThat(commandFailedEventCaptor.getValue().getClass()).isEqualTo(CommandFailedEvent.class); - assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); - assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isEqualTo(errorMsg); + @DisplayName("on process vorgang exception") + @Nested + class TestOnProcessVorgangException { + + @BeforeEach + void init(){ + when(processorService.processVorgang(any(), any())).thenReturn(Stream.of(Mono.error(exception))); + } + + @Test + void shouldProcessError() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(vorgangEventListener).publishCommandFailedEvent(any(), any()); + } + + @Test + void shouldPublishCommandFailedEvent() { + vorgangEventListener.onCommandExecuteProcessor(event); + + verify(resultService).processError(any(), eq(VorgangTestFactory.ID.toString())); + } } - @Disabled - @Test - @SneakyThrows - void shouldPublishCommandProcessedEvent() { - when(processorService.processVorgang(any(), any())).thenReturn(Stream.empty()); + @DisplayName("publish command failed event") + @Nested + class TestPublishCommandFailedEvent { + + private final static String ERROR_MSG = "ErrorMsg"; + + @BeforeEach + void init(){ + when(exception.getMessage()).thenReturn(ERROR_MSG); + } + + @Test + void shouldPublishEventBeClassOf() { + vorgangEventListener.publishCommandFailedEvent(exception, CommandTestFactory.ID); + + verify(publisher).publishEvent(commandFailedEventCaptor.capture()); + assertThat(commandFailedEventCaptor.getValue().getClass()).isEqualTo(CommandFailedEvent.class); + } - vorgangEventListener.onCommandExecuteProcessor(event); + @Test + void shouldPublishEventHasCommanIdAsSource() { + vorgangEventListener.publishCommandFailedEvent(exception, CommandTestFactory.ID); + + verify(publisher).publishEvent(commandFailedEventCaptor.capture()); + assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); + } - verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); - assertThat(commandFailedEventCaptor.getValue().getClass()).isEqualTo(CommandProcessedEvent.class); - assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(command); + @Test + void shouldPublishEventHasErrorMessage() { + vorgangEventListener.publishCommandFailedEvent(exception, CommandTestFactory.ID); + + verify(publisher).publishEvent(commandFailedEventCaptor.capture()); + assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isEqualTo(ERROR_MSG); + } } } } \ No newline at end of file