diff --git a/api-lib-core/pom.xml b/api-lib-core/pom.xml index 18560a62b52216ef90809ed4c2e5ed1e8bc04533..56ebb9a7ce8f9a42aa7974ce3b6bc9905578d7b8 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 0000000000000000000000000000000000000000..367bd31068acc2d36a5de76805783a7ffa2c17ea --- /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 0000000000000000000000000000000000000000..333a50bd0d55a2f72bf9ffc7249c00adda596b1e --- /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 0000000000000000000000000000000000000000..a1bbbc1a19557818a624b29a38c207dbcf40f70e --- /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 0000000000000000000000000000000000000000..b3538711109bb6e26756cba9a56a3cc59c4aed09 --- /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 0000000000000000000000000000000000000000..9c485e77d6e42eb06f2d8b0f4981cf2bc275d768 --- /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 0000000000000000000000000000000000000000..3cb2b4eebfc304379ce434df4baeea630118b201 --- /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 d95b83498f7a01bcaa2e1fb053bb87faeb86dc74..a9ab13cdbf4cea399d61e90e2ab8381d7579bbfb 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 5d6b8adda071fba5e9ace16e0da8751b87ac2815..b74ca3dbe7a7635c43b307e75726c8fa995338e2 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 0000000000000000000000000000000000000000..b187ee71d31d5db0b7cef252a85d203bf29a4845 --- /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 0000000000000000000000000000000000000000..1b0db3f057ce222f7b8f408d72e904e4e5a2f297 --- /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 0000000000000000000000000000000000000000..9fc872594a49d17be32619be4ff1e1c21977b4d3 --- /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 0000000000000000000000000000000000000000..fdc28f82aa20897d154bec1d41fb221a186df9a0 --- /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 ddc2304030486d3a6d5bda8b08f6e9b8fa08aff5..68302989302c8094c1cab7ca7a222abd64ab64ef 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 d31fe02fad15f0650928daebf2a395762ddddd32..d27fbb956d0761e4614d96fbf85ff11dee6c59da 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>