From 007d993bd36c21c334ed548a69b9d7b825b5b905 Mon Sep 17 00:00:00 2001 From: OZGCloud <ozgcloud@mgm-tp.com> Date: Fri, 1 Sep 2023 15:03:11 +0200 Subject: [PATCH] added command service --- api-lib-core/pom.xml | 4 ++ .../common/command/OzgCloudCommand.java | 46 ++++++++++++++ .../common/command/OzgCloudCommandId.java | 17 ++++++ .../command/OzgCloudCommandService.java | 6 ++ .../common/command/OzgCloudCommandStatus.java | 20 +++++++ .../grpc/GrpcOzgCloudCommandService.java | 37 ++++++++++++ .../command/grpc/OzgCloudCommandMapper.java | 46 ++++++++++++++ .../errorhandling/NotFoundException.java | 2 +- .../file/grpc/GrpcOzgCloudFileService.java | 2 +- .../GrpcCreateCommandRequestTestFactory.java | 25 ++++++++ .../grpc/GrpcOzgCloudCommandServiceTest.java | 60 +++++++++++++++++++ .../grpc/OzgCloudCommandMapperTest.java | 23 +++++++ .../grpc/OzgCloudCommandTestFactory.java | 51 ++++++++++++++++ .../grpc/GrpcOzgCloudFileServiceTest.java | 2 +- pom.xml | 3 +- 15 files changed, 339 insertions(+), 5 deletions(-) create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommand.java create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandId.java create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandService.java create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandStatus.java create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/GrpcOzgCloudCommandService.java create mode 100644 api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandMapper.java rename api-lib-core/src/main/java/de/ozgcloud/apilib/{ => common}/errorhandling/NotFoundException.java (86%) create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/GrpcCreateCommandRequestTestFactory.java create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/GrpcOzgCloudCommandServiceTest.java create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandMapperTest.java create mode 100644 api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandTestFactory.java diff --git a/api-lib-core/pom.xml b/api-lib-core/pom.xml index 18560a6..56ebb9a 100644 --- a/api-lib-core/pom.xml +++ b/api-lib-core/pom.xml @@ -31,6 +31,10 @@ <groupId>de.itvsh.ozg.pluto</groupId> <artifactId>pluto-interface</artifactId> </dependency> + <dependency> + <groupId>de.itvsh.ozg.pluto</groupId> + <artifactId>pluto-utils</artifactId> + </dependency> <!--spring --> <dependency> diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommand.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommand.java new file mode 100644 index 0000000..367bd31 --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommand.java @@ -0,0 +1,46 @@ +package de.ozgcloud.apilib.common.command; + +import java.time.ZonedDateTime; +import java.util.Map; + +import de.itvsh.kop.common.datatype.StringBasedValue; +import de.ozgcloud.apilib.user.OzgCloudUserId; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class OzgCloudCommand { + + private OzgCloudCommandId id; + + private OzgCloudVorgangId vorgangId; + /** + * Id of the entity, that is referenced by this command to be processed. That + * can be any Id, for example vorgangId, fileId and so on. + */ + private StringBasedValue relationId; + /** + * Version of the entity, to be processed by this command. Used for optimistic + * locking. + */ + private Long relationVersion; + + private String order; + + private ZonedDateTime createdAt; + private ZonedDateTime finishedAt; + + private OzgCloudUserId createdBy; + private OzgCloudCommandStatus status; + + private Map<String, Object> bodyObject; + /** + * @deprecated use {@link OzgCloudCommand#bodyObject} + */ + @Deprecated(since = "0.2.0", forRemoval = true) + private Map<String, String> body; + + private String errorMessage; +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandId.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandId.java new file mode 100644 index 0000000..333a50b --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandId.java @@ -0,0 +1,17 @@ +package de.ozgcloud.apilib.common.command; + +import org.mapstruct.ObjectFactory; + +import de.itvsh.kop.common.datatype.StringBasedValue; + +public class OzgCloudCommandId extends StringBasedValue { + + OzgCloudCommandId(String commandId) { + super(commandId); + } + + @ObjectFactory + public static OzgCloudCommandId from(String commandId) { + return new OzgCloudCommandId(commandId); + } +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandService.java new file mode 100644 index 0000000..a1bbbc1 --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandService.java @@ -0,0 +1,6 @@ +package de.ozgcloud.apilib.common.command; + +public interface OzgCloudCommandService { + + public OzgCloudCommand createAndWaitUntilDone(OzgCloudCommand commandToCreate); +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandStatus.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandStatus.java new file mode 100644 index 0000000..b353871 --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCommandStatus.java @@ -0,0 +1,20 @@ +package de.ozgcloud.apilib.common.command; + +import de.itvsh.kop.common.datatype.StringBasedValue; + +public class OzgCloudCommandStatus extends StringBasedValue { + + public static final OzgCloudCommandStatus PENDING = from("PENDING"); + public static final OzgCloudCommandStatus FINISHED = from("FINISHED"); + public static final OzgCloudCommandStatus ERROR = from("ERROR"); + public static final OzgCloudCommandStatus REVOKE_PENDING = from("REVOKE_PENDING"); + public static final OzgCloudCommandStatus REVOKED = from("REVOKED"); + + OzgCloudCommandStatus(String status) { + super(status); + } + + public static OzgCloudCommandStatus from(String status) { + return new OzgCloudCommandStatus(status); + } +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/GrpcOzgCloudCommandService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/GrpcOzgCloudCommandService.java new file mode 100644 index 0000000..9c485e7 --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/GrpcOzgCloudCommandService.java @@ -0,0 +1,37 @@ +package de.ozgcloud.apilib.common.command.grpc; + +import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; +import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.apilib.common.command.OzgCloudCommand; +import de.ozgcloud.apilib.common.command.OzgCloudCommandService; +import lombok.RequiredArgsConstructor; +import net.devh.boot.grpc.client.inject.GrpcClient; + +@RequiredArgsConstructor +public class GrpcOzgCloudCommandService implements OzgCloudCommandService { + + @GrpcClient("command-manager") + private final CommandServiceBlockingStub commandServiceStub; + + private GrpcObjectMapper objectMapper; + + @Override + public OzgCloudCommand createAndWaitUntilDone(OzgCloudCommand commandToCreate) { + var command = create(commandToCreate); + // TODO Auto-generated method stub + return null; + } + + OzgCloudCommand create(OzgCloudCommand commandToCreate) { + commandServiceStub.createCommand(buildCreateCommandRequest(commandToCreate)); + return null; + } + + GrpcCreateCommandRequest buildCreateCommandRequest(OzgCloudCommand commandToCreate) { + return GrpcCreateCommandRequest.newBuilder() + .build(); + + } + +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandMapper.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandMapper.java new file mode 100644 index 0000000..3cb2b4e --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandMapper.java @@ -0,0 +1,46 @@ +package de.ozgcloud.apilib.common.command.grpc; + +import java.util.Objects; +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import de.itvsh.kop.common.datatype.StringBasedValue; +import de.itvsh.kop.pluto.common.grpc.GrpcObjectMapper; +import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.apilib.common.command.OzgCloudCommand; + +@Mapper(uses = GrpcObjectMapper.class) +public interface OzgCloudCommandMapper { + + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "mergeBodyObj", ignore = true) + @Mapping(target = "mergeCallContext", ignore = true) + @Mapping(target = "mergeRedirectRequest", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "removeBody", ignore = true) + @Mapping(target = "callContext", ignore = true) + + @Mapping(target = "orderStringBytes", ignore = true) + @Mapping(target = "order", ignore = true) + @Mapping(target = "orderValue", ignore = true) + @Mapping(target = "redirectRequest", ignore = true) + @Mapping(target = "relationIdBytes", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "vorgangIdBytes", ignore = true) + @Mapping(target = "allFields", ignore = true) + @Mapping(target = "bodyBuilderList", ignore = true) + @Mapping(target = "bodyList", ignore = true) + @Mapping(target = "bodyOrBuilderList", ignore = true) + + @Mapping(target = "bodyObj", source = "bodyObject") + @Mapping(target = "orderString", source = "order") + GrpcCreateCommandRequest toCreateRequest(OzgCloudCommand command); + + default String toString(StringBasedValue stringBasedValue) { + return Optional.ofNullable(stringBasedValue).map(Objects::toString).orElse(null); + } +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/errorhandling/NotFoundException.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/errorhandling/NotFoundException.java similarity index 86% rename from api-lib-core/src/main/java/de/ozgcloud/apilib/errorhandling/NotFoundException.java rename to api-lib-core/src/main/java/de/ozgcloud/apilib/common/errorhandling/NotFoundException.java index d95b834..a9ab13c 100644 --- a/api-lib-core/src/main/java/de/ozgcloud/apilib/errorhandling/NotFoundException.java +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/errorhandling/NotFoundException.java @@ -1,4 +1,4 @@ -package de.ozgcloud.apilib.errorhandling; +package de.ozgcloud.apilib.common.errorhandling; import de.itvsh.kop.common.datatype.StringBasedValue; diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileService.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileService.java index 5d6b8ad..b74ca3d 100644 --- a/api-lib-core/src/main/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileService.java +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileService.java @@ -19,7 +19,7 @@ import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcBinaryFilesRequest; import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcFindFilesResponse; import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcGetBinaryFileDataRequest; import de.itvsh.ozg.pluto.grpc.file.GrpcOzgFile; -import de.ozgcloud.apilib.errorhandling.NotFoundException; +import de.ozgcloud.apilib.common.errorhandling.NotFoundException; import de.ozgcloud.apilib.file.OzgCloudFile; import de.ozgcloud.apilib.file.OzgCloudFileId; import de.ozgcloud.apilib.file.OzgCloudFileService; diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/GrpcCreateCommandRequestTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/GrpcCreateCommandRequestTestFactory.java new file mode 100644 index 0000000..b187ee7 --- /dev/null +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/GrpcCreateCommandRequestTestFactory.java @@ -0,0 +1,25 @@ +package de.ozgcloud.apilib.common.command.grpc; + +import static de.ozgcloud.apilib.common.command.grpc.OzgCloudCommandTestFactory.*; + +import de.itvsh.ozg.pluto.common.GrpcObject; +import de.itvsh.ozg.pluto.common.GrpcProperty; +import de.itvsh.ozg.pluto.grpc.command.GrpcCreateCommandRequest; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory; + +public class GrpcCreateCommandRequestTestFactory { + + public static GrpcCreateCommandRequest create() { + return createBuilder().build(); + } + + public static GrpcCreateCommandRequest.Builder createBuilder() { + return GrpcCreateCommandRequest.newBuilder() + .setVorgangId(OzgCloudVorgangTestFactory.ID.toString()) + .setRelationId(RELATION_ID.toString()) + .setRelationVersion(RELATION_VERSION) + .setOrderString(ORDER) + .setBodyObj(GrpcObject.newBuilder().addProperty( + GrpcProperty.newBuilder().setName(BODY_FIELD_NAME).addValue(BODY_FIELD_VALUE.toString()).build())); + } +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/GrpcOzgCloudCommandServiceTest.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/GrpcOzgCloudCommandServiceTest.java new file mode 100644 index 0000000..1b0db3f --- /dev/null +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/GrpcOzgCloudCommandServiceTest.java @@ -0,0 +1,60 @@ +package de.ozgcloud.apilib.common.command.grpc; + +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; +import org.mockito.Spy; + +import de.itvsh.ozg.pluto.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.apilib.common.command.OzgCloudCommand; + +class GrpcOzgCloudCommandServiceTest { + + @Spy + @InjectMocks + private GrpcOzgCloudCommandService service; + + @Mock + private CommandServiceBlockingStub serviceStub; + + @Nested + class TestCreateAndWaitUntilDone { + @Test + void shouldCallCreate() { + OzgCloudCommand command = OzgCloudCommandTestFactory.create(); + + service.createAndWaitUntilDone(command); + + verify(service).create(command); + } + + @Nested + class BuildCreateCommandRequest { + @Test + void shouldBuildCommand() { + var request = service.buildCreateCommandRequest(OzgCloudCommandTestFactory.create()); + + assertThat(request).usingRecursiveComparison().isEqualTo(GrpcCreateCommandRequestTestFactory.create()); + } + } + + @Nested + class Create { + @Test + void shouldCallStub() { + var request = GrpcCreateCommandRequestTestFactory.create(); + doReturn(request).when(service).buildCreateCommandRequest(any()); + + service.create(OzgCloudCommandTestFactory.create()); + + verify(serviceStub).createCommand(notNull()); + } + } + } + +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandMapperTest.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandMapperTest.java new file mode 100644 index 0000000..9fc8725 --- /dev/null +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandMapperTest.java @@ -0,0 +1,23 @@ +package de.ozgcloud.apilib.common.command.grpc; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +class OzgCloudCommandMapperTest { + + private OzgCloudCommandMapper mapper = Mappers.getMapper(OzgCloudCommandMapper.class); + + @Nested + class TestToCreateRequest { + @Test + void shouldMapFromCommand() { + var request = mapper.toCreateRequest(OzgCloudCommandTestFactory.create()); + + assertThat(request).usingRecursiveComparison().isEqualTo(GrpcCreateCommandRequestTestFactory.create()); + } + } + +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandTestFactory.java new file mode 100644 index 0000000..fdc28f8 --- /dev/null +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/OzgCloudCommandTestFactory.java @@ -0,0 +1,51 @@ +package de.ozgcloud.apilib.common.command.grpc; + +import java.time.ZonedDateTime; +import java.util.Map; +import java.util.UUID; + +import de.itvsh.kop.common.datatype.StringBasedValue; +import de.ozgcloud.apilib.common.command.OzgCloudCommand; +import de.ozgcloud.apilib.common.command.OzgCloudCommandId; +import de.ozgcloud.apilib.common.command.OzgCloudCommandStatus; +import de.ozgcloud.apilib.file.OzgCloudFileTestFactory; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; +import de.ozgcloud.apilib.vorgang.OzgCloudVorgangTestFactory; + +public class OzgCloudCommandTestFactory { + + public static final OzgCloudCommandId ID = OzgCloudCommandId.from(UUID.randomUUID().toString()); + + public static final OzgCloudVorgangId VORGANG_ID = OzgCloudVorgangTestFactory.ID; + public static final StringBasedValue RELATION_ID = OzgCloudFileTestFactory.ID; + public static final long RELATION_VERSION = 42; + + public static final String ORDER = "CREATE_NOTE"; + public static final OzgCloudCommandStatus STATUS = OzgCloudCommandStatus.FINISHED; + + private static final String CREATED_AT_STR = "2023-08-18T13:54:10Z"; + private static final ZonedDateTime CREATED_AT = ZonedDateTime.parse(CREATED_AT_STR); + private static final String FINISHED_AT_STR = "2023-08-18T13:55:10Z"; + private static final ZonedDateTime FINISHED_AT = ZonedDateTime.parse(FINISHED_AT_STR); + + public static final String BODY_FIELD_NAME = "FIELD"; + public static final Long BODY_FIELD_VALUE = 42L; + private static final Map<String, Object> BODY = Map.of(BODY_FIELD_NAME, BODY_FIELD_VALUE); + + public static OzgCloudCommand create() { + return createBuilder().build(); + } + + public static OzgCloudCommand.OzgCloudCommandBuilder createBuilder() { + return OzgCloudCommand.builder() + .id(ID) + .vorgangId(VORGANG_ID) + .relationId(RELATION_ID) + .relationVersion(RELATION_VERSION) + .order(ORDER) + .status(STATUS) + .createdAt(CREATED_AT) + .finishedAt(FINISHED_AT) + .bodyObject(BODY); + } +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileServiceTest.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileServiceTest.java index ddc2304..6830298 100644 --- a/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileServiceTest.java +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/file/grpc/GrpcOzgCloudFileServiceTest.java @@ -14,7 +14,7 @@ import org.mockito.Spy; import de.itvsh.ozg.pluto.grpc.binaryFile.BinaryFileServiceGrpc.BinaryFileServiceBlockingStub; import de.itvsh.ozg.pluto.grpc.binaryFile.GrpcFindFilesResponse; -import de.ozgcloud.apilib.errorhandling.NotFoundException; +import de.ozgcloud.apilib.common.errorhandling.NotFoundException; import de.ozgcloud.apilib.file.OzgCloudFileTestFactory; class GrpcOzgCloudFileServiceTest { diff --git a/pom.xml b/pom.xml index d31fe02..d27fbb9 100644 --- a/pom.xml +++ b/pom.xml @@ -7,8 +7,7 @@ <parent> <groupId>de.itvsh.kop.common</groupId> <artifactId>kop-common-dependencies</artifactId> -<!-- <version>2.3.0-SNAPSHOT</version>--> - <version>2.3.0-20230726.100032-5</version> + <version>2.3.0-SNAPSHOT</version> <relativePath /> <!-- lookup parent from repository --> </parent> -- GitLab