diff --git a/lombok.config b/lombok.config index e955a6b5b3b394bbae6458ecf7ac76f3b1b0f446..89d6230792835a66972d94928d8053e014e4fd16 100644 --- a/lombok.config +++ b/lombok.config @@ -28,4 +28,5 @@ lombok.log.log4j.flagUsage = ERROR lombok.data.flagUsage = ERROR lombok.nonNull.exceptionType = IllegalArgumentException lombok.addLombokGeneratedAnnotation = true -lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier \ No newline at end of file +lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier +lombok.copyableAnnotations += net.devh.boot.grpc.client.inject.GrpcClient \ No newline at end of file diff --git a/pom.xml b/pom.xml index bb7d3fc760eb515e4fa7e018ed2d18407d981dd6..5f780fa5e20615a00473653dcc615e75f85f3188 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ <parent> <groupId>de.ozgcloud.common</groupId> <artifactId>ozgcloud-common-parent</artifactId> - <version>4.9.0</version> + <version>4.10.0</version> </parent> <groupId>de.ozgcloud.processor</groupId> @@ -43,7 +43,7 @@ <description>OZG-Cloud Processor Manager</description> <properties> - <vorgang-manager.version>2.17.0</vorgang-manager.version> + <vorgang-manager.version>2.25.0-SNAPSHOT</vorgang-manager.version> <api-lib.version>0.13.0</api-lib.version> <tyrus-standalone-client.version>2.2.0</tyrus-standalone-client.version> <okio.version>3.9.1</okio.version> @@ -85,6 +85,16 @@ <groupId>org.springframework</groupId> <artifactId>spring-webflux</artifactId> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-json</artifactId> + </dependency> + + <!-- commons --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> <!-- test --> <dependency> @@ -132,12 +142,6 @@ <scope>test</scope> </dependency> - <!-- commons --> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - </dependency> - </dependencies> <build> diff --git a/src/main/java/de/ozgcloud/processor/command/Command.java b/src/main/java/de/ozgcloud/processor/command/Command.java new file mode 100644 index 0000000000000000000000000000000000000000..e517c170a8f9006deafe4e91d1afcbfe59d582d5 --- /dev/null +++ b/src/main/java/de/ozgcloud/processor/command/Command.java @@ -0,0 +1,15 @@ +package de.ozgcloud.processor.command; + +import de.ozgcloud.processor.vorgang.VorgangId; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class Command { + + private String id; + private String order; + + private VorgangId vorgangId; +} diff --git a/src/main/java/de/ozgcloud/processor/command/CommandRemoteService.java b/src/main/java/de/ozgcloud/processor/command/CommandRemoteService.java new file mode 100644 index 0000000000000000000000000000000000000000..6daf9300ba18f90cd18bd2861a88a6116b2d1f4b --- /dev/null +++ b/src/main/java/de/ozgcloud/processor/command/CommandRemoteService.java @@ -0,0 +1,27 @@ +package de.ozgcloud.processor.command; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.command.GrpcGetCommandRequest; +import lombok.RequiredArgsConstructor; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@Service("processorManagerCommandService") +@RequiredArgsConstructor +class CommandRemoteService { + + @GrpcClient("command-manager") + private final CommandServiceBlockingStub commandServiceStub; + private final ProcessorManagerCommandMapper mapper; + + public Command getCommand(String id) { + var grpcCommand = commandServiceStub.getCommand(buildRequest(id)); + + return mapper.fromGrpc(grpcCommand); + } + + private GrpcGetCommandRequest buildRequest(String id) { + return GrpcGetCommandRequest.newBuilder().setId(id).build(); + } +} diff --git a/src/main/java/de/ozgcloud/processor/command/CommandService.java b/src/main/java/de/ozgcloud/processor/command/CommandService.java new file mode 100644 index 0000000000000000000000000000000000000000..61f293dd5f4b0f27fff79d344989f2ab91081e5a --- /dev/null +++ b/src/main/java/de/ozgcloud/processor/command/CommandService.java @@ -0,0 +1,16 @@ +package de.ozgcloud.processor.command; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; + +@Service("processorCommandService") +@RequiredArgsConstructor +public class CommandService { + + private final CommandRemoteService remoteService; + + public Command getCommand(String id) { + return remoteService.getCommand(id); + } +} diff --git a/src/main/java/de/ozgcloud/processor/command/ProcessorManagerCommandMapper.java b/src/main/java/de/ozgcloud/processor/command/ProcessorManagerCommandMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..10021f056eaf7b16f159b3fc3e3d6aedc891f163 --- /dev/null +++ b/src/main/java/de/ozgcloud/processor/command/ProcessorManagerCommandMapper.java @@ -0,0 +1,21 @@ +package de.ozgcloud.processor.command; + +import java.util.Objects; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import de.ozgcloud.processor.vorgang.VorgangId; +import de.ozgcloud.vorgang.grpc.command.GrpcCommand; + +@Mapper +interface ProcessorManagerCommandMapper { + + @Mapping(target = "order", source = "orderString") + Command fromGrpc(GrpcCommand command); + + default VorgangId fromString(String idString) { + return Objects.nonNull(idString) ? VorgangId.from(idString) : null; + } + +} diff --git a/src/main/java/de/ozgcloud/processor/event/EventService.java b/src/main/java/de/ozgcloud/processor/event/EventService.java new file mode 100644 index 0000000000000000000000000000000000000000..b13eb001772af0a636233c7aa613f03351123918 --- /dev/null +++ b/src/main/java/de/ozgcloud/processor/event/EventService.java @@ -0,0 +1,26 @@ +package de.ozgcloud.processor.event; + +import java.util.Map; +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import de.ozgcloud.processor.command.Command; + +@Service +public class EventService { + + private static final Map<String, String> STATUS_ORDER_TO_EVENT = Map.of( + "VORGANG_ANNEHMEN", "ANGENOMMEN", + "VORGANG_VERWERFEN", "VERWORFEN", + "VORGANG_ZURUECKHOLEN", "ZURUECKGEHOLT", + "VORGANG_BEARBEITEN", "BEARBEITUNG_BEGONNEN", + "VORGANG_BESCHEIDEN", "BESCHIEDEN", + "VORGANG_ZURUECKSTELLEN", "ZURUECKGESTELLT", + "VORGANG_ABSCHLIESSEN", "ABGESCHLOSSEN", + "VORGANG_WIEDEREROEFFNEN", "WIEDEREROEFFNET"); + + public Optional<String> getEventNameFromOrder(Command command) { + return Optional.ofNullable(STATUS_ORDER_TO_EVENT.get(command.getOrder())); + } +} diff --git a/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java b/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java index 5f8ac51fe140c015f7592cced1d9e922dfce6fe7..936a17a4cb42e82814e66128a15e68dd7ebaea3c 100644 --- a/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java +++ b/src/main/java/de/ozgcloud/processor/processor/ProcessorEventListener.java @@ -39,11 +39,15 @@ import de.ozgcloud.command.Command; import de.ozgcloud.command.CommandCreatedEvent; import de.ozgcloud.command.CommandFailedEvent; import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.command.status.StatusChangedEvent; import de.ozgcloud.processor.ProcessorManagerConfiguration; +import de.ozgcloud.processor.command.CommandService; +import de.ozgcloud.processor.event.EventService; import de.ozgcloud.processor.result.ResultService; import de.ozgcloud.processor.vorgang.Vorgang; import de.ozgcloud.processor.vorgang.VorgangId; import de.ozgcloud.processor.vorgang.VorgangService; +import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import reactor.core.publisher.Mono; @@ -54,6 +58,15 @@ import reactor.core.publisher.Mono; @Log4j2 class ProcessorEventListener { + public static final String PROCESS_VORGANG_ORDER = "PROCESS_VORGANG"; + public static final Predicate<Command> IS_PROCESS_VORGANG_EVENT = command -> command.getOrder().equals(PROCESS_VORGANG_ORDER); + + static final String COMMAND_PROCESSOR_NAMES_KEY = "processorNames"; + + private static final String IS_PROCESS_VORGANG = "{T(de.ozgcloud.processor.processor.ProcessorEventListener).IS_PROCESS_VORGANG_EVENT.test(event.getSource())}"; + + private static final String EVENT_NAME_CREATED = "VORGANG_CREATED"; + @Qualifier(ProcessorManagerConfiguration.VORGANG_SERVICE_NAME) // NOSONAR private final VorgangService service; @@ -63,47 +76,58 @@ class ProcessorEventListener { @Qualifier(ProcessorManagerConfiguration.RESULT_SERVICE_NAME) // NOSONAR 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); + private final CommandService commandService; + private final EventService eventService; - static final String COMMAND_PROCESSOR_NAMES_KEY = "processorNames"; + private final ApplicationEventPublisher publisher; @EventListener public void triggerNewVorgangProcessors(VorgangCreatedEvent event) { try { - var vorgang = getVorgang(event.getSource()); - processorService.processVorgang(vorgang).forEach(processorResultMono -> processorResultMono - .doOnError(cause -> handleError(cause, event.getSource())).onErrorComplete() - .map(result -> addVorgangId(result, event.getSource())) - .subscribe(resultService::processResult)); + processVorgang(VorgangId.from(event.getSource()), EVENT_NAME_CREATED); } catch (RuntimeException e) { - handleError(e, event.getSource()); + handleError(e, VorgangId.from(event.getSource())); } } + @EventListener + public void onStatusChange(StatusChangedEvent event) { + var command = commandService.getCommand(event.getSource()); + var eventName = eventService.getEventNameFromOrder(command); + + eventName.ifPresent(name -> processVorgang(command.getVorgangId(), name)); + } + + void processVorgang(@NonNull VorgangId vorgangId, String eventName) { + var vorgang = getVorgang(vorgangId).withEvent(eventName); + + processorService.processVorgang(vorgang, eventName) + .forEach(processorResultMono -> processorResultMono.doOnError(cause -> handleError(cause, vorgangId)) + .onErrorComplete() + .map(result -> addVorgangId(result, vorgangId)) + .subscribe(resultService::processResult)); + } + @EventListener(condition = IS_PROCESS_VORGANG) public void onCommandProcessVorgang(CommandCreatedEvent event) { try { - var vorgang = getVorgang(event.getSource().getVorgangId()); + var vorgang = getVorgang(VorgangId.from(event.getSource().getVorgangId())); processorService.processVorgang(vorgang, getProcessorNames(event.getSource())) - .forEach(processorResultMono -> processResult(processorResultMono, event.getSource().getVorgangId())); + .forEach(processorResultMono -> processResult(processorResultMono, VorgangId.from(event.getSource().getVorgangId()))); publishCommandProcessedEvent(event.getSource()); } catch (Exception e) { - handleError(e, event.getSource().getVorgangId()); + handleError(e, VorgangId.from(event.getSource().getVorgangId())); publishCommandFailedEvent(e.getCause(), event.getSource().getId()); } } - void processResult(Mono<ProcessorResult> processorResultMono, String vorgangId) { + void processResult(Mono<ProcessorResult> processorResultMono, VorgangId vorgangId) { var blockedResult = processorResultMono.map(result -> addVorgangId(result, vorgangId)).block(); resultService.processResult(blockedResult); } - private Vorgang getVorgang(String vorgangId) { - return service.getVorgang(VorgangId.from(vorgangId)); + private Vorgang getVorgang(VorgangId vorgangId) { + return service.getVorgang(vorgangId); } @SuppressWarnings("unchecked") @@ -115,11 +139,11 @@ class ProcessorEventListener { return (Collection<String>) processorNames; } - private ProcessorResult addVorgangId(ProcessorResult result, String vorgangId) { - return result.toBuilder().vorgangId(VorgangId.from(vorgangId)).build(); + private ProcessorResult addVorgangId(ProcessorResult result, VorgangId vorgangId) { + return result.toBuilder().vorgangId(vorgangId).build(); } - private void handleError(Throwable cause, String vorgangId) { + private void handleError(Throwable cause, VorgangId vorgangId) { try { LOG.error("Error on procession Vorgang {} externally", vorgangId, cause); resultService.processError(cause, vorgangId); diff --git a/src/main/java/de/ozgcloud/processor/processor/ProcessorProperties.java b/src/main/java/de/ozgcloud/processor/processor/ProcessorProperties.java index 51fe4ae61b818c4320bf1aa144647dd000795ec8..6ca5dcf5c03b1930dc0c4c9151ed570a26d5106e 100644 --- a/src/main/java/de/ozgcloud/processor/processor/ProcessorProperties.java +++ b/src/main/java/de/ozgcloud/processor/processor/ProcessorProperties.java @@ -23,9 +23,11 @@ */ package de.ozgcloud.processor.processor; +import java.util.Collections; import java.util.List; import java.util.Set; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -91,6 +93,11 @@ class ProcessorProperties { @AllArgsConstructor static class Form { + /** Events to trigger Processor for this Form */ + @NotEmpty + @Builder.Default + private Set<String> events = Collections.singleton("VORGANG_CREATED"); + @NotNull private String formEngineName; diff --git a/src/main/java/de/ozgcloud/processor/processor/ProcessorService.java b/src/main/java/de/ozgcloud/processor/processor/ProcessorService.java index ff4d2230dfaf2883bf85450f2c0ea065ad20e4a6..48e36fcea2876fa4235536db9c5a7a45700dd55a 100644 --- a/src/main/java/de/ozgcloud/processor/processor/ProcessorService.java +++ b/src/main/java/de/ozgcloud/processor/processor/ProcessorService.java @@ -45,8 +45,10 @@ import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.processor.ProcessorManagerConfiguration; import de.ozgcloud.processor.processor.ProcessorProperties.Form; import de.ozgcloud.processor.processor.ProcessorProperties.Processor; -import de.ozgcloud.processor.result.ProcessorTechnicalException; +import de.ozgcloud.processor.result.Action; +import de.ozgcloud.processor.result.AktennotizFactory; import de.ozgcloud.processor.vorgang.Vorgang; +import de.ozgcloud.processor.vorgang.VorgangId; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import reactor.core.publisher.Mono; @@ -61,21 +63,26 @@ public class ProcessorService { @Qualifier(ProcessorManagerConfiguration.PROCESSOR_PROPERTIES_NAME) // NOSONAR private final ProcessorProperties properties; + private final AktennotizFactory aktennotizFactory; private final WebClient webClient; - public Stream<Mono<ProcessorResult>> processVorgang(Vorgang vorgang) { - return getProcessors(vorgang).map(processor -> callProcessor(processor, vorgang)); + public Stream<Mono<ProcessorResult>> processVorgang(Vorgang vorgang, String event) { + return getProcessors(vorgang, event).map(processor -> callProcessor(processor, vorgang)); } - Stream<Processor> getProcessors(Vorgang vorgang) { - return properties.getProcessors().parallelStream().filter(processor -> hasFormEngineNameAndFormIds(processor.getForms(), vorgang)); + Stream<Processor> getProcessors(Vorgang vorgang, String event) { + LOG.info("looking for processor for vorgang with formId: " + vorgang.getFormId()); + + return properties.getProcessors().parallelStream() + .filter(processor -> hasFormEngineNameAndFormIds(processor.getForms(), vorgang, event)); } - boolean hasFormEngineNameAndFormIds(Collection<Form> forms, Vorgang vorgang) { + boolean hasFormEngineNameAndFormIds(Collection<Form> forms, Vorgang vorgang, String event) { return Optional.ofNullable(forms).orElse(Collections.emptySet()).stream() .filter(form -> StringUtils.equals(form.getFormEngineName(), vorgang.getFormEngineName())) - .anyMatch(form -> StringUtils.equals(form.getFormId(), vorgang.getFormId())); + .filter(form -> StringUtils.equals(form.getFormId(), vorgang.getFormId())) + .anyMatch(form -> form.getEvents().contains(event)); } public Stream<Mono<ProcessorResult>> processVorgang(Vorgang vorgang, Collection<String> processorNames) { @@ -101,11 +108,17 @@ public class ProcessorService { .retrieve() .onStatus(HttpStatusCode::is3xxRedirection, this::buildRedirectError) .bodyToMono(ProcessorResult.class) - .onErrorMap(exception -> new ProcessorTechnicalException(vorgang.getId(), processor.getName(), "Failed to request Vorgang processor.", - exception)) + .onErrorResume(exception -> Mono.just(buildErrorResult(exception, processor, vorgang))) .doOnSuccess(processorResult -> processorResult.toBuilder().processorName(processor.getName()).build()); } + private ProcessorResult buildErrorResult(Throwable exception, Processor processor, Vorgang vorgang) { + return ProcessorResult.builder() + .action(Action.CREATE_AKTENNOTIZ) + .body(aktennotizFactory.createErrorAktennotiz(VorgangId.from(vorgang.getId()), processor.getName(), exception)) + .build(); + } + MultiValueMap<String, HttpEntity<?>> createRequestBody(Vorgang vorgang) { // NOSONAR var multipartBodyBuilder = new MultipartBodyBuilder(); multipartBodyBuilder.part(KEY_VORGANG, vorgang, MediaType.APPLICATION_JSON); diff --git a/src/main/java/de/ozgcloud/processor/result/Aktennotiz.java b/src/main/java/de/ozgcloud/processor/result/Aktennotiz.java index b3c5dbdaf58a788bb13315fe6fd33343a26784f2..ae92ce5a5123bc4590dfc723a7b7e61a98ef841d 100644 --- a/src/main/java/de/ozgcloud/processor/result/Aktennotiz.java +++ b/src/main/java/de/ozgcloud/processor/result/Aktennotiz.java @@ -26,6 +26,7 @@ package de.ozgcloud.processor.result; import jakarta.validation.constraints.NotBlank; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AllArgsConstructor; import lombok.Builder; @@ -36,6 +37,7 @@ import lombok.NoArgsConstructor; @Getter @NoArgsConstructor @AllArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) public class Aktennotiz { @JsonIgnore diff --git a/src/main/java/de/ozgcloud/processor/result/AktennotizFactory.java b/src/main/java/de/ozgcloud/processor/result/AktennotizFactory.java index 5083d57cb9ac80fc9756e49c37f46fefbc570ce9..e9e96d08addfa3bc3d69e2e48ee8376b8425daac 100644 --- a/src/main/java/de/ozgcloud/processor/result/AktennotizFactory.java +++ b/src/main/java/de/ozgcloud/processor/result/AktennotizFactory.java @@ -23,17 +23,25 @@ */ package de.ozgcloud.processor.result; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.stereotype.Component; import de.ozgcloud.processor.ProcessorManagerConfiguration; import de.ozgcloud.processor.processor.ProcessorResult; +import de.ozgcloud.processor.vorgang.VorgangId; @Component(ProcessorManagerConfiguration.AKTENNOTIZ_FACTORY_NAME) // NOSONAR public class AktennotizFactory { static final String AKTENNOTIZ_ERROR_TEXT = """ Bei der Verarbeitung im Processor '%s' ist ein Fehler aufgetreten. - ExceptionId: %s + ExceptionId: %s. + Meldung: %s. + """; + + static final String ERROR_TEXT_WO_EXCEPTIONID = """ + Bei der Verarbeitung im Processor '%s' ist ein Fehler aufgetreten. + Meldung: %s. """; public Aktennotiz createFrom(ProcessorResult processorResult) { @@ -46,21 +54,27 @@ public class AktennotizFactory { .build(); } - public Aktennotiz createErrorAktennotiz(String vorgangId, String processorName, String exceptionId) { + public Aktennotiz createErrorAktennotiz(ProcessorTechnicalException e) { + return createErrorAktennotizBuilder(VorgangId.from(e.getVorgangId())) + .text(buildErrorText(e.getProcessorName(), e.getExceptionId(), ExceptionUtils.getRootCauseMessage(e))) + .build(); + } + + public Aktennotiz createErrorAktennotiz(VorgangId vorgangId, String processorName, Throwable cause) { return createErrorAktennotizBuilder(vorgangId) - .text(buildErrorText(processorName, exceptionId)) + .text(ERROR_TEXT_WO_EXCEPTIONID.formatted(processorName, ExceptionUtils.getRootCauseMessage(cause))) .build(); } - public Aktennotiz.AktennotizBuilder createErrorAktennotizBuilder(String vorgangId) { + public Aktennotiz.AktennotizBuilder createErrorAktennotizBuilder(VorgangId vorgangId) { return Aktennotiz.builder() - .vorgangId(vorgangId) + .vorgangId(vorgangId.toString()) .severity(Severity.ERROR) .headline("Fehler"); } - String buildErrorText(String processorName, String exceptionId) { - return AKTENNOTIZ_ERROR_TEXT.formatted(processorName, exceptionId); + String buildErrorText(String processorName, String exceptionId, String causeMessage) { + return AKTENNOTIZ_ERROR_TEXT.formatted(processorName, exceptionId, causeMessage); } } diff --git a/src/main/java/de/ozgcloud/processor/result/ResultService.java b/src/main/java/de/ozgcloud/processor/result/ResultService.java index 9fdc0b84b92d294f6b63fd7b597e7aafe942426e..c809ca953875736cfff7b226571fa4fdd7066554 100644 --- a/src/main/java/de/ozgcloud/processor/result/ResultService.java +++ b/src/main/java/de/ozgcloud/processor/result/ResultService.java @@ -33,6 +33,7 @@ import de.ozgcloud.apilib.alfa.AlfaService; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper; import de.ozgcloud.processor.ProcessorManagerConfiguration; import de.ozgcloud.processor.processor.ProcessorResult; +import de.ozgcloud.processor.vorgang.VorgangId; import lombok.RequiredArgsConstructor; @Service(ProcessorManagerConfiguration.RESULT_SERVICE_NAME) // NOSONAR @@ -51,13 +52,12 @@ public class ResultService { } } - public void processError(Throwable cause, String vorgangId) { + public void processError(Throwable cause, VorgangId vorgangId) { if (cause instanceof ProcessorTechnicalException exception) { - addAktenNotiz( - aktennotizFactory.createErrorAktennotiz(exception.getVorgangId(), exception.getProcessorName(), exception.getExceptionId())); + addAktenNotiz(aktennotizFactory.createErrorAktennotiz(exception)); } else { addAktenNotiz(aktennotizFactory.createErrorAktennotizBuilder(vorgangId) - .text("Es ist eine Fehler bei der Verarbeitung des Vorganges aufgetreten").build()); + .text("Es ist eine Fehler bei der Verarbeitung des Vorganges aufgetreten.").build()); } } diff --git a/src/main/java/de/ozgcloud/processor/vorgang/ProcessorVorgangMapper.java b/src/main/java/de/ozgcloud/processor/vorgang/ProcessorVorgangMapper.java index 2774aed34bce917b8407cf19389408061491b4d7..851d098d5d283844e4dabc360bf2b51d28dea768 100644 --- a/src/main/java/de/ozgcloud/processor/vorgang/ProcessorVorgangMapper.java +++ b/src/main/java/de/ozgcloud/processor/vorgang/ProcessorVorgangMapper.java @@ -24,6 +24,7 @@ package de.ozgcloud.processor.vorgang; import java.util.List; +import java.util.Objects; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -43,6 +44,7 @@ import de.ozgcloud.apilib.vorgang.OzgCloudFormField; import de.ozgcloud.apilib.vorgang.OzgCloudSubForm; import de.ozgcloud.apilib.vorgang.OzgCloudVorgang; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangStatus; import de.ozgcloud.common.binaryfile.FileId; import de.ozgcloud.processor.ProcessorManagerConfiguration; @@ -53,6 +55,7 @@ public interface ProcessorVorgangMapper { @Mapping(target = "eingang", qualifiedByName = "mapEingang", source = "eingangs") @Mapping(target = "formId", qualifiedByName = "getFormId", source = "eingangs") @Mapping(target = "formEngineName", qualifiedByName = "mapFormEngineName", source = "eingangs") + @Mapping(target = "header.event", ignore = true) Vorgang mapVorgang(OzgCloudVorgang ozgCloudVorgang); default VorgangId mapId(OzgCloudVorgangId id) { @@ -109,4 +112,9 @@ public interface ProcessorVorgangMapper { default FileId fromOzgCloudId(OzgCloudFileId ozgCloudFileId) { return FileId.from(ozgCloudFileId.toString()); } + + default String map(OzgCloudVorgangStatus value) { + return Objects.nonNull(value) ? value.toString() : null; + } + } diff --git a/src/main/java/de/ozgcloud/processor/vorgang/Vorgang.java b/src/main/java/de/ozgcloud/processor/vorgang/Vorgang.java index 5634470d8e0879f822d392c07c65bcd0b913ba86..f50ba023e2c27edf97362bb1534a5989e7d9ad97 100644 --- a/src/main/java/de/ozgcloud/processor/vorgang/Vorgang.java +++ b/src/main/java/de/ozgcloud/processor/vorgang/Vorgang.java @@ -23,11 +23,15 @@ */ package de.ozgcloud.processor.vorgang; +import java.time.ZonedDateTime; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty.Access; import lombok.Builder; import lombok.Getter; +import lombok.With; @Builder @Getter @@ -43,9 +47,31 @@ public class Vorgang { private String formId; private Eingang eingang; + @With + @Builder.Default + private VorgangHeader header = VorgangHeader.builder().build(); @JsonProperty(access = Access.READ_ONLY, value = "vorgangId") public String getId() { return id.toString(); } + + @Builder + @Getter + static class VorgangHeader { + @With + private String event; + private String status; + private ZonedDateTime createdAt; + + // TODO workaround for faulty jackson configuration + @JsonProperty + public String getCreatedAt() { + return Objects.isNull(createdAt) ? null : createdAt.toString(); + } + } + + public Vorgang withEvent(String event) { + return this.withHeader(header.withEvent(event)); + } } diff --git a/src/test/java/de/ozgcloud/processor/ProcessorITCase.java b/src/test/java/de/ozgcloud/processor/ProcessorITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..9116dae4368433a297fc0c948200dcc9fe703b43 --- /dev/null +++ b/src/test/java/de/ozgcloud/processor/ProcessorITCase.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2023 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.processor; + +import static org.awaitility.Awaitility.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.concurrent.TimeUnit; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.bean.override.mockito.MockitoBean; + +import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.processor.processor.ProcessorService; +import de.ozgcloud.processor.vorgang.Vorgang; +import de.ozgcloud.processor.vorgang.VorgangId; +import de.ozgcloud.processor.vorgang.VorgangService; +import de.ozgcloud.processor.vorgang.VorgangTestFactory; + +//TODO: +// - rebuild it as api-test +// - build it as ProcessorManager-local test +// ozg api lib mit in-process server unterstützen: https://stackoverflow.com/questions/71059894/does-grpc-have-a-channel-that-can-be-used-for-testing + +@SpringBootTest(properties = { + "ozgcloud.processors.0.name=test", + "ozgcloud.processors.0.address=http://localhost:8090/testprocessor", + "ozgcloud.processors.0.forms.0.formEngineName=testFormEngine", + "ozgcloud.processors.0.forms.0.formId=testForm", + "grpc.server.in-process-name=test", + "ozgcloud.command-manager.address=in-process:test", +//}, classes = { VorgangManagerServerApplication.class }) +}, classes = { ProcessorTestApplication.class }) +//@WithMockCustomUser +@ITCase +@DirtiesContext +@Disabled +class ProcessorITCase { + + @Autowired + private ApplicationEventPublisher publisher; + + @MockitoBean + private VorgangService processorVorgangService; + +// @MockitoBean +// private PostfachService postfachService; +// @MockitoBean +// private de.ozgcloud.notification.vorgang.VorgangService notificationService; +// @MockitoBean +// private UserNotificationEventListener userNotificationEventListener; +// +// @MockitoBean +// private CommandService commandService; + @MockitoBean + private ProcessorService processorService; + +// @Captor +// private ArgumentCaptor<CreateCommandRequest> requestCaptor; + + @BeforeEach + void init() { + when(processorVorgangService.getVorgang(any())).thenReturn(buildVorgang()); + +// when(notificationService.getVorgang(any())).thenReturn(de.ozgcloud.notification.vorgang.Vorgang.builder().build()); + + when(processorService.processVorgang(any(), anyString())).thenThrow(RuntimeException.class); + } + +// @BeforeEach +// void setupCommandService() { +// var commandBuilder = PersistedCommand.builder().id("42").status(CommandStatus.PENDING).createdAt(ZonedDateTime.now()); +// +// when(commandService.createCommand(any())).thenReturn(commandBuilder.build()); +// when(commandService.findById("42")) +// .thenReturn(Optional.of(commandBuilder.status(CommandStatus.FINISHED).finishedAt(ZonedDateTime.now()).build())); +// } + + @Test + void triggerProcessorOnNewVorgang() { + publisher.publishEvent(new VorgangCreatedEvent(VorgangTestFactory.ID.toString())); + + await().atMost(5, TimeUnit.SECONDS).untilAsserted(() -> { + verify(processorVorgangService).getVorgang(any()); +// verify(commandService).createCommand(requestCaptor.capture()); + }); +// +// var request = requestCaptor.getValue(); +// @SuppressWarnings("unchecked") +// Map<String, Object> item = (Map<String, Object>) request.getBodyObject().get("item"); +// assertThat(item).containsEntry("text", "Es ist eine Fehler bei der Verarbeitung des Vorganges aufgetreten"); + } + + private Vorgang buildVorgang() { + return Vorgang.builder() + .id(VorgangId.from(de.ozgcloud.processor.vorgang.VorgangTestFactory.ID)) + .formEngineName("testFormEngine") + .formId("testForm") + .build(); + } +} diff --git a/src/test/java/de/ozgcloud/processor/command/CommandRemoteServiceTest.java b/src/test/java/de/ozgcloud/processor/command/CommandRemoteServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..290be1fce3c06e6338ab681ee00b389a5c411201 --- /dev/null +++ b/src/test/java/de/ozgcloud/processor/command/CommandRemoteServiceTest.java @@ -0,0 +1,63 @@ +package de.ozgcloud.processor.command; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import de.ozgcloud.apilib.common.command.grpc.GrpcCommandTestFactory; +import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.command.GrpcGetCommandRequest; + +class CommandRemoteServiceTest { + + @InjectMocks + private CommandRemoteService service; + + @Mock + private CommandServiceBlockingStub stub; + @Mock + private ProcessorManagerCommandMapper mapper; + + @Nested + class TestGetCommand { + + @Captor + private ArgumentCaptor<GrpcGetCommandRequest> requestCaptor; + + @Test + void shouldCallStub() { + service.getCommand(CommandTestFactory.ID); + + verify(stub).getCommand(requestCaptor.capture()); + assertThat(requestCaptor.getValue()).extracting(GrpcGetCommandRequest::getId) + .isEqualTo(CommandTestFactory.ID); + } + + @Test + void shouldCallMapper() { + var grpcCommand = GrpcCommandTestFactory.create(); + when(stub.getCommand(any())).thenReturn(grpcCommand); + + service.getCommand(CommandTestFactory.ID); + + verify(mapper).fromGrpc(grpcCommand); + } + + @Test + void shouldReturnMappingResult() { + when(mapper.fromGrpc(any())).thenReturn(CommandTestFactory.create()); + + var result = service.getCommand(CommandTestFactory.ID); + + assertThat(result).usingRecursiveComparison().isEqualTo(CommandTestFactory.create()); + } + } + +} diff --git a/src/test/java/de/ozgcloud/processor/command/CommandServiceTest.java b/src/test/java/de/ozgcloud/processor/command/CommandServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..75d3946f01939ee1668f8993922bcdb25dbc3011 --- /dev/null +++ b/src/test/java/de/ozgcloud/processor/command/CommandServiceTest.java @@ -0,0 +1,39 @@ +package de.ozgcloud.processor.command; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +class CommandServiceTest { + + @InjectMocks + private CommandService service; + @Mock + private CommandRemoteService remoteService; + + @Nested + class TestGetCommand { + @Test + void shouldCallRemoteService() { + service.getCommand(CommandTestFactory.ID); + + verify(remoteService).getCommand(CommandTestFactory.ID); + } + + @Test + void shouldReturnLoadedCommand() { + var expected = CommandTestFactory.create(); + when(remoteService.getCommand(any())).thenReturn(expected); + + var result = service.getCommand(CommandTestFactory.ID); + + assertThat(result).isSameAs(expected); + } + } + +} diff --git a/src/test/java/de/ozgcloud/processor/command/CommandTestFactory.java b/src/test/java/de/ozgcloud/processor/command/CommandTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..005dbfe9bdea4ea93086342c8ea81c695d966888 --- /dev/null +++ b/src/test/java/de/ozgcloud/processor/command/CommandTestFactory.java @@ -0,0 +1,22 @@ +package de.ozgcloud.processor.command; + +import java.util.UUID; + +import de.ozgcloud.processor.vorgang.VorgangTestFactory; + +public class CommandTestFactory { + + public static final String ID = UUID.randomUUID().toString(); + public static final String ORDER = "ANNEHMEN"; + + public static Command create() { + return createBuilder().build(); + } + + public static Command.CommandBuilder createBuilder() { + return Command.builder() + .id(ID) + .order(ORDER) + .vorgangId(VorgangTestFactory.ID); + } +} diff --git a/src/test/java/de/ozgcloud/processor/event/EventServiceTest.java b/src/test/java/de/ozgcloud/processor/event/EventServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..14d6d2836738543913e23bc83d2e983a8fa5097a --- /dev/null +++ b/src/test/java/de/ozgcloud/processor/event/EventServiceTest.java @@ -0,0 +1,36 @@ +package de.ozgcloud.processor.event; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Spy; + +import de.ozgcloud.processor.command.CommandTestFactory; + +class EventServiceTest { + + @Spy + @InjectMocks + private EventService service; + + @Nested + class TestGetEventName { + + @Test + void shouldReturnEventName() { + var result = service.getEventNameFromOrder(CommandTestFactory.createBuilder().order("VORGANG_ANNEHMEN").build()); + + assertThat(result).contains("ANGENOMMEN"); + } + + @Test + void shouldReturnEmptyForUnkown() { + var result = service.getEventNameFromOrder(CommandTestFactory.createBuilder().order("quatsch").build()); + + assertThat(result).isEmpty(); + } + } + +} diff --git a/src/test/java/de/ozgcloud/processor/processor/FormTestFactory.java b/src/test/java/de/ozgcloud/processor/processor/FormTestFactory.java index f0a943e159c6f4d8d6af893a3fc561b36daf4fc3..51bcf9bfef0f8b4418ce5e2e9c137f76bfde3492 100644 --- a/src/test/java/de/ozgcloud/processor/processor/FormTestFactory.java +++ b/src/test/java/de/ozgcloud/processor/processor/FormTestFactory.java @@ -23,18 +23,23 @@ */ package de.ozgcloud.processor.processor; +import java.util.Collections; + import de.ozgcloud.apilib.vorgang.OzgCloudEingangHeaderTestFactory; import de.ozgcloud.processor.processor.ProcessorProperties.Form; import de.ozgcloud.processor.processor.ProcessorProperties.Form.FormBuilder; public class FormTestFactory { + public static final String EVENT = "VORGANG_CREATED"; + public static Form create() { return createBuilder().build(); } public static FormBuilder createBuilder() { return Form.builder() + .events(Collections.singleton(EVENT)) .formId(OzgCloudEingangHeaderTestFactory.FORM_ID) .formEngineName(OzgCloudEingangHeaderTestFactory.FORM_ENGINE_NAME); } diff --git a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerITCase.java b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerITCase.java index d59d18de59df0b25e28ae41ae7e8fc65791e5d47..531fd3bb1a1013046e1cb5814d9bdf7eb919065c 100644 --- a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerITCase.java +++ b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerITCase.java @@ -30,8 +30,8 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory; import de.ozgcloud.command.CommandCreatedEvent; @@ -46,11 +46,11 @@ import de.ozgcloud.processor.vorgang.VorgangTestFactory; @ITCase class ProcessorEventListenerITCase { - @MockBean + @MockitoBean private ResultService resultService; - @MockBean + @MockitoBean private VorgangService service; - @MockBean + @MockitoBean private ProcessorService processorService; @Autowired diff --git a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java index e4e11f1733d0ad91e77be9162fd1f74a15b24bee..bbbd693bc3fb8711f207dc2111a33ba9909157bb 100644 --- a/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java +++ b/src/test/java/de/ozgcloud/processor/processor/ProcessorEventListenerTest.java @@ -32,6 +32,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Stream; import jakarta.validation.ConstraintViolationException; @@ -44,6 +45,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.Spy; import org.springframework.context.ApplicationEventPublisher; @@ -53,9 +55,13 @@ import de.ozgcloud.command.CommandCreatedEvent; import de.ozgcloud.command.CommandFailedEvent; import de.ozgcloud.command.CommandTestFactory; import de.ozgcloud.command.VorgangCreatedEvent; +import de.ozgcloud.command.status.StatusChangedEvent; +import de.ozgcloud.processor.command.CommandService; +import de.ozgcloud.processor.event.EventService; import de.ozgcloud.processor.result.ProcessorTechnicalException; import de.ozgcloud.processor.result.ResultService; import de.ozgcloud.processor.vorgang.Vorgang; +import de.ozgcloud.processor.vorgang.VorgangHeaderTestFactory; import de.ozgcloud.processor.vorgang.VorgangId; import de.ozgcloud.processor.vorgang.VorgangService; import de.ozgcloud.processor.vorgang.VorgangTestFactory; @@ -65,7 +71,7 @@ class ProcessorEventListenerTest { @Spy @InjectMocks - private ProcessorEventListener vorgangEventListener; + private ProcessorEventListener listener; @Mock private VorgangService vorgangService; @@ -76,6 +82,11 @@ class ProcessorEventListenerTest { @Mock private ApplicationEventPublisher publisher; + @Mock + private CommandService commandService; + @Mock + private EventService eventService; + @DisplayName("Trigger new vorgang processor") @Nested class TestTriggerNewVorgangProcessor { @@ -85,6 +96,8 @@ class ProcessorEventListenerTest { @Captor private ArgumentCaptor<ProcessorResult> resultCaptor; + @Captor + private ArgumentCaptor<Vorgang> vorgangCaptor; private static final VorgangCreatedEvent EVENT = new VorgangCreatedEvent(OzgCloudVorgangTestFactory.ID.toString()); @@ -95,28 +108,30 @@ class ProcessorEventListenerTest { when(vorgangService.getVorgang(any())).thenReturn(vorgang); var result = ProcessorResultTestFactory.createBuilder().vorgangId(null).build(); - when(processorService.processVorgang(any())).thenReturn(Stream.of(Mono.just(result))); + when(processorService.processVorgang(any(), anyString())).thenReturn(Stream.of(Mono.just(result))); } @Test void shouldGetVorgang() { var expectedVorgangId = VorgangId.from(OzgCloudVorgangTestFactory.ID.toString()); - vorgangEventListener.triggerNewVorgangProcessors(EVENT); + listener.triggerNewVorgangProcessors(EVENT); verify(vorgangService).getVorgang(expectedVorgangId); } @Test void shouldCallProcessVorgang() { - vorgangEventListener.triggerNewVorgangProcessors(EVENT); + listener.triggerNewVorgangProcessors(EVENT); - verify(processorService).processVorgang(vorgang); + verify(processorService).processVorgang(vorgangCaptor.capture(), eq("VORGANG_CREATED")); + assertThat(vorgangCaptor.getValue()).usingRecursiveComparison() + .isEqualTo(VorgangTestFactory.createWithHeader(VorgangHeaderTestFactory.createBuilder().event("VORGANG_CREATED").build())); } @Test void shouldSetVorgangId() { - vorgangEventListener.triggerNewVorgangProcessors(EVENT); + listener.triggerNewVorgangProcessors(EVENT); verify(resultService).processResult(resultCaptor.capture()); assertThat(resultCaptor.getValue().getVorgangId()).isEqualTo(VorgangTestFactory.ID); @@ -125,21 +140,21 @@ class ProcessorEventListenerTest { @Test void shouldCallConsumeException() { when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.create()); - when(processorService.processVorgang(any())).thenReturn(Stream.of(Mono.error(exception))); + when(processorService.processVorgang(any(), anyString())).thenReturn(Stream.of(Mono.error(exception))); - vorgangEventListener.triggerNewVorgangProcessors(EVENT); + listener.triggerNewVorgangProcessors(EVENT); - verify(resultService).processError(exception, VorgangTestFactory.ID.toString()); + verify(resultService).processError(exception, VorgangTestFactory.ID); } @Test void shouldCallConsumeUnexpectedExceptionType() { when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.create()); - when(processorService.processVorgang(any())).thenReturn(Stream.of(Mono.error(new Exception()))); + when(processorService.processVorgang(any(), anyString())).thenReturn(Stream.of(Mono.error(new Exception()))); - vorgangEventListener.triggerNewVorgangProcessors(EVENT); + listener.triggerNewVorgangProcessors(EVENT); - verify(resultService).processError(any(Exception.class), eq(VorgangTestFactory.ID.toString())); + verify(resultService).processError(any(Exception.class), eq(VorgangTestFactory.ID)); } } @@ -170,35 +185,35 @@ class ProcessorEventListenerTest { @BeforeEach void init() { when(vorgangService.getVorgang(any())).thenReturn(vorgang); - when(processorService.processVorgang(any(), any())).thenReturn(monoStream); + when(processorService.processVorgang(any(), Mockito.<Collection<String>>any())).thenReturn(monoStream); } @Test void shouldGetVorgang() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); verify(vorgangService).getVorgang(VorgangId.from(CommandTestFactory.VORGANG_ID)); } @Test void shouldCallService() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); verify(processorService).processVorgang(vorgang, processorNames); } @Test void shouldProcessResult() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); - verify(vorgangEventListener).processResult(any(), eq(CommandTestFactory.VORGANG_ID)); + verify(listener).processResult(any(), eq(VorgangId.from(CommandTestFactory.VORGANG_ID))); } @Test void shouldPublishCommandProcessedEvent() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); - verify(vorgangEventListener).publishCommandProcessedEvent(event.getSource()); + verify(listener).publishCommandProcessedEvent(event.getSource()); } } @@ -208,16 +223,16 @@ class ProcessorEventListenerTest { @Test void shouldReturnSingletonList() { - var processorNames = vorgangEventListener.getProcessorNames(createCommand("singleName")); + var result = listener.getProcessorNames(createCommand("singleName")); - assertThat(processorNames).isInstanceOf(Collection.class).containsExactly("singleName"); + assertThat(result).isInstanceOf(Collection.class).containsExactly("singleName"); } @Test void shouldReturnList() { - var processorNames = vorgangEventListener.getProcessorNames(createCommand(List.of("name", "otherName"))); + var result = listener.getProcessorNames(createCommand(List.of("name", "otherName"))); - assertThat(processorNames).isInstanceOf(Collection.class).containsExactly("name", "otherName"); + assertThat(result).isInstanceOf(Collection.class).containsExactly("name", "otherName"); } private Command createCommand(Object processorNames) { @@ -233,12 +248,12 @@ class ProcessorEventListenerTest { @BeforeEach void init() { - when(processorService.processVorgang(any(), any())).thenReturn(Stream.empty()); + when(processorService.processVorgang(any(), Mockito.<Collection<String>>any())).thenReturn(Stream.empty()); } @Test void shouldPublishEventBeClassOf() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); assertThat(commandSuccessEventCaptor.getValue().getClass()).isEqualTo(VorgangProcessedEvent.class); @@ -246,7 +261,7 @@ class ProcessorEventListenerTest { @Test void shouldPublishEventHasCommanIdAsSource() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); assertThat(commandSuccessEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); @@ -254,7 +269,7 @@ class ProcessorEventListenerTest { @Test void shouldPublishEventHasCommand() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); verify(publisher).publishEvent(commandSuccessEventCaptor.capture()); assertThat(commandSuccessEventCaptor.getValue().getCommand()).isEqualTo(command); @@ -272,23 +287,23 @@ class ProcessorEventListenerTest { @BeforeEach 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()); + when(processorService.processVorgang(any(), Mockito.<Collection<String>>any())).thenReturn(monoStream); + doThrow(exception).when(listener).processResult(any(), any()); + doNothing().when(listener).publishCommandFailedEvent(any(), any()); } @Test void shouldProcessError() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); - verify(resultService).processError(any(), eq(CommandTestFactory.VORGANG_ID)); + verify(resultService).processError(any(), eq(VorgangId.from(CommandTestFactory.VORGANG_ID))); } @Test void shouldPublishEventOnConstraintException() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); - verify(vorgangEventListener).publishCommandFailedEvent(any(), any()); + verify(listener).publishCommandFailedEvent(any(), any()); } } @@ -298,21 +313,21 @@ class ProcessorEventListenerTest { @BeforeEach void init() { - when(processorService.processVorgang(any(), any())).thenReturn(Stream.of(Mono.error(exception))); + when(processorService.processVorgang(any(), Mockito.<Collection<String>>any())).thenReturn(Stream.of(Mono.error(exception))); } @Test void shouldProcessError() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); - verify(vorgangEventListener).publishCommandFailedEvent(any(), any()); + verify(listener).publishCommandFailedEvent(any(), any()); } @Test void shouldPublishCommandFailedEvent() { - vorgangEventListener.onCommandProcessVorgang(event); + listener.onCommandProcessVorgang(event); - verify(resultService).processError(any(), eq(CommandTestFactory.VORGANG_ID)); + verify(resultService).processError(any(), eq(VorgangId.from(CommandTestFactory.VORGANG_ID))); } } @@ -320,7 +335,7 @@ class ProcessorEventListenerTest { @Nested class TestPublishCommandFailedEvent { - private final static String ERROR_MSG = "ErrorMsg"; + private static final String ERROR_MSG = "ErrorMsg"; @BeforeEach void init() { @@ -329,7 +344,7 @@ class ProcessorEventListenerTest { @Test void shouldPublishEventBeClassOf() { - vorgangEventListener.publishCommandFailedEvent(exception, CommandTestFactory.ID); + listener.publishCommandFailedEvent(exception, CommandTestFactory.ID); verify(publisher).publishEvent(commandFailedEventCaptor.capture()); assertThat(commandFailedEventCaptor.getValue().getClass()).isEqualTo(CommandFailedEvent.class); @@ -337,7 +352,7 @@ class ProcessorEventListenerTest { @Test void shouldPublishEventHasCommanIdAsSource() { - vorgangEventListener.publishCommandFailedEvent(exception, CommandTestFactory.ID); + listener.publishCommandFailedEvent(exception, CommandTestFactory.ID); verify(publisher).publishEvent(commandFailedEventCaptor.capture()); assertThat(commandFailedEventCaptor.getValue().getSource()).isEqualTo(CommandTestFactory.ID); @@ -345,11 +360,47 @@ class ProcessorEventListenerTest { @Test void shouldPublishEventHasErrorMessage() { - vorgangEventListener.publishCommandFailedEvent(exception, CommandTestFactory.ID); + listener.publishCommandFailedEvent(exception, CommandTestFactory.ID); verify(publisher).publishEvent(commandFailedEventCaptor.capture()); assertThat(commandFailedEventCaptor.getValue().getErrorMessage()).isEqualTo(ERROR_MSG); } } } + + @Nested + class TestOnStatusChange { + + private StatusChangedEvent event = new StatusChangedEvent(CommandTestFactory.create()); + private de.ozgcloud.processor.command.Command command = de.ozgcloud.processor.command.CommandTestFactory.create(); + private static final String EVENT_NAME = "EVENT"; + + @BeforeEach + void init() { + when(commandService.getCommand(any())).thenReturn(command); + when(eventService.getEventNameFromOrder(any())).thenReturn(Optional.of(EVENT_NAME)); + when(vorgangService.getVorgang(any())).thenReturn(VorgangTestFactory.create()); + } + + @Test + void shouldLoadCommand() { + listener.onStatusChange(event); + + verify(commandService).getCommand(CommandTestFactory.ID); + } + + @Test + void shouldGetEventName() { + listener.onStatusChange(event); + + verify(eventService).getEventNameFromOrder(command); + } + + @Test + void shouldProcessVorgang() { + listener.onStatusChange(event); + + verify(listener).processVorgang(VorgangTestFactory.ID, EVENT_NAME); + } + } } \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/processor/processor/ProcessorServiceITCase.java b/src/test/java/de/ozgcloud/processor/processor/ProcessorServiceITCase.java index c05616259f4ad99759753c1ad796e7f358946027..97f2fb75b78247a881dfa3cb5efae5757d351983 100644 --- a/src/test/java/de/ozgcloud/processor/processor/ProcessorServiceITCase.java +++ b/src/test/java/de/ozgcloud/processor/processor/ProcessorServiceITCase.java @@ -24,12 +24,12 @@ package de.ozgcloud.processor.processor; import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; import java.time.Duration; import java.util.Collections; import java.util.concurrent.TimeUnit; +import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -40,29 +40,35 @@ import org.junit.jupiter.params.provider.NullAndEmptySource; import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.springframework.test.util.ReflectionTestUtils; +import com.fasterxml.jackson.databind.DeserializationFeature; + import de.ozgcloud.common.test.ITCase; +import de.ozgcloud.common.test.TestUtils; import de.ozgcloud.processor.processor.ProcessorProperties.Processor; -import de.ozgcloud.processor.result.ProcessorTechnicalException; +import de.ozgcloud.processor.result.AktennotizTestFactory; import de.ozgcloud.processor.result.ResultService; +import de.ozgcloud.processor.result.Severity; import de.ozgcloud.processor.vorgang.Vorgang; import de.ozgcloud.processor.vorgang.VorgangTestFactory; import lombok.SneakyThrows; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; -import reactor.core.publisher.Mono; @ITCase class ProcessorServiceITCase { @Autowired private ProcessorService service; - @SpyBean + @MockitoSpyBean private ResultService resultService; private Processor processor; @@ -78,13 +84,6 @@ class ProcessorServiceITCase { @BeforeEach void setup() { processor = ProcessorTestFactory.createBuilder().address(mockWebServer.url("/").toString()).build(); - mockWebServer.enqueue(createMockResponse()); - } - - private MockResponse createMockResponse() { - return new MockResponse() - .addHeader("Content-Type", "application/json") - .setBody("{\"%s\": \"%s\"}".formatted(ProcessorResultTestFactory.KEY_RESULT_ACTION, ProcessorResultTestFactory.RESULT_ACTION)); } @AfterEach @@ -95,17 +94,48 @@ class ProcessorServiceITCase { @Test void shouldSendVorgangIdAsString() { + mockWebServer.enqueue(createMockResponse( + "{\"%s\": \"%s\"}".formatted(ProcessorResultTestFactory.KEY_RESULT_ACTION, ProcessorResultTestFactory.RESULT_ACTION))); var vorgang = VorgangTestFactory.create(); - var request = sendRequest(processor, vorgang); + var request = sendRequest(processor, vorgang).getLeft(); assertThat(request.getBody().readUtf8()).contains("\"vorgangId\":\"" + vorgang.getId() + "\""); } + @Test + void shouldReadResonse() { + mockWebServer.enqueue(createMockResponse( + TestUtils.loadTextFile("results/createAktennotiz.json", VorgangTestFactory.ID.toString(), VorgangTestFactory.ID.toString()))); + var vorgang = VorgangTestFactory.create(); + + var response = sendRequest(processor, vorgang).getRight(); + + assertThat(response.getBody()).usingRecursiveComparison().ignoringFields("vorgangId").isEqualTo(AktennotizTestFactory.create()); + } + + @Test + void shouldReadWithUnkownField() { + mockWebServer.enqueue(createMockResponse( + TestUtils.loadTextFile("results/createAktennotiz_unkownField.json", VorgangTestFactory.ID.toString(), + VorgangTestFactory.ID.toString()))); + + assertThat(sendRequest(processor, VorgangTestFactory.create()).getValue().getBody()).usingRecursiveComparison() + .ignoringFields("vorgangId").isEqualTo(AktennotizTestFactory.create()); + + } + + private MockResponse createMockResponse(String response) { + return new MockResponse() + .addHeader("Content-Type", "application/json") + .setBody(response); + } + @SneakyThrows - private RecordedRequest sendRequest(Processor processor, Vorgang vorgang) { - service.callProcessor(processor, vorgang).block(Duration.ofMillis(1000)); - return mockWebServer.takeRequest(100, TimeUnit.MILLISECONDS); + private Pair<RecordedRequest, ProcessorResult> sendRequest(Processor processor, Vorgang vorgang) { + var result = service.callProcessor(processor, vorgang).block(Duration.ofMillis(1000)); + + return Pair.of(mockWebServer.takeRequest(100, TimeUnit.MILLISECONDS), result); } } @@ -149,7 +179,9 @@ class ProcessorServiceITCase { mockWebServer.enqueue(createResponse(ProcessorResultTestFactory.KEY_RESULT_ACTION, action)); var vorgang = VorgangTestFactory.create(); - assertThrows(ProcessorTechnicalException.class, () -> sendRequest(vorgang)); + var result = service.callProcessor(processor, vorgang).block(); + + assertThat(result.getBody().getSeverity()).isEqualTo(Severity.ERROR); } @Test @@ -157,7 +189,9 @@ class ProcessorServiceITCase { mockWebServer.enqueue(createResponse("body", null)); var vorgang = VorgangTestFactory.create(); - assertThrows(ProcessorTechnicalException.class, () -> sendRequest(vorgang)); + var result = service.callProcessor(processor, vorgang).block(); + + assertThat(result.getBody().getSeverity()).isEqualTo(Severity.ERROR); } private MockResponse createResponse(String actionKey, String actionValue) { @@ -197,9 +231,9 @@ class ProcessorServiceITCase { MockResponse response = new MockResponse().setResponseCode(HttpStatus.BAD_REQUEST.value()); mockWebServer.enqueue(response); - var results = service.processVorgang(vorgang); + var result = service.callProcessor(processor, vorgang).block(); - assertThrows(ProcessorTechnicalException.class, () -> results.forEach(Mono::block)); + assertThat(result.getBody().getSeverity()).isEqualTo(Severity.ERROR); } @Test @@ -207,18 +241,18 @@ class ProcessorServiceITCase { MockResponse response = new MockResponse().setResponseCode(HttpStatus.BAD_GATEWAY.value()); mockWebServer.enqueue(response); - var results = service.processVorgang(vorgang); + var result = service.callProcessor(processor, vorgang).block(); - assertThrows(ProcessorTechnicalException.class, () -> results.forEach(Mono::block)); + assertThat(result.getBody().getSeverity()).isEqualTo(Severity.ERROR); } @Test void shouldHandleRedirectStatus() { mockWebServer.enqueue(new MockResponse().setResponseCode(301)); - var results = service.processVorgang(vorgang); + var result = service.callProcessor(processor, vorgang).block(); - assertThrows(ProcessorTechnicalException.class, () -> results.forEach(Mono::block)); + assertThat(result.getBody().getSeverity()).isEqualTo(Severity.ERROR); } @Test @@ -226,9 +260,9 @@ class ProcessorServiceITCase { MockResponse response = new MockResponse().addHeader("content-type", MediaType.APPLICATION_JSON).setBody("test"); mockWebServer.enqueue(response); - var results = service.processVorgang(vorgang); + var result = service.callProcessor(processor, vorgang).block(); - assertThrows(ProcessorTechnicalException.class, () -> results.forEach(Mono::block)); + assertThat(result.getBody().getSeverity()).isEqualTo(Severity.ERROR); } } @@ -266,4 +300,13 @@ class ProcessorServiceITCase { assertThat(result).isEmpty(); } } + +} + +@Configuration +class JacksonConfiguration { + @Bean + Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { + return builder -> builder.featuresToEnable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + } } \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/processor/processor/ProcessorServiceTest.java b/src/test/java/de/ozgcloud/processor/processor/ProcessorServiceTest.java index c9a87204347c1039119adde275cd3508af8a3d8d..20f759718888aee6f19bd0cae69f23857f4ae30a 100644 --- a/src/test/java/de/ozgcloud/processor/processor/ProcessorServiceTest.java +++ b/src/test/java/de/ozgcloud/processor/processor/ProcessorServiceTest.java @@ -72,7 +72,7 @@ class ProcessorServiceTest { @Test void shouldReturnProcessor() { - var processor = service.getProcessors(VorgangTestFactory.create()); + var processor = service.getProcessors(VorgangTestFactory.create(), FormTestFactory.EVENT); assertThat(processor).contains(configuredProcessor); } @@ -82,7 +82,7 @@ class ProcessorServiceTest { void shouldReturnEmptyIfNoFormId() { var vorgang = VorgangTestFactory.createBuilder().formId("other").build(); - var processor = service.getProcessors(vorgang); + var processor = service.getProcessors(vorgang, FormTestFactory.EVENT); assertThat(processor).isEmpty(); } @@ -92,7 +92,14 @@ class ProcessorServiceTest { void shouldReturnEmptyIfNoFormEngineName() { var vorgang = VorgangTestFactory.createBuilder().formEngineName("other").build(); - var processor = service.getProcessors(vorgang); + var processor = service.getProcessors(vorgang, FormTestFactory.EVENT); + + assertThat(processor).isEmpty(); + } + + @Test + void shouldReturnEmptyForOtherEvent() { + var processor = service.getProcessors(VorgangTestFactory.create(), "other"); assertThat(processor).isEmpty(); } diff --git a/src/test/java/de/ozgcloud/processor/processor/ProxyPropertiesITCase.java b/src/test/java/de/ozgcloud/processor/processor/ProxyPropertiesITCase.java index 4a356c22ac0782ce0f7e6b3de8982dac05af1717..52cdb54791551012e1e6dae12e9bb9a8f0417628 100644 --- a/src/test/java/de/ozgcloud/processor/processor/ProxyPropertiesITCase.java +++ b/src/test/java/de/ozgcloud/processor/processor/ProxyPropertiesITCase.java @@ -29,7 +29,9 @@ import org.junit.jupiter.api.Nested; 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; +@ActiveProfiles("itcase") public class ProxyPropertiesITCase { @Nested diff --git a/src/test/java/de/ozgcloud/processor/result/AktennotizFactoryTest.java b/src/test/java/de/ozgcloud/processor/result/AktennotizFactoryTest.java index 1b041a90146dd5a8395369cf5dc132009f37dd26..18d5938f2ae4886445ce5502b5159ca02e61fcb8 100644 --- a/src/test/java/de/ozgcloud/processor/result/AktennotizFactoryTest.java +++ b/src/test/java/de/ozgcloud/processor/result/AktennotizFactoryTest.java @@ -33,6 +33,7 @@ import org.mockito.Spy; import de.ozgcloud.processor.processor.ProcessorResult; import de.ozgcloud.processor.processor.ProcessorResultTestFactory; +import de.ozgcloud.processor.vorgang.VorgangId; import de.ozgcloud.processor.vorgang.VorgangTestFactory; class AktennotizFactoryTest { @@ -77,7 +78,7 @@ class AktennotizFactoryTest { @Nested class TestCreateErrorAktennotiz { - private static final String VORGANG_ID = VorgangTestFactory.ID.toString(); + private static final VorgangId VORGANG_ID = VorgangTestFactory.ID; private static final String PROCESSOR_NAME = "processorName"; @@ -107,7 +108,7 @@ class AktennotizFactoryTest { @Test void shouldSetText() { var errorText = "errorText"; - doReturn(errorText).when(factory).buildErrorText(anyString(), anyString()); + doReturn(errorText).when(factory).buildErrorText(anyString(), anyString(), anyString()); var aktennotiz = createErrorAktennotiz(); @@ -115,7 +116,7 @@ class AktennotizFactoryTest { } private Aktennotiz createErrorAktennotiz() { - return factory.createErrorAktennotiz(VORGANG_ID, PROCESSOR_NAME, EXCEPTION_ID); + return factory.createErrorAktennotiz(new ProcessorTechnicalException(VORGANG_ID.toString(), PROCESSOR_NAME, EXCEPTION_ID)); } } @@ -126,7 +127,7 @@ class AktennotizFactoryTest { void shouldAddProcessorName() { var processorName = "processorName"; - var errorText = factory.buildErrorText(processorName, ""); + var errorText = factory.buildErrorText(processorName, "", ""); assertThat(errorText).contains(processorName); } @@ -135,9 +136,18 @@ class AktennotizFactoryTest { void shouldAddExceptionId() { var exceptionId = "exceptionId"; - var errorText = factory.buildErrorText("", exceptionId); + var errorText = factory.buildErrorText("", exceptionId, ""); assertThat(errorText).contains(exceptionId); } + + @Test + void shouldAddRootCause() { + var rootCause = "cause"; + + var errorText = factory.buildErrorText("", "", rootCause); + + assertThat(errorText).contains(rootCause); + } } } \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/processor/result/ResultServiceTest.java b/src/test/java/de/ozgcloud/processor/result/ResultServiceTest.java index 4597e31aeb93cffb621204c2cdb49ec95f3e5c05..4287d42c2396c4cc97760183aa2a6c2d89907be9 100644 --- a/src/test/java/de/ozgcloud/processor/result/ResultServiceTest.java +++ b/src/test/java/de/ozgcloud/processor/result/ResultServiceTest.java @@ -38,7 +38,6 @@ import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangIdMapper; import de.ozgcloud.processor.processor.ProcessorResult; import de.ozgcloud.processor.processor.ProcessorResultTestFactory; -import de.ozgcloud.processor.processor.ProcessorTestFactory; import de.ozgcloud.processor.vorgang.VorgangTestFactory; class ResultServiceTest { @@ -83,31 +82,24 @@ class ResultServiceTest { @Nested class TestProcessError { - private static final String EXCEPTION_ID = "exceptionId"; - @Mock private ProcessorTechnicalException exception; @BeforeEach void setup() { - when(exception.getVorgangId()).thenReturn(VorgangTestFactory.ID.toString()); - when(exception.getExceptionId()).thenReturn(EXCEPTION_ID); - when(aktennotizFactory.createErrorAktennotiz(any(), any(), any())).thenReturn(aktennotiz); + when(aktennotizFactory.createErrorAktennotiz(any())).thenReturn(aktennotiz); } @Test void shouldCallCreateErrorAktennotiz() { - when(exception.getProcessorName()).thenReturn(ProcessorTestFactory.PROCESSOR_NAME); - when(exception.getExceptionId()).thenReturn(EXCEPTION_ID); - - resultService.processError(exception, VorgangTestFactory.ID.toString()); + resultService.processError(exception, VorgangTestFactory.ID); - verify(aktennotizFactory).createErrorAktennotiz(VorgangTestFactory.ID.toString(), ProcessorTestFactory.PROCESSOR_NAME, EXCEPTION_ID); + verify(aktennotizFactory).createErrorAktennotiz(exception); } @Test void shouldCallAddAktenNotiz() { - resultService.processError(exception, VorgangTestFactory.ID.toString()); + resultService.processError(exception, VorgangTestFactory.ID); verify(resultService).addAktenNotiz(aktennotiz); } diff --git a/src/test/java/de/ozgcloud/processor/vorgang/ProcessorVorgangMapperTest.java b/src/test/java/de/ozgcloud/processor/vorgang/ProcessorVorgangMapperTest.java index 42be8a3c0d5c3551c2ea4efd99949b214a11b826..3240749de60c7c81b9af051854393707358b0461 100644 --- a/src/test/java/de/ozgcloud/processor/vorgang/ProcessorVorgangMapperTest.java +++ b/src/test/java/de/ozgcloud/processor/vorgang/ProcessorVorgangMapperTest.java @@ -42,7 +42,8 @@ class ProcessorVorgangMapperTest { void shouldMapAllField() { var mapped = mapper.mapVorgang(OzgCloudVorgangTestFactory.create()); - assertThat(mapped).usingRecursiveComparison().isEqualTo(VorgangTestFactory.create()); + assertThat(mapped).usingRecursiveComparison() + .isEqualTo(VorgangTestFactory.createWithHeader(VorgangHeaderTestFactory.createBuilder().event(null).build())); } @Test diff --git a/src/test/java/de/ozgcloud/processor/vorgang/VorgangHeaderTestFactory.java b/src/test/java/de/ozgcloud/processor/vorgang/VorgangHeaderTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..72d225c37949b3e86af570c3d5c5897afa1963c3 --- /dev/null +++ b/src/test/java/de/ozgcloud/processor/vorgang/VorgangHeaderTestFactory.java @@ -0,0 +1,24 @@ +package de.ozgcloud.processor.vorgang; + +import java.time.ZonedDateTime; + +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangHeaderTestFactory; +import de.ozgcloud.processor.vorgang.Vorgang.VorgangHeader; + +public class VorgangHeaderTestFactory { + + static final ZonedDateTime CREATED_AT = OzgCloudVorgangHeaderTestFactory.CREATED_AT; + static final String STATUS = OzgCloudVorgangHeaderTestFactory.STATUS_STR; + static final String EVENT = "ABGESCHLOSSEN"; + + public static VorgangHeader create() { + return createBuilder().build(); + } + + public static VorgangHeader.VorgangHeaderBuilder createBuilder() { + return VorgangHeader.builder() + .createdAt(CREATED_AT) + .status(STATUS) + .event(EVENT); + } +} diff --git a/src/test/java/de/ozgcloud/processor/vorgang/VorgangTestFactory.java b/src/test/java/de/ozgcloud/processor/vorgang/VorgangTestFactory.java index ef2b5ca9c1414176abf5b24c695379a95a6e60bc..5d9aca7812e5275f86e8c9910c35b65493eb3ba2 100644 --- a/src/test/java/de/ozgcloud/processor/vorgang/VorgangTestFactory.java +++ b/src/test/java/de/ozgcloud/processor/vorgang/VorgangTestFactory.java @@ -27,6 +27,7 @@ import static de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory.*; import de.ozgcloud.apilib.vorgang.OzgCloudEingangHeaderTestFactory; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory; +import de.ozgcloud.processor.vorgang.Vorgang.VorgangHeader; public class VorgangTestFactory { @@ -44,6 +45,11 @@ public class VorgangTestFactory { .vorgangNummer(VORGANG_NUMMER) .formId(OzgCloudEingangHeaderTestFactory.FORM_ID) .formEngineName(OzgCloudEingangHeaderTestFactory.FORM_ENGINE_NAME) + .header(VorgangHeaderTestFactory.create()) .eingang(EingangTestFactory.create()); } + + public static Vorgang createWithHeader(VorgangHeader header) { + return createBuilder().header(header).build(); + } } diff --git a/src/test/resources/application-itcase.yml b/src/test/resources/application-itcase.yml index 4e522a6a1ee94794d05902434e815c204688a8a6..abbc391103440f5116b29485b09f802774c7eeac 100644 --- a/src/test/resources/application-itcase.yml +++ b/src/test/resources/application-itcase.yml @@ -21,6 +21,12 @@ # Die sprachspezifischen Genehmigungen und Beschränkungen # unter der Lizenz sind dem Lizenztext zu entnehmen. # + +logging: + level: + root: WARN + config: classpath:log4j2-local.xml + ozgcloud: processors: - address: http://test1 diff --git a/src/test/resources/results/createAktennotiz.json b/src/test/resources/results/createAktennotiz.json new file mode 100644 index 0000000000000000000000000000000000000000..64cecd83a6c5899f42a768b5d64012a1fa3f4e4e --- /dev/null +++ b/src/test/resources/results/createAktennotiz.json @@ -0,0 +1,10 @@ +{ + "vorgangId": "%s", + "action": "CREATE_AKTENNOTIZ", + "body": { + "vorgangId": "%s", + "severity": "INFO", + "headline": "Headline", + "text": "Text" + } +} \ No newline at end of file diff --git a/src/test/resources/results/createAktennotiz_unkownField.json b/src/test/resources/results/createAktennotiz_unkownField.json new file mode 100644 index 0000000000000000000000000000000000000000..33bdc8e563b6ac75ac40f7b3435bce22af5cdf46 --- /dev/null +++ b/src/test/resources/results/createAktennotiz_unkownField.json @@ -0,0 +1,11 @@ +{ + "vorgangId": "%s", + "action": "CREATE_AKTENNOTIZ", + "body": { + "vorgangId": "%s", + "severity": "INFO", + "headline": "Headline", + "text": "Text", + "new": "unkown" + } +} \ No newline at end of file