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 index 3398e4751ccf61c6696563118d959de0cb36dc91..1cecb578e467e518700b53eef8719f34ca7a0455 100644 --- 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 @@ -1,8 +1,12 @@ package de.ozgcloud.apilib.common.command; +import java.util.List; + public interface OzgCloudCommandService { - public OzgCloudCommand create(OzgCloudCommand commandToCreate); + OzgCloudCommand create(OzgCloudCommand commandToCreate); + + OzgCloudCommand createAndWaitUntilDone(OzgCloudCommand commandToCreate); - public OzgCloudCommand createAndWaitUntilDone(OzgCloudCommand commandToCreate); + List<OzgCloudCommand> addSubCommands(OzgCloudCreateSubCommandsRequest request); } diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCreateSubCommandsRequest.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCreateSubCommandsRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..bb1a281df14960b76c7f516e800c16e229596a10 --- /dev/null +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/OzgCloudCreateSubCommandsRequest.java @@ -0,0 +1,20 @@ +package de.ozgcloud.apilib.common.command; + +import java.util.List; + +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.Singular; + +@Builder +@Getter +public class OzgCloudCreateSubCommandsRequest { + + @NonNull + private String parentId; + private String executionMode; + private boolean completedIfSubsCompleted; + @Singular + private List<OzgCloudCommand> subCommands; +} diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/CommandMapper.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/CommandMapper.java index 5d9313beb3f13d8867b4a21eec2f4eee98d3e00f..bdc6efaa4adb4b9b91f4c48f7296543a11a698b9 100644 --- a/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/CommandMapper.java +++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/common/command/grpc/CommandMapper.java @@ -1,6 +1,7 @@ package de.ozgcloud.apilib.common.command.grpc; import java.time.ZonedDateTime; +import java.util.List; import org.apache.commons.lang3.StringUtils; import org.mapstruct.Mapper; @@ -11,17 +12,25 @@ import org.mapstruct.NullValueCheckStrategy; 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.common.command.OzgCloudCreateSubCommandsRequest; import de.ozgcloud.apilib.common.datatypes.GenericId; import de.ozgcloud.apilib.user.OzgCloudUserId; import de.ozgcloud.apilib.vorgang.OzgCloudVorgangId; import de.ozgcloud.common.datatype.StringBasedValue; import de.ozgcloud.vorgang.common.grpc.GrpcObjectMapper; +import de.ozgcloud.vorgang.grpc.command.GrpcAddSubCommandsRequest; import de.ozgcloud.vorgang.grpc.command.GrpcCommand; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommand; import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommandRequest; @Mapper(uses = { GrpcObjectMapper.class }, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) public interface CommandMapper { + @Mapping(target = "redirectRequestOrBuilder", ignore = true) + @Mapping(target = "orderStringBytes", ignore = true) + @Mapping(target = "defaultInstanceForType", ignore = true) + @Mapping(target = "callContextOrBuilder", ignore = true) + @Mapping(target = "bodyObjOrBuilder", ignore = true) @Mapping(target = "mergeFrom", ignore = true) @Mapping(target = "clearField", ignore = true) @Mapping(target = "clearOneof", ignore = true) @@ -31,9 +40,6 @@ public interface CommandMapper { @Mapping(target = "mergeUnknownFields", ignore = true) @Mapping(target = "removeBody", ignore = true) @Mapping(target = "callContext", ignore = true) - @Mapping(target = "order", ignore = true) - @Mapping(target = "orderStringBytes", ignore = true) - @Mapping(target = "orderValue", ignore = true) @Mapping(target = "redirectRequest", ignore = true) @Mapping(target = "relationIdBytes", ignore = true) @Mapping(target = "unknownFields", ignore = true) @@ -84,4 +90,44 @@ public interface CommandMapper { default String valueToString(StringBasedValue value) { return value.toString(); } + + default GrpcAddSubCommandsRequest toAddSubCommandsRequest(OzgCloudCreateSubCommandsRequest createSubCommandsRequest) { + return toAddSubCommandsRequestWithoutSubCommands(createSubCommandsRequest).toBuilder() + .addAllSubCommands(toCreateCommands(createSubCommandsRequest.getSubCommands())).build(); + } + + @Mapping(target = "subCommandsList", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "subCommandsOrBuilderList", ignore = true) + @Mapping(target = "subCommandsBuilderList", ignore = true) + @Mapping(target = "removeSubCommands", ignore = true) + @Mapping(target = "parentIdBytes", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "executionModeBytes", ignore = true) + @Mapping(target = "defaultInstanceForType", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "allFields", ignore = true) + GrpcAddSubCommandsRequest toAddSubCommandsRequestWithoutSubCommands(OzgCloudCreateSubCommandsRequest command); + + default List<GrpcCreateCommand> toCreateCommands(List<OzgCloudCommand> subCommands) { + return subCommands.stream().map(this::toCreateCommand).toList(); + } + + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "relationIdBytes", ignore = true) + @Mapping(target = "orderBytes", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "mergeBodyObj", ignore = true) + @Mapping(target = "defaultInstanceForType", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "bodyObjOrBuilder", ignore = true) + @Mapping(target = "allFields", ignore = true) + + @Mapping(target = "bodyObj", source = "bodyObject") + GrpcCreateCommand toCreateCommand(OzgCloudCommand commands); + } 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 index c06320d9bb78c7a599756d7a7b368cd43ad44a74..91e05f4c9af4d367f850c8f01b04f61f884a0c39 100644 --- 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 @@ -1,11 +1,14 @@ package de.ozgcloud.apilib.common.command.grpc; +import java.util.List; + import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextAttachingInterceptor; import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider; import de.ozgcloud.apilib.common.command.OzgCloudCommand; import de.ozgcloud.apilib.common.command.OzgCloudCommandId; import de.ozgcloud.apilib.common.command.OzgCloudCommandService; import de.ozgcloud.apilib.common.command.OzgCloudCommandStatus; +import de.ozgcloud.apilib.common.command.OzgCloudCreateSubCommandsRequest; import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; import de.ozgcloud.vorgang.grpc.command.GrpcGetCommandRequest; @@ -60,13 +63,18 @@ public class GrpcOzgCloudCommandService implements OzgCloudCommandService { return mapper.fromGrpc(getCommandServiceStub().getCommand(request)); } - CommandServiceBlockingStub getCommandServiceStub() { - return commandServiceStub.withInterceptors(new OzgCloudCallContextAttachingInterceptor(contextProvider)); - } - void verifyCommand(OzgCloudCommand command) { if (OzgCloudCommandStatus.ERROR.equals(command.getStatus())) { throw new TechnicalException("Command (id=%s) failed: %s".formatted(command.getId(), command.getErrorMessage())); } } + + public List<OzgCloudCommand> addSubCommands(OzgCloudCreateSubCommandsRequest request) { + var response = getCommandServiceStub().addSubCommands(mapper.toAddSubCommandsRequest(request)); + return response.getCommandList().stream().map(mapper::fromGrpc).toList(); + } + + CommandServiceBlockingStub getCommandServiceStub() { + return commandServiceStub.withInterceptors(new OzgCloudCallContextAttachingInterceptor(contextProvider)); + } } 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 index 1842021b2cba2e0676c3ac0eb9669be7a89eb954..c33ed1a91d16940f522e7113d25e1a8bd74679c8 100644 --- 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 @@ -25,9 +25,6 @@ public interface OzgCloudCommandMapper { @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) diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/GrpcCreateCommandTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/GrpcCreateCommandTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..0c3f9fb4c3500191295f97e8365f72e6b38f6b75 --- /dev/null +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/GrpcCreateCommandTestFactory.java @@ -0,0 +1,24 @@ +package de.ozgcloud.apilib.common.command; + +import de.ozgcloud.apilib.common.command.grpc.OzgCloudCommandTestFactory; +import de.ozgcloud.vorgang.common.GrpcObject; +import de.ozgcloud.vorgang.common.GrpcProperty; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommand; + +public class GrpcCreateCommandTestFactory { + + public static final GrpcObject BODY_OBJ = GrpcObject.newBuilder().addProperty( + GrpcProperty.newBuilder().setName(OzgCloudCommandTestFactory.BODY_FIELD_NAME).addValue(OzgCloudCommandTestFactory.BODY_FIELD_VALUE)).build(); + + public static GrpcCreateCommand creatio() { + return createBuilder().build(); + } + + public static GrpcCreateCommand.Builder createBuilder() { + return GrpcCreateCommand.newBuilder() + .setOrder(OzgCloudCommandTestFactory.ORDER) + .setRelationId(OzgCloudCommandTestFactory.RELATION_ID.toString()) + .setRelationVersion(OzgCloudCommandTestFactory.RELATION_VERSION) + .setBodyObj(BODY_OBJ); + } +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/OzgCloudCreateSubCommandsRequestTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/OzgCloudCreateSubCommandsRequestTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..df866f5efb4938593a310797de110d8ec457976c --- /dev/null +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/OzgCloudCreateSubCommandsRequestTestFactory.java @@ -0,0 +1,23 @@ +package de.ozgcloud.apilib.common.command; + +import de.ozgcloud.apilib.common.command.OzgCloudCreateSubCommandsRequest.OzgCloudCreateSubCommandsRequestBuilder; +import de.ozgcloud.apilib.common.command.grpc.OzgCloudCommandTestFactory; + +public class OzgCloudCreateSubCommandsRequestTestFactory { + + public static final String PARENT_ID = "parent-id"; + public static final String EXECUTION_MODE = "PARALLEL"; + public static final boolean COMPLETED_IF_SUBS_COMPLETED = true; + + public static OzgCloudCreateSubCommandsRequest create() { + return createBuilder().build(); + } + + public static OzgCloudCreateSubCommandsRequestBuilder createBuilder() { + return OzgCloudCreateSubCommandsRequest.builder() + .parentId(PARENT_ID) + .executionMode(EXECUTION_MODE) + .completedIfSubsCompleted(COMPLETED_IF_SUBS_COMPLETED) + .subCommand(OzgCloudCommandTestFactory.create()); + } +} diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/CommandMapperTest.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/CommandMapperTest.java index 66253a5867d3c5be5f61aff46fdd0569f88cd1c4..95e20408924b573fc11d09354ff2bae2639440f0 100644 --- a/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/CommandMapperTest.java +++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/common/command/grpc/CommandMapperTest.java @@ -1,14 +1,27 @@ package de.ozgcloud.apilib.common.command.grpc; import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; + +import de.ozgcloud.apilib.common.command.GrpcCreateCommandTestFactory; +import de.ozgcloud.apilib.common.command.OzgCloudCommand; +import de.ozgcloud.apilib.common.command.OzgCloudCreateSubCommandsRequestTestFactory; +import de.ozgcloud.vorgang.grpc.command.GrpcCreateCommand; class CommandMapperTest { + @Spy @InjectMocks private CommandMapper mapper = Mappers.getMapper(CommandMapper.class); @@ -34,4 +47,83 @@ class CommandMapperTest { } } + @Nested + class TestToAddSubCommandsRequest { + + @Captor + private ArgumentCaptor<List<OzgCloudCommand>> subCommandsCaptor; + + @Test + void shouldMapParentId() { + var request = mapper.toAddSubCommandsRequest(OzgCloudCreateSubCommandsRequestTestFactory.create()); + + assertThat(request.getParentId()).isEqualTo(OzgCloudCreateSubCommandsRequestTestFactory.PARENT_ID); + } + + @Test + void shouldMapExecutionMode() { + var request = mapper.toAddSubCommandsRequest(OzgCloudCreateSubCommandsRequestTestFactory.create()); + + assertThat(request.getExecutionMode()).isEqualTo(OzgCloudCreateSubCommandsRequestTestFactory.EXECUTION_MODE); + } + + @Test + void shouldMapCompletedIfSubsCompleted() { + var request = mapper.toAddSubCommandsRequest(OzgCloudCreateSubCommandsRequestTestFactory.create()); + + assertThat(request.getCompletedIfSubsCompleted()).isEqualTo(OzgCloudCreateSubCommandsRequestTestFactory.COMPLETED_IF_SUBS_COMPLETED); + } + + @Test + void shouldCallMapSubCommands() { + var subCommand = OzgCloudCommandTestFactory.create(); + var createSubCommandsRequest = OzgCloudCreateSubCommandsRequestTestFactory.createBuilder().clearSubCommands().subCommand(subCommand) + .build(); + + mapper.toAddSubCommandsRequest(createSubCommandsRequest); + + verify(mapper).toCreateCommands(subCommandsCaptor.capture()); + assertThat(subCommandsCaptor.getValue()).containsExactly(subCommand); + } + } + + @Nested + class TestToCreateCommands { + + @Mock + private GrpcCreateCommand createCommand; + + @Test + void shouldCallToCreateCommandRequest() { + var subCommand = OzgCloudCommandTestFactory.create(); + + mapper.toCreateCommands(List.of(subCommand)); + + verify(mapper).toCreateCommand(subCommand); + } + + @Test + void shouldReturnResult() { + var subCommand = OzgCloudCommandTestFactory.create(); + doReturn(createCommand).when(mapper).toCreateCommand(subCommand); + + var result = mapper.toCreateCommands(List.of(subCommand)); + + assertThat(result).containsExactly(createCommand); + } + } + + @Nested + class TestToCreateCommand { + + @Test + void shouldMap() { + var command = OzgCloudCommandTestFactory.create(); + + var result = mapper.toCreateCommand(command); + + assertThat(result).usingRecursiveComparison().isEqualTo(GrpcCreateCommandTestFactory.creatio()); + } + + } } 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 index fa820c62f6acbc2d40e755a9b08a61b309c68b31..83f1e3eed2402fa8ec9c6ae8d6849101aa0fde36 100644 --- 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 @@ -5,6 +5,8 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.List; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -14,8 +16,12 @@ import org.mockito.Mockito; import de.ozgcloud.apilib.common.callcontext.OzgCloudCallContextProvider; import de.ozgcloud.apilib.common.command.OzgCloudCommand; import de.ozgcloud.apilib.common.command.OzgCloudCommandStatus; +import de.ozgcloud.apilib.common.command.OzgCloudCreateSubCommandsRequestTestFactory; import de.ozgcloud.common.errorhandling.TechnicalException; import de.ozgcloud.vorgang.grpc.command.CommandServiceGrpc.CommandServiceBlockingStub; +import de.ozgcloud.vorgang.grpc.command.GrpcAddSubCommandsRequest; +import de.ozgcloud.vorgang.grpc.command.GrpcCommand; +import de.ozgcloud.vorgang.grpc.command.GrpcCommandsResponse; class GrpcOzgCloudCommandServiceTest { @@ -130,4 +136,68 @@ class GrpcOzgCloudCommandServiceTest { } } + + @Nested + class TestAddSubCommands { + + private static final GrpcCommand GRPC_COMMAND = GrpcCommandTestFactory.create(); + + @Mock + private GrpcCommandsResponse commandsResponse; + @Mock + private GrpcAddSubCommandsRequest grpcAddSubCommandsRequest; + + @BeforeEach + void init() { + doReturn(serviceStub).when(service).getCommandServiceStub(); + when(serviceStub.addSubCommands(any())).thenReturn(commandsResponse); + when(commandsResponse.getCommandList()).thenReturn(List.of(GRPC_COMMAND)); + } + + @Test + void shouldCallGetCommandServiceStub() { + addSubCommands(); + + verify(service).getCommandServiceStub(); + } + + @Test + void shouldCallMapToAddSubcommandsRequest() { + var request = OzgCloudCreateSubCommandsRequestTestFactory.create(); + + service.addSubCommands(request); + + verify(mapper).toAddSubCommandsRequest(request); + } + + @Test + void shouldCallAddSubCommands() { + when(mapper.toAddSubCommandsRequest(any())).thenReturn(grpcAddSubCommandsRequest); + + addSubCommands(); + + verify(serviceStub).addSubCommands(grpcAddSubCommandsRequest); + } + + @Test + void shouldCallMapFromGrpc() { + addSubCommands(); + + verify(mapper).fromGrpc(GRPC_COMMAND); + } + + @Test + void shouldReturnResult() { + var createdCommand = OzgCloudCommandTestFactory.create(); + when(mapper.fromGrpc(any())).thenReturn(createdCommand); + + var result = addSubCommands(); + + assertThat(result).containsExactly(createdCommand); + } + + private List<OzgCloudCommand> addSubCommands() { + return service.addSubCommands(OzgCloudCreateSubCommandsRequestTestFactory.create()); + } + } } \ No newline at end of file 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 index 7f6910fbe28e73301a6aa589fcd828b613858363..2cdfe300aa1bc38547c14b57d8fed00ed4ce787d 100644 --- 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 @@ -31,7 +31,7 @@ public class OzgCloudCommandTestFactory { public static final String BODY_FIELD_NAME = "FIELD"; public static final String BODY_FIELD_VALUE = "42"; - private static final Map<String, Object> BODY = Map.of(BODY_FIELD_NAME, BODY_FIELD_VALUE); + public static final Map<String, Object> BODY = Map.of(BODY_FIELD_NAME, BODY_FIELD_VALUE); public static final String CREATED_RESOURCE = UUID.randomUUID().toString(); public static final OzgCloudUserId CREATED_BY = OzgCloudUserId.from(UUID.randomUUID().toString()); public static final String CREATED_BY_NAME = "Dorothea Dow"; diff --git a/pom.xml b/pom.xml index 0a2dc79b15e1c7744760dd4a1e037cc7a18dd5de..7b38c436fefd64134ca22dd031ec1285f0983f0d 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ <parent> <groupId>de.ozgcloud.common</groupId> <artifactId>ozgcloud-common-dependencies</artifactId> - <version>4.2.0</version> + <version>4.3.0</version> <relativePath /> <!-- lookup parent from repository --> </parent> @@ -28,7 +28,7 @@ <failsafe-plugin.version>3.2.2</failsafe-plugin.version> <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version> - <vorgang-manager.version>2.5.0</vorgang-manager.version> + <vorgang-manager.version>2.11.0-SNAPSHOT</vorgang-manager.version> <user-manager.version>2.1.0</user-manager.version> </properties>