diff --git a/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java b/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java index 8dccef2d260b307126ed701e629ca68d488393b5..eafc17cd8b69b2b38513fac7e4d46c0ba28fac25 100644 --- a/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java +++ b/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java @@ -32,11 +32,11 @@ class ProcessorEventListener { private final ProcessorService processorService; private final ResultService resultService; private final ApplicationEventPublisher publisher; - + static final String PROCESS_VORGANG_ORDER = "PROCESS_VORGANG"; private static final String IS_PROCESS_VORGANG = "{T(de.ozgcloud.processor.processor.ProcessorEventListener).IS_PROCESS_VORGANG_EVENT.test(event.getSource())}"; public static final Predicate<Command> IS_PROCESS_VORGANG_EVENT = command -> command.getOrder().equals(PROCESS_VORGANG_ORDER); - + static final String COMMAND_PROCESSOR_NAMES_KEY = "processorNames"; @EventListener @@ -51,47 +51,51 @@ class ProcessorEventListener { handleError(e, event.getSource()); } } - + @EventListener(condition = IS_PROCESS_VORGANG) public void onCommandProcessVorgang(CommandCreatedEvent event) { try { var vorgang = getVorgang(event.getSource().getVorgangId()); processorService.processVorgang(vorgang, getProcessorNames(event.getSource())) - .forEach(processorResultMono -> processResult(processorResultMono, event.getSource().getVorgangId())); + .forEach(processorResultMono -> processResult(processorResultMono, event.getSource().getVorgangId())); publishCommandProcessedEvent(event.getSource()); - } catch(Exception e) { + } 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) { return service.getVorgang(VorgangId.from(vorgangId)); } - + @SuppressWarnings("unchecked") - private Collection<String> getProcessorNames(Command command) { - return (Collection<String>) MapUtils.getObject(command.getBodyObject(), COMMAND_PROCESSOR_NAMES_KEY, Collections.emptyList()); + Collection<String> getProcessorNames(Command command) { + var processorNames = MapUtils.getObject(command.getBodyObject(), COMMAND_PROCESSOR_NAMES_KEY, Collections.emptyList()); + if (processorNames instanceof String processorNamesStr) { + return Collections.singleton(processorNamesStr); + } + return (Collection<String>) processorNames; } - + private ProcessorResult addVorgangId(ProcessorResult result, String vorgangId) { return result.toBuilder().vorgangId(VorgangId.from(vorgangId)).build(); } - + private void handleError(Throwable cause, String vorgangId) { LOG.error("Error on procession Vorgang {} externally", vorgangId, cause); resultService.processError(cause, vorgangId); } - + void publishCommandProcessedEvent(Command command) { publisher.publishEvent(new VorgangProcessedEvent(command)); } - + void publishCommandFailedEvent(Throwable e, String commandId) { publisher.publishEvent(new CommandFailedEvent(commandId, e.getMessage())); } diff --git a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java index 125d0c067272b7d6cc10eba25c213d4395d3b42f..ae70a1bf68fa31bed6ea820c76d93b33725bda7d 100644 --- a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java +++ b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java @@ -6,6 +6,7 @@ import static org.mockito.Mockito.*; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Stream; @@ -54,70 +55,70 @@ class ProcessorEventListenerTest { @DisplayName("Trigger new vorgang processor") @Nested class TestTriggerNewVorgangProcessor { - + @Mock private ProcessorTechnicalException exception; - + @Captor private ArgumentCaptor<ProcessorResult> resultCaptor; - + private static final VorgangCreatedEvent EVENT = new VorgangCreatedEvent(OzgCloudVorgangTestFactory.ID.toString()); - + private Vorgang vorgang = VorgangTestFactory.create(); - + @BeforeEach void init() { when(vorgangService.getVorgang(any())).thenReturn(vorgang); - + var result = ProcessorResultTestFactory.createBuilder().vorgangId(null).build(); when(processorService.processVorgang(any())).thenReturn(Stream.of(Mono.just(result))); } - + @Test void shouldGetVorgang() { var expectedVorgangId = VorgangId.from(OzgCloudVorgangTestFactory.ID.toString()); - + vorgangEventListener.triggerNewVorgangProcessors(EVENT); - + verify(vorgangService).getVorgang(expectedVorgangId); } - + @Test void shouldCallProcessVorgang() { vorgangEventListener.triggerNewVorgangProcessors(EVENT); - + verify(processorService).processVorgang(vorgang); } - + @Test void shouldSetVorgangId() { vorgangEventListener.triggerNewVorgangProcessors(EVENT); - + verify(resultService).processResult(resultCaptor.capture()); assertThat(resultCaptor.getValue().getVorgangId()).isEqualTo(VorgangTestFactory.ID); } - + @Test void shouldCallConsumeException() { when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.create()); when(processorService.processVorgang(any())).thenReturn(Stream.of(Mono.error(exception))); - + vorgangEventListener.triggerNewVorgangProcessors(EVENT); - + verify(resultService).processError(exception, VorgangTestFactory.ID.toString()); } - + @Test void shouldCallConsumeUnexpectedExceptionType() { when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.create()); when(processorService.processVorgang(any())).thenReturn(Stream.of(Mono.error(new Exception()))); - + vorgangEventListener.triggerNewVorgangProcessors(EVENT); - + verify(resultService).processError(any(Exception.class), eq(VorgangTestFactory.ID.toString())); } } - + @DisplayName("On command processVorgang") @Nested class TestOnCommandProcessVorgang { @@ -128,174 +129,200 @@ class ProcessorEventListenerTest { private ArgumentCaptor<CommandFailedEvent> commandFailedEventCaptor; @Captor private ArgumentCaptor<VorgangProcessedEvent> commandSuccessEventCaptor; - + private final Vorgang vorgang = VorgangTestFactory.create(); private final Collection<String> processorNames = List.of("dummy1", "dummy2"); - private final Command command = CommandTestFactory.createBuilder().bodyObject(Map.of(ProcessorEventListener.COMMAND_PROCESSOR_NAMES_KEY, processorNames)).build(); + private final Command command = CommandTestFactory.createBuilder() + .bodyObject(Map.of(ProcessorEventListener.COMMAND_PROCESSOR_NAMES_KEY, processorNames)).build(); private final CommandCreatedEvent event = new CommandCreatedEvent(command); - + @DisplayName("process flow") @Nested class TestProcessFlow { - - private final Mono<ProcessorResult> processorResults = Mono.just(ProcessorResultTestFactory.create()); + + 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.onCommandProcessVorgang(event); - + verify(vorgangService).getVorgang(VorgangId.from(CommandTestFactory.VORGANG_ID)); } - + @Test void shouldCallService() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(processorService).processVorgang(vorgang, processorNames); } - + @Test void shouldProcessResult() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(vorgangEventListener).processResult(any(), eq(CommandTestFactory.VORGANG_ID)); } - + @Test void shouldPublishCommandProcessedEvent() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(vorgangEventListener).publishCommandProcessedEvent(event.getSource()); } } - + + @DisplayName("get processorNames") + @Nested + class TestGetProcessorNames { + + @Test + void shouldReturnSingletonList() { + var processorNames = vorgangEventListener.getProcessorNames(createCommand("singleName")); + + assertThat(processorNames).isInstanceOf(Collection.class).containsExactly("singleName"); + } + + @Test + void shouldReturnList() { + var processorNames = vorgangEventListener.getProcessorNames(createCommand(List.of("name", "otherName"))); + + assertThat(processorNames).isInstanceOf(Collection.class).containsExactly("name", "otherName"); + } + + private Command createCommand(Object processorNames) { + var map = new HashMap<String, Object>(); + map.put(ProcessorEventListener.COMMAND_PROCESSOR_NAMES_KEY, processorNames); + return CommandTestFactory.createBuilder().bodyObject(map).build(); + } + } + @DisplayName("publish command processed event") @Nested class TestPublishCommandProcessedEvent { - + @BeforeEach - void init(){ + void init() { when(processorService.processVorgang(any(), any())).thenReturn(Stream.empty()); } - + @Test void shouldPublishEventBeClassOf() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); assertThat(commandSuccessEventCaptor.getValue().getClass()).isEqualTo(VorgangProcessedEvent.class); } - + @Test void shouldPublishEventHasCommanIdAsSource() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); assertThat(commandSuccessEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); } - + @Test void shouldPublishEventHasCommand() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); assertThat(commandSuccessEventCaptor.getValue().getCommand()).isEqualTo(command); } } - + @DisplayName("On ViolationConstraint exception") @Nested class TestOnViolationConstraintException { - - private final Mono<ProcessorResult> processorResults = Mono.just(ProcessorResultTestFactory.create()); + + private final Mono<ProcessorResult> processorResults = Mono.just(ProcessorResultTestFactory.create()); private final Stream<Mono<ProcessorResult>> monoStream = Stream.of(processorResults); private final ConstraintViolationException exception = new ConstraintViolationException("", Collections.emptySet()); - + @BeforeEach - void init(){ + void init() { when(vorgangService.getVorgang(any())).thenReturn(vorgang); when(processorService.processVorgang(any(), any())).thenReturn(monoStream); doThrow(exception).when(vorgangEventListener).processResult(any(), any()); doNothing().when(vorgangEventListener).publishCommandFailedEvent(any(), any()); } - + @Test void shouldProcessError() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(resultService).processError(any(), eq(CommandTestFactory.VORGANG_ID)); } - + @Test void shouldPublishEventOnConstraintException() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(vorgangEventListener).publishCommandFailedEvent(any(), any()); } } - + @DisplayName("on process vorgang exception") @Nested class TestOnProcessVorgangException { - + @BeforeEach - void init(){ + void init() { when(processorService.processVorgang(any(), any())).thenReturn(Stream.of(Mono.error(exception))); } - + @Test void shouldProcessError() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(vorgangEventListener).publishCommandFailedEvent(any(), any()); } - + @Test void shouldPublishCommandFailedEvent() { vorgangEventListener.onCommandProcessVorgang(event); - + verify(resultService).processError(any(), eq(CommandTestFactory.VORGANG_ID)); } } - + @DisplayName("publish command failed event") @Nested class TestPublishCommandFailedEvent { - + private final static String ERROR_MSG = "ErrorMsg"; - + @BeforeEach - void init(){ + 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); } - + @Test void shouldPublishEventHasCommanIdAsSource() { vorgangEventListener.publishCommandFailedEvent(exception, CommandTestFactory.ID); - + verify(publisher).publishEvent(commandFailedEventCaptor.capture()); assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); } - + @Test void shouldPublishEventHasErrorMessage() { vorgangEventListener.publishCommandFailedEvent(exception, CommandTestFactory.ID); - + verify(publisher).publishEvent(commandFailedEventCaptor.capture()); assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isEqualTo(ERROR_MSG); }