diff --git a/CHANGELOG.md b/CHANGELOG.md index c08433c62..c15c792f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog All notable changes to this project will be documented in this file. + +## [5.14.0](https://github.com/Backbase/stream-services/compare/5.13.0...5.14.0) +### Changed +- Updated arrangement-manager service-api from v2 to v3 + ## [5.13.0](https://github.com/Backbase/stream-services/compare/5.12.0...5.13.0) ### Changed - Bumping Backbase BOM to 2024.09-LTS @@ -9,7 +14,6 @@ All notable changes to this project will be documented in this file. ### Added - Adding additional pmts mappings - ## [5.11.1](https://github.com/Backbase/stream-services/compare/5.11.0...5.11.1) ### Changed - Updated plan-manager service api from 0.5.0 to 0.9.0 diff --git a/pom.xml b/pom.xml index d9c09cf8d..975402493 100644 --- a/pom.xml +++ b/pom.xml @@ -5,13 +5,13 @@ com.backbase.buildingblocks backbase-parent - 17.0.0 + 17.1.0 com.backbase.stream stream-services - 5.13.0 + 5.14.0 pom Stream :: Services diff --git a/stream-access-control/access-control-core/src/main/java/com/backbase/stream/service/EntitlementsService.java b/stream-access-control/access-control-core/src/main/java/com/backbase/stream/service/EntitlementsService.java index 0ac07426a..e9087bd4e 100644 --- a/stream-access-control/access-control-core/src/main/java/com/backbase/stream/service/EntitlementsService.java +++ b/stream-access-control/access-control-core/src/main/java/com/backbase/stream/service/EntitlementsService.java @@ -1,16 +1,15 @@ package com.backbase.stream.service; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; import com.backbase.stream.exceptions.UserNotFoundException; import com.backbase.stream.legalentity.model.AssignedPermission; +import com.backbase.stream.legalentity.model.BaseProductGroup.ProductGroupTypeEnum; import com.backbase.stream.legalentity.model.LegalEntity; -import com.backbase.stream.legalentity.model.ProductGroup; import com.backbase.stream.legalentity.model.ServiceAgreement; import com.backbase.stream.legalentity.model.User; import com.backbase.stream.product.service.ArrangementService; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import reactor.core.publisher.Flux; @@ -71,42 +70,10 @@ private Flux getAssignedPermissionForServiceAgreement( .map(products -> setAssignedPermissionForArrangements(permission, products))); } - /** - * Get All Products a legal entity has access to. - * - * @param legalEntityId Internal Legal Entity Id - * @return List of Products - */ - public Flux getProductsForInternalLegalEntityId(String legalEntityId) { - return legalEntityService.getMasterServiceAgreementForInternalLegalEntityId(legalEntityId) - .flatMapMany(sa -> accessGroupService.getDataGroupItemIdsByServiceAgreementId(sa.getInternalId()) - .flatMap(arrangementService::getArrangement) - ); - } - - /** - * Get All Products a legal entity has access to. - * - * @param legalEntityId External Legal Entity Id - * @return List of Products - */ - public Flux getProductsForExternalLegalEntityId(String legalEntityId) { - return legalEntityService.getLegalEntityByExternalId(legalEntityId).flux() - .flatMap(legalEntity -> getProductsForInternalLegalEntityId(legalEntity.getInternalId())); - } - - private AssignedPermission setAssignedPermissionForJourneys(AssignedPermission permission, List externalIds, - ProductGroup.ProductGroupTypeEnum productGroupTypeEnum) { - permission.setPermittedObjectExternalIds(externalIds); - return permission; - } - private AssignedPermission setAssignedPermissionForArrangements(AssignedPermission permission, - List products) { - List externalIds = products.stream().map(AccountArrangementItem::getExternalArrangementId) - .collect(Collectors.toList()); - permission.setPermittedObjects( - Collections.singletonMap(ProductGroup.ProductGroupTypeEnum.ARRANGEMENTS.name(), products)); + List products) { + List externalIds = products.stream().map(ArrangementItem::getExternalArrangementId).toList(); + permission.setPermittedObjects(Collections.singletonMap(ProductGroupTypeEnum.ARRANGEMENTS.name(), products)); permission.setPermittedObjectExternalIds(externalIds); return permission; } @@ -115,9 +82,7 @@ public Mono> getLegalEntityForUserName(String username return userService.getUserByExternalId(username) .doOnNext(user -> log.info("Found user: {} for username: {}", user.getInternalId(), username)) .switchIfEmpty(Mono.error(new UserNotFoundException("User not found for username: " + username))) - .flatMap(user -> { - return Mono.just(user).zipWith(legalEntityService.getLegalEntityByInternalId(user.getLegalEntityId())); - }); + .flatMap(user -> Mono.just(user).zipWith(legalEntityService.getLegalEntityByInternalId(user.getLegalEntityId()))); } diff --git a/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/mapper/ArrangementMapper.java b/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/mapper/ArrangementMapper.java index 995980391..6628cc056 100644 --- a/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/mapper/ArrangementMapper.java +++ b/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/mapper/ArrangementMapper.java @@ -1,18 +1,33 @@ package com.backbase.stream.compositions.product.core.mapper; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; +import org.mapstruct.AfterMapping; import org.mapstruct.InjectionStrategy; import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; import org.springframework.stereotype.Component; @Component @Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR) public interface ArrangementMapper { - com.backbase.stream.compositions.product.api.model.AccountArrangementItemPut mapStreamToComposition( - com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut arrangement); - com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut mapIntegrationToStream( - com.backbase.stream.compositions.product.integration.client.model.AccountArrangementItemPut arrangementItem); + com.backbase.stream.compositions.product.api.model.AccountArrangementItemPut mapStreamToComposition(ArrangementPutItem arrangement); + + ArrangementPutItem mapIntegrationToStream(com.backbase.stream.compositions.product.integration.client.model.AccountArrangementItemPut arrangementItem); + + ArrangementPutItem mapCompositionToStream(com.backbase.stream.compositions.product.api.model.AccountArrangementItemPut arrangementItem); + + /** + * The following after mapping has been set because the models are initializing both internalLegalEntities + * and externalLegalEntities fields, which are Sets, and they need to have at least 1 element. For this scenario + * if we do not set them as null, the validation rejects them. + * + * @param arrangementPutItem {@link ArrangementPutItem} instance to be used for data ingestion + */ + @AfterMapping + default void setNullLegalEntities(@MappingTarget ArrangementPutItem arrangementPutItem) { + arrangementPutItem.setInternalLegalEntities(null); + arrangementPutItem.setExternalLegalEntities(null); + } - com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut mapCompositionToStream( - com.backbase.stream.compositions.product.api.model.AccountArrangementItemPut arrangementItem); } diff --git a/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/model/ArrangementIngestPushRequest.java b/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/model/ArrangementIngestPushRequest.java index 5405d9208..e40c672b9 100644 --- a/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/model/ArrangementIngestPushRequest.java +++ b/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/model/ArrangementIngestPushRequest.java @@ -1,6 +1,6 @@ package com.backbase.stream.compositions.product.core.model; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -11,7 +11,7 @@ @Builder(toBuilder = true) @AllArgsConstructor public class ArrangementIngestPushRequest { - private AccountArrangementItemPut arrangement; + private ArrangementPutItem arrangement; private String arrangementInternalId; private String source; private RequestConfig config; diff --git a/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/model/ArrangementIngestResponse.java b/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/model/ArrangementIngestResponse.java index f8a07c2d0..d04407c01 100644 --- a/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/model/ArrangementIngestResponse.java +++ b/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/model/ArrangementIngestResponse.java @@ -1,6 +1,6 @@ package com.backbase.stream.compositions.product.core.model; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -11,7 +11,7 @@ @Builder(toBuilder = true) @AllArgsConstructor public class ArrangementIngestResponse { - private AccountArrangementItemPut arrangement; + private ArrangementPutItem arrangement; private String arrangementInternalId; private String source; private RequestConfig config; diff --git a/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/service/impl/ArrangementIngestionServiceImpl.java b/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/service/impl/ArrangementIngestionServiceImpl.java index d50834404..1a9bf01d2 100644 --- a/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/service/impl/ArrangementIngestionServiceImpl.java +++ b/stream-compositions/services/product-composition-service/src/main/java/com/backbase/stream/compositions/product/core/service/impl/ArrangementIngestionServiceImpl.java @@ -2,7 +2,7 @@ import com.backbase.buildingblocks.presentation.errors.BadRequestException; import com.backbase.buildingblocks.presentation.errors.Error; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; import com.backbase.stream.compositions.product.core.model.ArrangementIngestPullRequest; import com.backbase.stream.compositions.product.core.model.ArrangementIngestPushRequest; import com.backbase.stream.compositions.product.core.model.ArrangementIngestResponse; @@ -68,7 +68,7 @@ public Mono pushArrangement(ArrangementIngestPushRequ } private Mono validate(ArrangementIngestResponse res) { - Set> violations = validator.validate(res.getArrangement()); + Set> violations = validator.validate(res.getArrangement()); if (!CollectionUtils.isEmpty(violations)) { List errors = violations.stream().map(c -> new Error() diff --git a/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/core/mapper/ArrangementRestMapperTest.java b/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/core/mapper/ArrangementRestMapperTest.java index 45e06ec37..4929374d9 100644 --- a/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/core/mapper/ArrangementRestMapperTest.java +++ b/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/core/mapper/ArrangementRestMapperTest.java @@ -1,6 +1,15 @@ package com.backbase.stream.compositions.product.core.mapper; -import com.backbase.stream.compositions.product.api.model.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import com.backbase.stream.compositions.product.api.model.AccountArrangementItemPut; +import com.backbase.stream.compositions.product.api.model.ArrangementIngestionConfig; +import com.backbase.stream.compositions.product.api.model.ArrangementIngestionResponse; +import com.backbase.stream.compositions.product.api.model.ArrangementPullIngestionRequest; +import com.backbase.stream.compositions.product.api.model.ArrangementPushIngestionRequest; import com.backbase.stream.compositions.product.core.model.ArrangementIngestPullRequest; import com.backbase.stream.compositions.product.core.model.ArrangementIngestPushRequest; import com.backbase.stream.compositions.product.core.model.ArrangementIngestResponse; @@ -12,11 +21,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.ResponseEntity; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - @ExtendWith(MockitoExtension.class) class ArrangementRestMapperTest { private static final String ARRANGEMENT_ID = "arrangementId"; @@ -37,7 +41,7 @@ void mapPushRequest() { AccountArrangementItemPut arrangementItemPut = new AccountArrangementItemPut(); when(arrangementMapper.mapCompositionToStream(arrangementItemPut)) - .thenReturn(new com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut()); + .thenReturn(new com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem()); when(chainsMapper.map(any())) .thenReturn(RequestConfig.builder().build()); @@ -79,8 +83,8 @@ void mapPullRequest() { @Test void mapResponse() { - com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut streamArrangement = - new com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut(); + com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem streamArrangement = + new com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem(); AccountArrangementItemPut compositionArrangement = new AccountArrangementItemPut(); @@ -89,7 +93,7 @@ void mapResponse() { ArrangementIngestResponse response = ArrangementIngestResponse .builder() - .arrangement(new com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut()) + .arrangement(new com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem()) .build(); ResponseEntity responseEntity = arrangementRestMapper.mapResponse(response); diff --git a/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/core/service/impl/ArrangementIntegrationServiceImplTest.java b/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/core/service/impl/ArrangementIntegrationServiceImplTest.java index 5039c9de4..d1c4679c9 100644 --- a/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/core/service/impl/ArrangementIntegrationServiceImplTest.java +++ b/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/core/service/impl/ArrangementIntegrationServiceImplTest.java @@ -1,11 +1,15 @@ package com.backbase.stream.compositions.product.core.service.impl; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + import com.backbase.stream.compositions.product.core.mapper.ArrangementMapper; import com.backbase.stream.compositions.product.core.model.ArrangementIngestPullRequest; import com.backbase.stream.compositions.product.core.model.ArrangementIngestResponse; import com.backbase.stream.compositions.product.integration.client.ArrangementIntegrationApi; import com.backbase.stream.compositions.product.integration.client.model.AccountArrangementItemPut; import com.backbase.stream.compositions.product.integration.client.model.PullArrangementResponse; +import java.util.Objects; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -14,9 +18,6 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - @ExtendWith(MockitoExtension.class) class ArrangementIntegrationServiceImplTest { @InjectMocks @@ -44,14 +45,12 @@ void pullArrangement_Success() { .name("name") ))); when(arrangementMapper.mapIntegrationToStream(any())) - .thenReturn(new com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut()); + .thenReturn(new com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem()); Mono responseMono = arrangementIntegrationService.pullArrangement(request); StepVerifier.create(responseMono) - .expectNextMatches(item -> { - return item != null; - }) + .expectNextMatches(Objects::nonNull) .verifyComplete(); } diff --git a/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/http/ProductControllerIT.java b/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/http/ProductControllerIT.java index 7de1fdd05..eb62cb90d 100644 --- a/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/http/ProductControllerIT.java +++ b/stream-compositions/services/product-composition-service/src/test/java/com/backbase/stream/compositions/product/http/ProductControllerIT.java @@ -1,6 +1,12 @@ package com.backbase.stream.compositions.product.http; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.mockserver.integration.ClientAndServer.startClientAndServer; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; import com.backbase.stream.compositions.paymentorder.client.model.PaymentOrderIngestionResponse; import com.backbase.stream.compositions.paymentorder.client.model.PaymentOrderPostResponse; import com.backbase.stream.compositions.product.api.model.ArrangementPullIngestionRequest; @@ -20,12 +26,16 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; import lombok.extern.slf4j.Slf4j; import org.apache.activemq.broker.BrokerService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockserver.client.MockServerClient; @@ -41,18 +51,6 @@ import org.springframework.test.web.reactive.server.WebTestClient; import reactor.core.publisher.Mono; -import java.io.IOException; -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; -import static org.mockserver.integration.ClientAndServer.startClientAndServer; -import static org.mockserver.model.HttpRequest.request; -import static org.mockserver.model.HttpResponse.response; - @DirtiesContext @SpringBootTest @AutoConfigureWebTestClient @@ -220,7 +218,7 @@ void pushIngestProduct_Success() throws Exception { @Test void pullIngestArrangement_Success() throws Exception { when(arrangementService.updateArrangement(any())) - .thenReturn(Mono.just(new AccountArrangementItemPut())); + .thenReturn(Mono.just(new ArrangementPutItem())); ArrangementPullIngestionRequest pullIngestionRequest = new ArrangementPullIngestionRequest() @@ -266,7 +264,7 @@ void pushIngestArrangement_Success() throws IOException { mapper.treeToValue(node, com.backbase.stream.compositions.product.api.model.AccountArrangementItemPut.class); when(arrangementService.updateArrangement(any())) - .thenReturn(Mono.just(new AccountArrangementItemPut())); + .thenReturn(Mono.just(new ArrangementPutItem())); ArrangementPushIngestionRequest pushIngestionRequest = new ArrangementPushIngestionRequest() diff --git a/stream-cursor/cursor-publishers/src/main/java/com/backbase/stream/cursor/events/AbstractLoginEventListener.java b/stream-cursor/cursor-publishers/src/main/java/com/backbase/stream/cursor/events/AbstractLoginEventListener.java index c1a006dc7..a00943602 100644 --- a/stream-cursor/cursor-publishers/src/main/java/com/backbase/stream/cursor/events/AbstractLoginEventListener.java +++ b/stream-cursor/cursor-publishers/src/main/java/com/backbase/stream/cursor/events/AbstractLoginEventListener.java @@ -1,6 +1,6 @@ package com.backbase.stream.cursor.events; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; import com.backbase.stream.TransactionService; import com.backbase.stream.cursor.configuration.CursorServiceConfigurationProperties; import com.backbase.stream.cursor.model.IngestionCursor; @@ -85,13 +85,11 @@ private Flux createIngestionCursor(User user, LegalEntity legal List ingestionCursors = new ArrayList<>(); ProductGroup.ProductGroupTypeEnum arrangements1 = ProductGroup.ProductGroupTypeEnum.ARRANGEMENTS; Object arrangements = assignedPermission.getPermittedObjects().get(arrangements1.name()); - if (arrangements instanceof List && (((List) arrangements).get(0) instanceof AccountArrangementItem)) { - List products = (List) arrangements; - - for (AccountArrangementItem product : products) { + if (arrangements instanceof List && (((List) arrangements).getFirst() instanceof ArrangementItem)) { + @SuppressWarnings("unchecked") List products = (List) arrangements; + for (ArrangementItem product : products) { IngestionCursor ingestionCursor = createLoginIngestionCursor(loginEvent, user, legalEntity); - ingestionCursor.setArrangementId(product.getId()); ingestionCursor.setExternalArrangementId(product.getExternalArrangementId()); // Make this configurable? diff --git a/stream-dbs-clients/pom.xml b/stream-dbs-clients/pom.xml index 1898899a5..6eefbbe2e 100644 --- a/stream-dbs-clients/pom.xml +++ b/stream-dbs-clients/pom.xml @@ -257,9 +257,22 @@ generate-sources REFACTOR_ALLOF_WITH_PROPERTIES_ONLY=true - ${project.build.directory}/yaml/arrangement-manager/arrangement-service-api-v2*.yaml - com.backbase.dbs.arrangement.api.service.v2 - com.backbase.dbs.arrangement.api.service.v2.model + ${project.build.directory}/yaml/arrangement-manager/arrangement-service-api-v3*.yaml + com.backbase.dbs.arrangement.api.service.v3 + com.backbase.dbs.arrangement.api.service.v3.model + + + + generate-arrangement-manager-integration-api-code + + generate-webclient-embedded + + generate-sources + + REFACTOR_ALLOF_WITH_PROPERTIES_ONLY=true + ${project.build.directory}/yaml/arrangement-manager/arrangement-integration-inbound-api-v2*.yaml + com.backbase.dbs.arrangement.api.integration.v2 + com.backbase.dbs.arrangement.api.integration.v2.model diff --git a/stream-dbs-clients/src/main/java/com/backbase/stream/clients/config/ArrangementManagerClientConfig.java b/stream-dbs-clients/src/main/java/com/backbase/stream/clients/config/ArrangementManagerClientConfig.java index 00a437457..069e528b3 100644 --- a/stream-dbs-clients/src/main/java/com/backbase/stream/clients/config/ArrangementManagerClientConfig.java +++ b/stream-dbs-clients/src/main/java/com/backbase/stream/clients/config/ArrangementManagerClientConfig.java @@ -1,9 +1,9 @@ package com.backbase.stream.clients.config; import com.backbase.dbs.arrangement.api.service.ApiClient; -import com.backbase.dbs.arrangement.api.service.v2.ArrangementsApi; -import com.backbase.dbs.arrangement.api.service.v2.ProductKindsApi; -import com.backbase.dbs.arrangement.api.service.v2.ProductsApi; +import com.backbase.dbs.arrangement.api.service.v3.ArrangementsApi; +import com.backbase.dbs.arrangement.api.service.v3.ProductKindsApi; +import com.backbase.dbs.arrangement.api.service.v3.ProductsApi; import com.fasterxml.jackson.databind.ObjectMapper; import java.text.DateFormat; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -28,12 +28,25 @@ public ApiClient arrangementManagerApiClient(ObjectMapper objectMapper, DateForm .setBasePath(createBasePath()); } + @Bean + @ConditionalOnMissingBean + public com.backbase.dbs.arrangement.api.integration.ApiClient arrangementApiIntegrationClient(ObjectMapper objectMapper, DateFormat dateFormat) { + return new com.backbase.dbs.arrangement.api.integration.ApiClient(getWebClient(), objectMapper, dateFormat) + .setBasePath(createBasePath()); + } + @Bean @ConditionalOnMissingBean public ArrangementsApi arrangementsApi(ApiClient arrangementManagerApiClient) { return new ArrangementsApi(arrangementManagerApiClient); } + @Bean + @ConditionalOnMissingBean + public com.backbase.dbs.arrangement.api.integration.v2.ArrangementsApi arrangementApiIntegration(com.backbase.dbs.arrangement.api.integration.ApiClient arrangementManagerIntegrationApiClient) { + return new com.backbase.dbs.arrangement.api.integration.v2.ArrangementsApi(arrangementManagerIntegrationApiClient); + } + @Bean @ConditionalOnMissingBean public ProductsApi productsApi(ApiClient arrangementManagerApiClient) { diff --git a/stream-legal-entity/legal-entity-bootstrap-task/src/test/resources/mappings/create-arrangements.json b/stream-legal-entity/legal-entity-bootstrap-task/src/test/resources/mappings/create-arrangements.json index 75ab36bde..9e7a05251 100644 --- a/stream-legal-entity/legal-entity-bootstrap-task/src/test/resources/mappings/create-arrangements.json +++ b/stream-legal-entity/legal-entity-bootstrap-task/src/test/resources/mappings/create-arrangements.json @@ -1,7 +1,7 @@ { "request": { "method": "POST", - "url": "/arrangement-manager/service-api/v2/arrangements/batch", + "url": "/arrangement-manager/integration-api/v2/arrangements/batch", "headers": { "X-B3-TraceId": { "matches": "[\\w-]+" @@ -18,19 +18,22 @@ "status": 207, "jsonBody": [ { - "resourceId": "021000021", - "arrangementId": "arrangement-id", - "status": 200 + "arrangementId" : "arrangement-id", + "action" : "add", + "resourceId" : "021000021", + "status" : "200" }, { - "resourceId": "021000022", - "arrangementId": "arrangement-id", - "status": 200 + "arrangementId" : "arrangement-id", + "action" : "add", + "resourceId" : "021000022", + "status" : "200" }, { - "resourceId": "021000023", - "arrangementId": "arrangement-id", - "status": 200 + "arrangementId" : "arrangement-id", + "action" : "add", + "resourceId" : "021000023", + "status" : "200" } ], "headers": { diff --git a/stream-legal-entity/legal-entity-core/src/test/java/com/backbase/stream/UpdatedServiceAgreementSagaTest.java b/stream-legal-entity/legal-entity-core/src/test/java/com/backbase/stream/UpdatedServiceAgreementSagaTest.java index cc0aa72a6..38bca6002 100644 --- a/stream-legal-entity/legal-entity-core/src/test/java/com/backbase/stream/UpdatedServiceAgreementSagaTest.java +++ b/stream-legal-entity/legal-entity-core/src/test/java/com/backbase/stream/UpdatedServiceAgreementSagaTest.java @@ -8,7 +8,7 @@ import static org.mockito.Mockito.when; import com.backbase.dbs.accesscontrol.api.service.v3.model.FunctionGroupItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; import com.backbase.dbs.user.api.service.v2.model.GetUser; import com.backbase.stream.legalentity.model.BaseProductGroup; import com.backbase.stream.legalentity.model.BatchProductGroup; @@ -108,7 +108,7 @@ void updateServiceAgreement() { when(arrangementService.getArrangementByExternalId(ArgumentMatchers.>any())) .thenReturn(Flux.fromIterable( - Collections.singletonList(new AccountArrangementItem().id(loanInId).externalArrangementId(loanExId)))); + Collections.singletonList(new ArrangementItem().id(loanInId).externalArrangementId(loanExId)))); UpdatedServiceAgreementTask actual = updatedServiceAgreementSaga.executeTask(task).block(); diff --git a/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/controller/ServiceAgreementControllerTest.java b/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/controller/ServiceAgreementControllerTest.java index 6ca8d59aa..df271a0b5 100644 --- a/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/controller/ServiceAgreementControllerTest.java +++ b/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/controller/ServiceAgreementControllerTest.java @@ -9,7 +9,7 @@ import com.backbase.dbs.accesscontrol.api.service.v3.LegalEntitiesApi; import com.backbase.dbs.accesscontrol.api.service.v3.model.FunctionGroupItem; -import com.backbase.dbs.arrangement.api.service.v2.ArrangementsApi; +import com.backbase.dbs.arrangement.api.service.v3.ArrangementsApi; import com.backbase.dbs.contact.api.service.v2.ContactsApi; import com.backbase.dbs.limit.api.service.v2.LimitsServiceApi; import com.backbase.dbs.user.api.service.v2.IdentityManagementApi; @@ -35,10 +35,9 @@ import com.backbase.stream.product.task.BatchProductGroupTask; import com.backbase.stream.product.task.ProductGroupTask; import com.backbase.stream.service.AccessGroupService; +import com.backbase.streams.tailoredvalue.PlansService; import java.net.URI; import java.util.List; - -import com.backbase.streams.tailoredvalue.PlansService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -111,7 +110,10 @@ class ServiceAgreementControllerTest { private com.backbase.dbs.user.profile.api.service.v2.UserProfileManagementApi userProfileManagement; @MockBean - private ArrangementsApi arrangementsApi; + private ArrangementsApi arrangementsApiV3; + + @MockBean + private com.backbase.dbs.arrangement.api.integration.v2.ArrangementsApi arrangementsApi; @MockBean private UserKindSegmentationSaga userKindSegmentationSaga; diff --git a/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/it/LegalEntitySagaIT.java b/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/it/LegalEntitySagaIT.java index c529d4712..0cb5e64c2 100644 --- a/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/it/LegalEntitySagaIT.java +++ b/stream-legal-entity/legal-entity-http/src/test/java/com/backbase/stream/it/LegalEntitySagaIT.java @@ -263,7 +263,7 @@ private void setupWireMock() { ); stubFor( - WireMock.post("/arrangement-manager/service-api/v2/arrangements/batch") + WireMock.post("/arrangement-manager/integration-api/v2/arrangements/batch") .willReturn(WireMock.aResponse().withStatus(HttpStatus.ACCEPTED.value())) ); diff --git a/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/config/PaymentOrderServiceConfiguration.java b/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/config/PaymentOrderServiceConfiguration.java index 5000d1a34..1962b7290 100644 --- a/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/config/PaymentOrderServiceConfiguration.java +++ b/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/config/PaymentOrderServiceConfiguration.java @@ -1,6 +1,6 @@ package com.backbase.stream.config; -import com.backbase.dbs.arrangement.api.service.v2.ArrangementsApi; +import com.backbase.dbs.arrangement.api.service.v3.ArrangementsApi; import com.backbase.dbs.paymentorder.api.service.v3.PaymentOrdersApi; import com.backbase.stream.PaymentOrderService; import com.backbase.stream.PaymentOrderServiceImpl; diff --git a/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/model/PaymentOrderIngestContext.java b/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/model/PaymentOrderIngestContext.java index 1e2beadcb..147f8ea60 100644 --- a/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/model/PaymentOrderIngestContext.java +++ b/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/model/PaymentOrderIngestContext.java @@ -1,12 +1,10 @@ package com.backbase.stream.model; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItems; -import java.util.ArrayList; -import java.util.List; - +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementSearchesListResponse; import com.backbase.dbs.paymentorder.api.service.v3.model.GetPaymentOrderResponse; import com.backbase.dbs.paymentorder.api.service.v3.model.PaymentOrderPostRequest; - +import java.util.ArrayList; +import java.util.List; import lombok.Data; import lombok.experimental.Accessors; @@ -17,5 +15,5 @@ public class PaymentOrderIngestContext { private String internalUserId; private List corePaymentOrder = new ArrayList<>(); private List existingPaymentOrder = new ArrayList<>(); - private List arrangementIds = new ArrayList<>(); + private List arrangementIds = new ArrayList<>(); } diff --git a/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/paymentorder/PaymentOrderUnitOfWorkExecutor.java b/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/paymentorder/PaymentOrderUnitOfWorkExecutor.java index e276864ee..e50fc310d 100644 --- a/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/paymentorder/PaymentOrderUnitOfWorkExecutor.java +++ b/stream-payment-order/payment-order-core/src/main/java/com/backbase/stream/paymentorder/PaymentOrderUnitOfWorkExecutor.java @@ -1,21 +1,22 @@ package com.backbase.stream.paymentorder; -import static java.time.temporal.ChronoUnit.MILLIS; -import static java.util.Collections.emptyList; -import static reactor.core.publisher.Flux.defer; -import static reactor.core.publisher.Flux.empty; -import static reactor.util.retry.Retry.fixedDelay; import static com.backbase.dbs.paymentorder.api.service.v3.model.Status.ACCEPTED; import static com.backbase.dbs.paymentorder.api.service.v3.model.Status.CANCELLATION_PENDING; import static com.backbase.dbs.paymentorder.api.service.v3.model.Status.CANCELLED; import static com.backbase.dbs.paymentorder.api.service.v3.model.Status.PROCESSED; import static com.backbase.dbs.paymentorder.api.service.v3.model.Status.READY; import static com.backbase.dbs.paymentorder.api.service.v3.model.Status.REJECTED; +import static java.time.temporal.ChronoUnit.MILLIS; +import static java.util.Collections.emptyList; +import static java.util.Optional.ofNullable; +import static reactor.core.publisher.Flux.defer; +import static reactor.core.publisher.Flux.empty; +import static reactor.util.retry.Retry.fixedDelay; -import com.backbase.dbs.arrangement.api.service.v2.ArrangementsApi; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItems; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementsFilter; +import com.backbase.dbs.arrangement.api.service.v3.ArrangementsApi; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementSearchesListResponse; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsSearchesPostRequest; import com.backbase.dbs.paymentorder.api.service.v3.model.AccessFilter; import com.backbase.dbs.paymentorder.api.service.v3.model.Status; import com.backbase.stream.config.PaymentOrderTypeConfiguration; @@ -24,6 +25,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -32,6 +34,7 @@ import com.backbase.dbs.paymentorder.api.service.v3.model.PaymentOrderPostFilterRequest; import com.backbase.dbs.paymentorder.api.service.v3.model.PaymentOrderPostFilterResponse; import com.backbase.dbs.paymentorder.api.service.v3.model.PaymentOrderPostRequest; +import com.backbase.dbs.paymentorder.api.service.v3.model.SimpleOriginatorAccount; import com.backbase.stream.config.PaymentOrderWorkerConfigurationProperties; import com.backbase.stream.mappers.PaymentOrderTypeMapper; import com.backbase.stream.model.PaymentOrderIngestContext; @@ -89,7 +92,7 @@ public Flux> prepareUnitOfWork(List> prepareUnitOfWork(Flux items) { return items.collectList() - .map(paymentOrderPostRequests -> this.createPaymentOrderIngestContext(paymentOrderPostRequests)) + .map(this::createPaymentOrderIngestContext) .flatMap(this::addArrangementIdMap) .flatMap(this::getPersistedScheduledTransfers) .flatMapMany(this::getPaymentOrderIngestRequest) @@ -134,10 +137,13 @@ private PaymentOrderIngestContext createPaymentOrderIngestContext(List paymentOrderIngestContext.arrangementIds(accountInternalIdGetResponseBody)); } - private Mono getArrangement(PaymentOrderPostRequest paymentOrderPostRequest) { - AccountArrangementsFilter accountArrangementsFilter = new AccountArrangementsFilter() - .externalArrangementIds(Collections.singleton(paymentOrderPostRequest.getOriginatorAccount().getExternalArrangementId())); - return arrangementsApi.postFilter(accountArrangementsFilter); + private Mono getArrangement(PaymentOrderPostRequest paymentOrderPostRequest) { + SimpleOriginatorAccount originatorAccount = paymentOrderPostRequest.getOriginatorAccount(); + if (originatorAccount == null) { + return Mono.empty(); + } + return arrangementsApi.postSearchArrangements(new ArrangementsSearchesPostRequest() + .externalArrangementIds(Collections.singleton(originatorAccount.getExternalArrangementId()))); } /** @@ -146,7 +152,7 @@ private Mono getArrangement(PaymentOrderPostRequest pay * @param arrangementIds Check for all the arrangements that belong to this PMT. * @return A Mono with the response from the service api. */ - private Mono getPayments(List arrangementIds) { + private Mono getPayments(List arrangementIds) { if (isEmptyArrangmetIds(arrangementIds)) { return Mono.just(new PaymentOrderPostFilterResponse().paymentOrders(emptyList()).totalElements(new BigDecimal(0))); @@ -154,7 +160,7 @@ private Mono getPayments(List allArrangementIds = arrangementIds .stream().flatMap(accountArrangementItems -> accountArrangementItems.getArrangementElements().stream()) - .map(AccountArrangementItem::getId) + .map(ArrangementItem::getId) .collect(Collectors.toList()); return pullFromDBS(allArrangementIds).map(result -> { @@ -191,10 +197,14 @@ private Flux getPaymentOrderIngestRequest(PaymentOrde // build new payment list (Bank ref is in core, but not in DBS) orders.forEach(corePaymentOrder -> { if(!existingBankRefIds.contains(corePaymentOrder.getBankReferenceId())) { - AccountArrangementItem accountArrangementItem = getInternalArrangementId(paymentOrderIngestContext.arrangementIds(), - corePaymentOrder.getOriginatorAccount().getExternalArrangementId()); - if (accountArrangementItem != null) { - corePaymentOrder.getOriginatorAccount().setArrangementId(accountArrangementItem.getId()); + SimpleOriginatorAccount simpleOriginatorAccount = corePaymentOrder.getOriginatorAccount(); + if (simpleOriginatorAccount == null) { + return; + } + ArrangementItem arrangementItem = getInternalArrangementId(paymentOrderIngestContext.arrangementIds(), + simpleOriginatorAccount.getExternalArrangementId()); + if (arrangementItem != null) { + simpleOriginatorAccount.setArrangementId(arrangementItem.getId()); } paymentOrderIngestRequests.add(new NewPaymentOrderIngestRequest(corePaymentOrder)); } @@ -224,10 +234,10 @@ private void buildDeletePaymentList(List existing, List } } - private AccountArrangementItem getInternalArrangementId(List accountArrangementItemsList, String externalArrangementId) { - + private ArrangementItem getInternalArrangementId(List accountArrangementItemsList, String externalArrangementId) { return accountArrangementItemsList.stream() .flatMap(a -> a.getArrangementElements().stream()) + .filter(b -> Objects.nonNull(b.getExternalArrangementId())) .filter(b -> b.getExternalArrangementId().equalsIgnoreCase(externalArrangementId)) .findFirst() .orElse(null); @@ -269,13 +279,15 @@ private Mono retrieveNextPage(int currentCount, final t -> t instanceof WebClientRequestException || t instanceof WebClientResponseException.ServiceUnavailable)) .map(resp -> { - final List results = resp.getPaymentOrders() == null ? emptyList() : resp.getPaymentOrders(); - final var total = resp.getTotalElements() == null ? new BigDecimal(0).intValue() : resp.getTotalElements().intValue(); + // getPaymentOrders() is marked with @NotNull, dunno why still checking its nullability? + final List results = ofNullable(resp.getPaymentOrders()).orElse(emptyList()); + // getTotalElements() is marked with @NotNull, dunno why still checking its nullability? + final var total = ofNullable(resp.getTotalElements()).orElse(new BigDecimal(0)).intValue(); return new DBSPaymentOrderPageResult(currentCount + results.size(), total, results); }); } - private boolean isEmptyArrangmetIds(List arrangementItems) { + private boolean isEmptyArrangmetIds(List arrangementItems) { return arrangementItems == null || arrangementItems.isEmpty(); } @@ -287,7 +299,7 @@ private String getInternalUserId(List paymentOrderPostR if (paymentOrderPostRequests == null || paymentOrderPostRequests.isEmpty()) { return null; } else { - return paymentOrderPostRequests.get(0).getInternalUserId(); + return paymentOrderPostRequests.getFirst().getInternalUserId(); } } } diff --git a/stream-payment-order/payment-order-core/src/test/java/com/backbase/stream/task/PaymentOrderUnitOfWorkExecutorTest.java b/stream-payment-order/payment-order-core/src/test/java/com/backbase/stream/task/PaymentOrderUnitOfWorkExecutorTest.java index c344f1080..40ee00533 100644 --- a/stream-payment-order/payment-order-core/src/test/java/com/backbase/stream/task/PaymentOrderUnitOfWorkExecutorTest.java +++ b/stream-payment-order/payment-order-core/src/test/java/com/backbase/stream/task/PaymentOrderUnitOfWorkExecutorTest.java @@ -6,9 +6,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.lenient; -import com.backbase.dbs.arrangement.api.service.v2.ArrangementsApi; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItems; +import com.backbase.dbs.arrangement.api.service.v3.ArrangementsApi; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementSearchesListResponse; import com.backbase.dbs.paymentorder.api.service.v3.PaymentOrdersApi; import com.backbase.dbs.paymentorder.api.service.v3.model.GetPaymentOrderResponse; import com.backbase.dbs.paymentorder.api.service.v3.model.PaymentOrderPostFilterResponse; @@ -32,7 +32,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; @@ -87,22 +86,22 @@ void test_prepareUnitOfWork_paymentOrderIngestRequestList() { lenient().when(paymentOrdersApi.postPaymentOrder(Mockito.any())) .thenReturn(Mono.just(paymentOrderPostResponse)); - AccountArrangementItem accountArrangementItem = new AccountArrangementItem() + ArrangementItem arrangementItem = new ArrangementItem() .id("arrangementId_1") .externalArrangementId("externalArrangementId_1"); - AccountArrangementItems accountArrangementItems = new AccountArrangementItems() - .addArrangementElementsItem(accountArrangementItem); + ArrangementSearchesListResponse arrangementSearchesListResponse = new ArrangementSearchesListResponse() + .addArrangementElementsItem(arrangementItem); - lenient().when(arrangementsApi.postFilter(Mockito.any())) - .thenReturn(Mono.just(accountArrangementItems)); + Mockito.lenient().when(arrangementsApi.postSearchArrangements(Mockito.any())) + .thenReturn(Mono.just(arrangementSearchesListResponse)); StepVerifier.create(paymentOrderUnitOfWorkExecutor.prepareUnitOfWork(paymentOrderIngestRequestList)) .assertNext(unitOfWork -> { Assertions.assertTrue(unitOfWork.getUnitOfOWorkId().startsWith("payment-orders-mixed-")); Assertions.assertEquals(UnitOfWork.State.NEW, unitOfWork.getState()); Assertions.assertEquals(1, unitOfWork.getStreamTasks().size()); - Assertions.assertEquals(paymentOrderIngestRequestList.size(), unitOfWork.getStreamTasks().get(0).getData().size()); + Assertions.assertEquals(paymentOrderIngestRequestList.size(), unitOfWork.getStreamTasks().getFirst().getData().size()); }) .verifyComplete(); } @@ -126,21 +125,22 @@ void test_prepareUnitOfWork_paymentOrderPostRequestFlux() { doReturn(Mono.just(paymentOrderPostFilterResponse)).when(paymentOrdersApi).postFilterPaymentOrders(any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); - AccountArrangementItem accountArrangementItem = new AccountArrangementItem() - .id("arrangementId_1") - .externalArrangementId("externalArrangementId_1"); - AccountArrangementItems accountArrangementItems = new AccountArrangementItems() - .addArrangementElementsItem(accountArrangementItem); + ArrangementItem arrangementItem = new ArrangementItem() + .id("arrangementId_1") + .externalArrangementId("externalArrangementId_1"); - Mockito.when(arrangementsApi.postFilter(Mockito.any())) - .thenReturn(Mono.just(accountArrangementItems)); + ArrangementSearchesListResponse arrangementSearchesListResponse = new ArrangementSearchesListResponse() + .addArrangementElementsItem(arrangementItem); + + Mockito.lenient().when(arrangementsApi.postSearchArrangements(Mockito.any())) + .thenReturn(Mono.just(arrangementSearchesListResponse)); StepVerifier.create(paymentOrderUnitOfWorkExecutor.prepareUnitOfWork(paymentOrderPostRequestFlux)) .assertNext(unitOfWork -> { Assertions.assertTrue(unitOfWork.getUnitOfOWorkId().startsWith("payment-orders-mixed-")); Assertions.assertEquals(UnitOfWork.State.NEW, unitOfWork.getState()); Assertions.assertEquals(1, unitOfWork.getStreamTasks().size()); - Assertions.assertEquals(paymentOrderPostRequest.size(), unitOfWork.getStreamTasks().get(0).getData().size()); + Assertions.assertEquals(paymentOrderPostRequest.size(), unitOfWork.getStreamTasks().getFirst().getData().size()); }) .verifyComplete(); } @@ -152,19 +152,20 @@ void test_prepareunitofwork_blankuserid() { repository, streamTaskExecutor, streamWorkerConfiguration, paymentOrdersApi, arrangementsApi, null, paymentOrderTypeConfiguration); - paymentOrderPostRequest.get(0).setInternalUserId(StringUtils.EMPTY); + paymentOrderPostRequest.getFirst().setInternalUserId(StringUtils.EMPTY); paymentOrderPostRequest.get(1).setInternalUserId(null); Flux paymentOrderPostRequestFlux = Flux.fromIterable(paymentOrderPostRequest); - AccountArrangementItem accountArrangementItem = new AccountArrangementItem() + ArrangementItem arrangementItem = new ArrangementItem() .id("arrangementId_1") .externalArrangementId("externalArrangementId_1"); - AccountArrangementItems accountArrangementItems = new AccountArrangementItems() - .addArrangementElementsItem(accountArrangementItem); - lenient().when(arrangementsApi.postFilter(Mockito.any())) - .thenReturn(Mono.just(accountArrangementItems)); + ArrangementSearchesListResponse arrangementSearchesListResponse = new ArrangementSearchesListResponse() + .addArrangementElementsItem(arrangementItem); + + lenient().when(arrangementsApi.postSearchArrangements(Mockito.any())) + .thenReturn(Mono.just(arrangementSearchesListResponse)); GetPaymentOrderResponse getPaymentOrderResponseWithEmptyUserId = new GetPaymentOrderResponse() .id("arrangementId_1"); diff --git a/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/ReactiveProductCatalogService.java b/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/ReactiveProductCatalogService.java index 3c4ca7fa6..f2b046125 100644 --- a/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/ReactiveProductCatalogService.java +++ b/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/ReactiveProductCatalogService.java @@ -1,12 +1,9 @@ package com.backbase.stream.productcatalog; -import com.backbase.dbs.arrangement.api.service.v2.ProductKindsApi; -import com.backbase.dbs.arrangement.api.service.v2.ProductsApi; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountProductId; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountProductKindId; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountSchemasProductItem; -import com.backbase.dbs.arrangement.api.service.v2.model.ExternalProductKindItemExtended; -import com.backbase.dbs.arrangement.api.service.v2.model.ExternalProductKindItemPut; +import com.backbase.dbs.arrangement.api.service.v3.ProductKindsApi; +import com.backbase.dbs.arrangement.api.service.v3.ProductsApi; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementProductsListResponse; +import com.backbase.dbs.arrangement.api.service.v3.model.ResourceAddPostResponse; import com.backbase.stream.productcatalog.mapper.ProductCatalogMapper; import com.backbase.stream.productcatalog.model.ProductCatalog; import com.backbase.stream.productcatalog.model.ProductKind; @@ -42,8 +39,9 @@ public class ReactiveProductCatalogService { public Mono getProductCatalog() { Flux productKindsFlux = getProductKindFlux(); - Flux products = productsApi.getProducts(null, null); - Flux productTypesFlux = products.map(productCatalogMapper::toStream); + Flux productTypesFlux = productsApi.getProducts(null, null) + .flatMapIterable(ArrangementProductsListResponse::getArrangementProductElements) + .map(productCatalogMapper::toStream); return Mono.zip(productKindsFlux.collectList(), productTypesFlux.collectList()) .map(tuple -> new ProductCatalog().productTypes(tuple.getT2()).productKinds(tuple.getT1())) @@ -53,9 +51,7 @@ public Mono getProductCatalog() { private Flux getProductKindFlux() { return productKindsApi.getProductKinds(null, null, null) .flux() - .flatMap(productKindsWrapper -> Flux.fromIterable(productKindsWrapper.getProductKinds() != null - ? productKindsWrapper.getProductKinds() - : new ArrayList<>())) + .flatMap(productKindsWrapper -> Flux.fromIterable(productKindsWrapper.getProductKindElements())) .map(productCatalogMapper::toStream); } @@ -85,24 +81,18 @@ public Mono setupProductCatalog(ProductCatalog productCatalog) { .collect(Collectors.toList()); } - Flux productKindFlux = storeProductKinds(newProductKinds) - .mergeWith(getProductKindFlux()); - // Ensure products kinds are created first List finalNewProductTypes = newProductTypes; - return productKindFlux.collectList().flatMap(productKinds -> { - return createProductTypes(finalNewProductTypes, productKinds).collectList().flatMap(productTypes -> { - productCatalog.setProductTypes(productTypes); - return Mono.just(productCatalog); - }); - }); + return getProductKindFlux().collectList().flatMap(productKinds -> createProductTypes(finalNewProductTypes, productKinds).collectList().flatMap(productTypes -> { + productCatalog.setProductTypes(productTypes); + return Mono.just(productCatalog); + })); }); } - - /** - * Setup Product Catalog from Aggregate. + * Setup Product Catalog from Aggregate. It does not update Product Kinds since Product Kinds + * are static and should be managed through YAML settings file. * * @param productCatalog Product Catalog * @return Completed Product Catalog @@ -110,27 +100,14 @@ public Mono setupProductCatalog(ProductCatalog productCatalog) { public Mono updateExistingProductCatalog(ProductCatalog productCatalog) { return getProductCatalog().flatMap(existingProductCatalog -> { - List existingProductKinds = productCatalog.getProductKinds().stream() - .filter(existingProductKind -> existingProductCatalog.getProductKinds().stream() - .anyMatch(productKind -> - productKind.getExternalKindId().equals(existingProductKind.getExternalKindId()))) - .collect(Collectors.toList()); List existingProductTypes = productCatalog.getProductTypes().stream() .filter(existingProductType -> existingProductCatalog.getProductTypes().stream() .anyMatch(productType -> productType.getExternalProductId().equals(existingProductType.getExternalProductId()))) - .collect(Collectors.toList()); - - Flux existingProductKindFlux = updateProductKind(existingProductKinds).map(productCatalogMapper::toStream) - .map(productCatalogMapper::toStream).mergeWith(getProductKindFlux()); - - return existingProductKindFlux.collectList().flatMap( - productKinds -> { - return updateProductTypes(existingProductTypes, productKinds).collectList().flatMap(productTypes -> { - return Mono.just(productCatalog); - }); - } - ); + .toList(); + return getProductKindFlux().collectList().flatMap( + productKinds -> updateProductTypes(existingProductTypes, productKinds).collectList() + .flatMap(productTypes -> Mono.just(productCatalog))); }); } @@ -139,25 +116,6 @@ public Mono upsertProductCatalog(ProductCatalog productCatalog) .flatMap(this::setupProductCatalog); } - private Flux updateProductKind(List productKinds) { - log.info("Updating Product Type1: {}", productKinds); - return Flux.fromIterable(productKinds) - .map(productCatalogMapper::toPresentation) - .map(productCatalogMapper::toPutPresentation) - .flatMap(this::updateProductKind); - } - - private Mono updateProductKind(ExternalProductKindItemPut productKind) { - log.info("Updating Product Type2: {}", productKind.getKindName()); - return productKindsApi.putProductKinds(productKind) - .doOnError(WebClientResponseException.BadRequest.class, e -> - log.error("Bad Request Storing Product Kind: {} \n[{}]: {}\nResponse: {}", productKind, Objects.requireNonNull(e.getRequest()).getMethod(), e.getRequest().getURI(), e.getResponseBodyAsString()) - ) - .doOnError(WebClientResponseException.class, e -> - log.error("Bad Request Product Kind: {} \n[{}]: {}\nResponse: {}", productKind, Objects.requireNonNull(e.getRequest()).getMethod(), e.getRequest().getURI(), e.getResponseBodyAsString()) - ).map(actual -> productKind); - } - private Flux createProductTypes(List productTypes, List productKinds) { return Flux.fromIterable(productTypes) .flatMap(productType -> createProductType(productType, productKinds)); @@ -197,40 +155,35 @@ public Mono updateProductType(ProductType productType, List createProductType(ProductType productType, List productKinds) { - - Mono productIdMono = Mono.just(productType) - .map(productCatalogMapper::toPresentation) - .map(productItem -> { - log.info("Creating Product Type: {}", productItem.getProductTypeName()); + Mono arrangementProductItemBaseMono = Mono.just(productType).map(productCatalogMapper::toPresentation) + .map(arrangementProductItemBase -> { + log.info("Creating Product Type: {}", arrangementProductItemBase.getTypeName()); ProductKind productKind; - if (productItem.getProductKind() != null) { + if (arrangementProductItemBase.getProductKind() != null) { productKind = productType.getProductKind(); } else { - productKind = productKinds.stream() - .filter(kind -> productType.getExternalProductKindId().equals(kind.getExternalKindId())) + productKind = productKinds.stream().filter(kind -> productType.getExternalProductKindId().equals(kind.getExternalKindId())) .findFirst() .orElseThrow(NullPointerException::new); } - productItem.setExternalProductKindId(productKind.getExternalKindId()); - productItem.setProductKindName(productKind.getKindName()); - productItem.setProductTypeName(productType.getTypeName()); - productItem.setExternalTypeId(productType.getExternalTypeId()); - return productItem; + + arrangementProductItemBase.setExternalProductKindId(productKind.getExternalKindId()); + arrangementProductItemBase.setProductKindName(productKind.getKindName()); + arrangementProductItemBase.setTypeName(productType.getTypeName()); + arrangementProductItemBase.setExternalTypeId(productType.getExternalTypeId()); + + return arrangementProductItemBase; }) - .flatMap( - productItem -> - productsApi.postProducts(productItem) - .doOnError(WebClientResponseException.BadRequest.class, e -> log.error("Bad Request Storing Product Type: {} \n[{}]: {}\nResponse: {}", productItem, Objects.requireNonNull(e.getRequest()).getMethod(), e.getRequest().getURI(), e.getResponseBodyAsString())) - .doOnError(WebClientResponseException.class, e -> log.error("Bad Request Storing Product Type: {} \n[{}]: {}\nResponse: {}", productItem, Objects.requireNonNull(e.getRequest()).getMethod(), e.getRequest().getURI(), e.getResponseBodyAsString()))); + .flatMap(arrangementProductItemBase -> productsApi.postProducts(arrangementProductItemBase) + .doOnError(WebClientResponseException.BadRequest.class, e -> log.error("Bad Request Storing Product Type: {} \n[{}]: {}\nResponse: {}", arrangementProductItemBase, Objects.requireNonNull(e.getRequest()).getMethod(), e.getRequest().getURI(), e.getResponseBodyAsString())) + .doOnError(WebClientResponseException.class, e -> log.error("Bad Request Storing Product Type: {} \n[{}]: {}\nResponse: {}", arrangementProductItemBase, Objects.requireNonNull(e.getRequest()).getMethod(), e.getRequest().getURI(), e.getResponseBodyAsString()))); - return Mono.zip(Mono.just(productType), productIdMono, this::handelStoreProductTypeResult); + return Mono.zip(Mono.just(productType), arrangementProductItemBaseMono, this::handelStoreProductTypeResult); } - - private ProductType handelStoreProductTypeResult(ProductType productType, AccountProductId productId) { - log.info("Product Type: {} created with: {}", productType.getProductTypeName(), productId.getId()); + private ProductType handelStoreProductTypeResult(ProductType productType, ResourceAddPostResponse resourceAddPostResponse) { + log.info("Product Type: {} created with: {}", productType.getProductTypeName(), resourceAddPostResponse.getId()); return productType; } @@ -238,38 +191,14 @@ private ProductType handelUpdateProductTypeResult(ProductType productType, Objec log.info("Product Type: {} updated.", productType.getProductTypeName()); return productType; } - private Flux storeProductKinds(List productKinds) { - return Flux.fromIterable(productKinds) - .map(productCatalogMapper::toPresentation) - .flatMap(this::storeProductKind); - } - - - private Mono storeProductKind(ExternalProductKindItemExtended productKind) { - Mono productKindIdMono = productKindsApi.postProductKinds(productKind) - .doOnError(WebClientResponseException.BadRequest.class, e -> - log.error("Bad Request Storing Product Kind: {} \n[{}]: {}\nResponse: {}", productKind, Objects.requireNonNull(e.getRequest()).getMethod(), e.getRequest().getURI(), e.getResponseBodyAsString()) - ) - .doOnError(WebClientResponseException.class, e -> - log.error("Bad Request Product Kind: {} \n[{}]: {}\nResponse: {}", productKind, Objects.requireNonNull(e.getRequest()).getMethod(), e.getRequest().getURI(), e.getResponseBodyAsString()) - ); - return Mono.zip(Mono.just(productKind), productKindIdMono, - this::handleStoreResult).map(productCatalogMapper::toStream); - } - - private ExternalProductKindItemExtended handleStoreResult(ExternalProductKindItemExtended productKindItem, AccountProductKindId productKindId) { - log.info("Product Kind: {} created with: {}", productKindItem.getKindName(), productKindId); - return productKindItem; - } - public Mono getProductTypeByExternalId(String productTypeExternalId) { log.info("Get Product Type: {}", productTypeExternalId); return productsApi.getProducts(Collections.singleton(productTypeExternalId), null) + .flatMapIterable(ArrangementProductsListResponse::getArrangementProductElements) .doOnNext(productItem -> log.info("Found product: {} for id: {}", productItem.getTypeName(), productTypeExternalId)) - .doOnError(WebClientResponseException.class, ex -> { - log.error("Failed to get product type by external id: {}. Response: {}", productTypeExternalId, ex.getResponseBodyAsString()); - }) + .doOnError(WebClientResponseException.class, ex -> + log.error("Failed to get product type by external id: {}. Response: {}", productTypeExternalId, ex.getResponseBodyAsString())) .onErrorResume(WebClientResponseException.NotFound.class, ex -> { log.info("No product type found with id: {}", productTypeExternalId); return Mono.empty(); diff --git a/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/configuration/ProductCatalogServiceConfiguration.java b/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/configuration/ProductCatalogServiceConfiguration.java index 77675d171..70453b731 100644 --- a/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/configuration/ProductCatalogServiceConfiguration.java +++ b/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/configuration/ProductCatalogServiceConfiguration.java @@ -1,7 +1,7 @@ package com.backbase.stream.productcatalog.configuration; -import com.backbase.dbs.arrangement.api.service.v2.ProductKindsApi; -import com.backbase.dbs.arrangement.api.service.v2.ProductsApi; +import com.backbase.dbs.arrangement.api.service.v3.ProductKindsApi; +import com.backbase.dbs.arrangement.api.service.v3.ProductsApi; import com.backbase.stream.productcatalog.ProductCatalogService; import com.backbase.stream.productcatalog.ReactiveProductCatalogService; import org.springframework.context.annotation.Bean; diff --git a/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/mapper/ProductCatalogMapper.java b/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/mapper/ProductCatalogMapper.java index 62b6d88cc..40b0e0eb3 100644 --- a/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/mapper/ProductCatalogMapper.java +++ b/stream-product-catalog/product-catalog-core/src/main/java/com/backbase/stream/productcatalog/mapper/ProductCatalogMapper.java @@ -1,11 +1,10 @@ package com.backbase.stream.productcatalog.mapper; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountProductItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountSchemasProductItem; -import com.backbase.dbs.arrangement.api.service.v2.model.ExternalProductKindItemExtended; -import com.backbase.dbs.arrangement.api.service.v2.model.ExternalProductKindItemPut; -import com.backbase.dbs.arrangement.api.service.v2.model.ProductKindItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementProductItemBase; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementProductsListElement; +import com.backbase.dbs.arrangement.api.service.v3.model.ExternalProductKindItemExtended; +import com.backbase.dbs.arrangement.api.service.v3.model.ProductKindItem; import com.backbase.stream.productcatalog.model.ProductKind; import com.backbase.stream.productcatalog.model.ProductType; import org.mapstruct.Mapper; @@ -13,21 +12,14 @@ @Mapper public interface ProductCatalogMapper { - AccountProductItem toPresentation(ProductType productType); + ArrangementProductItemBase toPresentation(ProductType productType); ExternalProductKindItemExtended toPresentation(ProductKind productKind); ProductKind toStream(ProductKindItem productKindItem); - ExternalProductKindItemPut toPutPresentation(ExternalProductKindItemExtended productKindItem); - - ExternalProductKindItemExtended toStream(ExternalProductKindItemPut productKindItem); - ProductKind toStream(ExternalProductKindItemExtended presentationProductKindItemGet); - /*ProductKind toStream(ProductKindItem productKindItem);*/ - - ProductType toStream(AccountSchemasProductItem productItem); - + ProductType toStream(ArrangementProductsListElement arrangementProductsListElement); } diff --git a/stream-product-catalog/product-catalog-task/src/test/resources/mappings/arrangement-manager-stubs.json b/stream-product-catalog/product-catalog-task/src/test/resources/mappings/arrangement-manager-stubs.json index 56c60d9ac..a139a327f 100644 --- a/stream-product-catalog/product-catalog-task/src/test/resources/mappings/arrangement-manager-stubs.json +++ b/stream-product-catalog/product-catalog-task/src/test/resources/mappings/arrangement-manager-stubs.json @@ -2,13 +2,13 @@ "mappings": [ { "id": "ec55d9b3-ff28-4aec-9310-a57b8120d615", - "name": "service-api_v2_products", + "name": "service-api_v3_products", "request": { - "url": "/service-api/v2/products", + "url": "/service-api/v3/products", "method": "POST", "bodyPatterns": [ { - "equalToJson": "{\"externalId\":null,\"externalTypeId\":null,\"typeName\":\"Savings Accounts\",\"externalProductId\":\"savings-account\",\"externalProductKindId\":\"kind2\",\"productKindName\":\"Savings Account\",\"externalProductTypeId\":null,\"productTypeName\":\"Savings Accounts\",\"productKind\":null}", + "equalToJson": "{\"externalId\":null,\"externalTypeId\":null,\"typeName\":\"Savings Accounts\",\"externalProductId\":\"savings-account\",\"externalProductKindId\":\"kind2\",\"productKindName\":\"Savings Account\",\"externalProductTypeId\":null,\"productTypeName\":\"savings-account\",\"productKind\":null,\"translations\":[],\"additions\":{}}", "ignoreArrayOrder": true, "ignoreExtraElements": true } @@ -37,13 +37,13 @@ }, { "id": "cf183288-e389-4287-bbb3-309889d699c2", - "name": "service-api_v2_products", + "name": "service-api_v3_products", "request": { - "url": "/service-api/v2/products", + "url": "/service-api/v3/products", "method": "POST", "bodyPatterns": [ { - "equalToJson": "{\"externalId\":null,\"externalTypeId\":null,\"typeName\":\"Current Account\",\"externalProductId\":\"current-account\",\"externalProductKindId\":\"kind1\",\"productKindName\":\"Current Account\",\"externalProductTypeId\":null,\"productTypeName\":\"Current Account\",\"productKind\":null}", + "equalToJson": "{\"externalId\":null,\"externalTypeId\":null,\"typeName\":\"Current Account\",\"externalProductId\":\"current-account\",\"externalProductKindId\":\"kind1\",\"productKindName\":\"Current Account\",\"externalProductTypeId\":null,\"productTypeName\":\"current-account\",\"productKind\":null,\"translations\":[],\"additions\":{}}", "ignoreArrayOrder": true, "ignoreExtraElements": true } @@ -72,14 +72,14 @@ }, { "id": "48f1fc4a-545f-4812-9a3e-0358a89cc490", - "name": "service-api_v2_product-kinds", + "name": "service-api_v3_product-kinds", "request": { - "url": "/service-api/v2/product-kinds", + "url": "/service-api/v3/product-kinds", "method": "GET" }, "response": { "status": 200, - "body": "{\"productKinds\":[{\"id\":1,\"externalKindId\":\"kind1\",\"kindName\":\"Current Account\",\"kindUri\":\"current-account\",\"translations\":[]},{\"id\":2,\"externalKindId\":\"kind2\",\"kindName\":\"Savings Account\",\"kindUri\":\"savings-account\",\"translations\":[]},{\"id\":3,\"externalKindId\":\"kind3\",\"kindName\":\"Debit Card\",\"kindUri\":\"debit-card\",\"translations\":[]},{\"id\":4,\"externalKindId\":\"kind4\",\"kindName\":\"Credit Card\",\"kindUri\":\"credit-card\",\"translations\":[]},{\"id\":5,\"externalKindId\":\"kind5\",\"kindName\":\"Loan\",\"kindUri\":\"loan\",\"translations\":[]},{\"id\":6,\"externalKindId\":\"kind6\",\"kindName\":\"Term Deposit\",\"kindUri\":\"term-deposit\",\"translations\":[]},{\"id\":7,\"externalKindId\":\"kind7\",\"kindName\":\"Investment Account\",\"kindUri\":\"investment-account\",\"translations\":[]},{\"id\":8,\"externalKindId\":\"kind8\",\"kindName\":\"Pocket Parent\",\"kindUri\":\"pocket-parent\",\"translations\":[]},{\"id\":9,\"externalKindId\":\"kind9\",\"kindName\":\"Pocket\",\"kindUri\":\"pocket\",\"translations\":[]}]}", + "body": "{\"productKindElements\":[{\"id\":1,\"externalKindId\":\"kind1\",\"kindName\":\"Current Account\",\"kindUri\":\"current-account\",\"translations\":[]},{\"id\":2,\"externalKindId\":\"kind2\",\"kindName\":\"Savings Account\",\"kindUri\":\"savings-account\",\"translations\":[]},{\"id\":3,\"externalKindId\":\"kind3\",\"kindName\":\"Debit Card\",\"kindUri\":\"debit-card\",\"translations\":[]},{\"id\":4,\"externalKindId\":\"kind4\",\"kindName\":\"Credit Card\",\"kindUri\":\"credit-card\",\"translations\":[]},{\"id\":5,\"externalKindId\":\"kind5\",\"kindName\":\"Loan\",\"kindUri\":\"loan\",\"translations\":[]},{\"id\":6,\"externalKindId\":\"kind6\",\"kindName\":\"Term Deposit\",\"kindUri\":\"term-deposit\",\"translations\":[]},{\"id\":7,\"externalKindId\":\"kind7\",\"kindName\":\"Investment Account\",\"kindUri\":\"investment-account\",\"translations\":[]},{\"id\":8,\"externalKindId\":\"kind8\",\"kindName\":\"Pocket Parent\",\"kindUri\":\"pocket-parent\",\"translations\":[]},{\"id\":9,\"externalKindId\":\"kind9\",\"kindName\":\"Pocket\",\"kindUri\":\"pocket\",\"translations\":[]}]}", "headers": { "x-content-type-options": "nosniff", "x-xss-protection": "1; mode=block", @@ -100,14 +100,14 @@ }, { "id": "bb6a3fa4-2612-479b-8e76-a02d2fbb1b47", - "name": "service-api_v2_products", + "name": "service-api_v3_products", "request": { - "url": "/service-api/v2/products", + "url": "/service-api/v3/products", "method": "GET" }, "response": { "status": 200, - "body": "[{\"externalId\":\"default-pocket-external-id\",\"typeName\":\"Pocket\",\"externalProductId\":\"default-pocket-external-id\",\"externalProductKindId\":\"kind9\",\"productKindName\":\"Pocket\",\"productTypeName\":\"Pocket\",\"productKind\":{\"externalKindId\":\"kind9\",\"kindName\":\"Pocket\",\"kindUri\":\"pocket\",\"translations\":[]},\"translations\":[],\"id\":\"5e493bca-4f58-4593-90b8-c2dfde2d1620\"},{\"externalId\":\"default-pocket-parent-external-id\",\"typeName\":\"Pocket Parent\",\"externalProductId\":\"default-pocket-parent-external-id\",\"externalProductKindId\":\"kind8\",\"productKindName\":\"Pocket Parent\",\"productTypeName\":\"Pocket Parent\",\"productKind\":{\"externalKindId\":\"kind8\",\"kindName\":\"Pocket Parent\",\"kindUri\":\"pocket-parent\",\"translations\":[]},\"translations\":[],\"id\":\"c55edc8b-ceef-439b-b637-ee9bc74f91e4\"}]", + "body": "{\"arrangementProductElements\":[{\"externalId\":\"default-pocket-external-id\",\"typeName\":\"Pocket\",\"externalProductId\":\"default-pocket-external-id\",\"externalProductKindId\":\"kind9\",\"productKindName\":\"Pocket\",\"productTypeName\":\"Pocket\",\"productKind\":{\"externalKindId\":\"kind9\",\"kindName\":\"Pocket\",\"kindUri\":\"pocket\",\"translations\":[]},\"translations\":[],\"id\":\"5e493bca-4f58-4593-90b8-c2dfde2d1620\"},{\"externalId\":\"default-pocket-parent-external-id\",\"typeName\":\"Pocket Parent\",\"externalProductId\":\"default-pocket-parent-external-id\",\"externalProductKindId\":\"kind8\",\"productKindName\":\"Pocket Parent\",\"productTypeName\":\"Pocket Parent\",\"productKind\":{\"externalKindId\":\"kind8\",\"kindName\":\"Pocket Parent\",\"kindUri\":\"pocket-parent\",\"translations\":[]},\"translations\":[],\"id\":\"c55edc8b-ceef-439b-b637-ee9bc74f91e4\"}]}", "headers": { "x-content-type-options": "nosniff", "x-xss-protection": "1; mode=block", @@ -128,14 +128,14 @@ }, { "id": "13f4e38d-071d-4670-9308-e7a7760434d6", - "name": "service-api_v2_product-kinds", + "name": "sservice-api_v3_product-kinds", "request": { - "url": "/service-api/v2/product-kinds", + "url": "/service-api/v3/product-kinds", "method": "GET" }, "response": { "status": 200, - "body": "{\"productKinds\":[{\"id\":1,\"externalKindId\":\"kind1\",\"kindName\":\"Current Account\",\"kindUri\":\"current-account\",\"translations\":[]},{\"id\":2,\"externalKindId\":\"kind2\",\"kindName\":\"Savings Account\",\"kindUri\":\"savings-account\",\"translations\":[]},{\"id\":3,\"externalKindId\":\"kind3\",\"kindName\":\"Debit Card\",\"kindUri\":\"debit-card\",\"translations\":[]},{\"id\":4,\"externalKindId\":\"kind4\",\"kindName\":\"Credit Card\",\"kindUri\":\"credit-card\",\"translations\":[]},{\"id\":5,\"externalKindId\":\"kind5\",\"kindName\":\"Loan\",\"kindUri\":\"loan\",\"translations\":[]},{\"id\":6,\"externalKindId\":\"kind6\",\"kindName\":\"Term Deposit\",\"kindUri\":\"term-deposit\",\"translations\":[]},{\"id\":7,\"externalKindId\":\"kind7\",\"kindName\":\"Investment Account\",\"kindUri\":\"investment-account\",\"translations\":[]},{\"id\":8,\"externalKindId\":\"kind8\",\"kindName\":\"Pocket Parent\",\"kindUri\":\"pocket-parent\",\"translations\":[]},{\"id\":9,\"externalKindId\":\"kind9\",\"kindName\":\"Pocket\",\"kindUri\":\"pocket\",\"translations\":[]}]}", + "body": "{\"productKindElements\":[{\"id\":1,\"externalKindId\":\"kind1\",\"kindName\":\"Current Account\",\"kindUri\":\"current-account\",\"translations\":[]},{\"id\":2,\"externalKindId\":\"kind2\",\"kindName\":\"Savings Account\",\"kindUri\":\"savings-account\",\"translations\":[]},{\"id\":3,\"externalKindId\":\"kind3\",\"kindName\":\"Debit Card\",\"kindUri\":\"debit-card\",\"translations\":[]},{\"id\":4,\"externalKindId\":\"kind4\",\"kindName\":\"Credit Card\",\"kindUri\":\"credit-card\",\"translations\":[]},{\"id\":5,\"externalKindId\":\"kind5\",\"kindName\":\"Loan\",\"kindUri\":\"loan\",\"translations\":[]},{\"id\":6,\"externalKindId\":\"kind6\",\"kindName\":\"Term Deposit\",\"kindUri\":\"term-deposit\",\"translations\":[]},{\"id\":7,\"externalKindId\":\"kind7\",\"kindName\":\"Investment Account\",\"kindUri\":\"investment-account\",\"translations\":[]},{\"id\":8,\"externalKindId\":\"kind8\",\"kindName\":\"Pocket Parent\",\"kindUri\":\"pocket-parent\",\"translations\":[]},{\"id\":9,\"externalKindId\":\"kind9\",\"kindName\":\"Pocket\",\"kindUri\":\"pocket\",\"translations\":[]}]}", "headers": { "x-content-type-options": "nosniff", "x-xss-protection": "1; mode=block", diff --git a/stream-product/product-core/src/main/java/com/backbase/stream/product/configuration/ProductConfiguration.java b/stream-product/product-core/src/main/java/com/backbase/stream/product/configuration/ProductConfiguration.java index e505339a2..f8edb4799 100644 --- a/stream-product/product-core/src/main/java/com/backbase/stream/product/configuration/ProductConfiguration.java +++ b/stream-product/product-core/src/main/java/com/backbase/stream/product/configuration/ProductConfiguration.java @@ -1,7 +1,7 @@ package com.backbase.stream.product.configuration; -import com.backbase.dbs.arrangement.api.service.v2.ArrangementsApi; +import com.backbase.dbs.arrangement.api.service.v3.ArrangementsApi; import com.backbase.stream.product.service.ArrangementService; import lombok.AllArgsConstructor; import org.springframework.context.annotation.Bean; @@ -15,8 +15,9 @@ public class ProductConfiguration { @Bean - public ArrangementService arrangementService(ArrangementsApi arrangementsApi) { - return new ArrangementService(arrangementsApi); + public ArrangementService arrangementService(ArrangementsApi arrangementsApi, + com.backbase.dbs.arrangement.api.integration.v2.ArrangementsApi arrangementsIntegrationApi) { + return new ArrangementService(arrangementsApi, arrangementsIntegrationApi); } } diff --git a/stream-product/product-core/src/main/java/com/backbase/stream/product/mapping/ProductMapper.java b/stream-product/product-core/src/main/java/com/backbase/stream/product/mapping/ProductMapper.java index 8e3d57fc1..c2fc0dff0 100644 --- a/stream-product/product-core/src/main/java/com/backbase/stream/product/mapping/ProductMapper.java +++ b/stream-product/product-core/src/main/java/com/backbase/stream/product/mapping/ProductMapper.java @@ -1,11 +1,15 @@ package com.backbase.stream.product.mapping; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemBase; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPost; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountUserPreferencesItemPut; -import com.backbase.dbs.arrangement.api.service.v2.model.TimeUnit; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptySet; +import static org.apache.commons.lang3.StringUtils.isBlank; + +import com.backbase.dbs.arrangement.api.integration.v2.model.PostArrangement; +import com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItemBase; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItemPostRequest; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; import com.backbase.stream.legalentity.model.AvailableBalance; import com.backbase.stream.legalentity.model.BaseProduct; import com.backbase.stream.legalentity.model.BookedBalance; @@ -25,7 +29,6 @@ import com.backbase.stream.legalentity.model.SavingsAccount; import com.backbase.stream.legalentity.model.TermDeposit; import com.backbase.stream.legalentity.model.TermUnit; -import com.backbase.stream.legalentity.model.UserPreferences; import java.math.BigDecimal; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; @@ -46,164 +49,158 @@ @SuppressWarnings({"squid:S1710"}) public interface ProductMapper { - - @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) - @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) - @Mapping(source = "state.externalStateId", target = ProductMapperConstants.EXTERNAL_STATE_ID) + @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.ID) + @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.PRODUCT_ID) + @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.LEGAL_ENTITY_IDS) + @Mapping(source = "state.externalStateId", target = ProductMapperConstants.STATE_ID) @Mapping(source = ProductMapperConstants.ACCOUNT_HOLDER_NAME, target = ProductMapperConstants.ACCOUNT_HOLDER_NAMES) - AccountArrangementItemPost toPresentation(Product product); - + PostArrangement toPresentation(Product product); @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) @Mapping(source = "state.externalStateId", target = ProductMapperConstants.EXTERNAL_STATE_ID) - AccountArrangementItemPost toPresentation(BaseProduct product); + ArrangementItemPostRequest toPresentation(BaseProduct product); - - @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) - @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) + @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.ID) + @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.PRODUCT_ID) + @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.LEGAL_ENTITY_IDS) @InheritConfiguration @Mapping(source = "debitCardsItems", target = "debitCards") @Mapping(source = ProductMapperConstants.ACCOUNT_HOLDER_NAME, target = ProductMapperConstants.ACCOUNT_HOLDER_NAMES) @Mapping(source = ProductMapperConstants.PAN_SUFFIX, target = ProductMapperConstants.NUMBER) - AccountArrangementItemPost toPresentation(CurrentAccount currentAccount); + PostArrangement toPresentation(CurrentAccount currentAccount); - - @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) - @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) + @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.ID) + @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.PRODUCT_ID) + @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.LEGAL_ENTITY_IDS) @Mapping(source = ProductMapperConstants.DEBIT_CARDS_ITEMS, target = ProductMapperConstants.DEBIT_CARDS) @Mapping(source = ProductMapperConstants.ACCOUNT_HOLDER_NAME, target = ProductMapperConstants.ACCOUNT_HOLDER_NAMES) @Mapping(source = ProductMapperConstants.PAN_SUFFIX, target = ProductMapperConstants.NUMBER) @InheritConfiguration - AccountArrangementItemPost toPresentation(SavingsAccount savingsAccount); + PostArrangement toPresentation(SavingsAccount savingsAccount); - - @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) - @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) + @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.ID) + @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.PRODUCT_ID) + @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.LEGAL_ENTITY_IDS) @Mapping(source = ProductMapperConstants.ACCOUNT_HOLDER_NAME, target = ProductMapperConstants.ACCOUNT_HOLDER_NAMES) @Mapping(source = "debitCard", qualifiedByName = "mapDebitCardNumber", target = ProductMapperConstants.NUMBER) @InheritConfiguration - AccountArrangementItemPost toPresentation(DebitCard debitCard); + PostArrangement toPresentation(DebitCard debitCard); - @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) - @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) + @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.ID) + @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.PRODUCT_ID) + @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.LEGAL_ENTITY_IDS) @Mapping(source = ProductMapperConstants.ACCOUNT_HOLDER_NAME, target = ProductMapperConstants.ACCOUNT_HOLDER_NAMES) @Mapping(source = "creditCard", qualifiedByName = "mapCreditCardNumber", target = ProductMapperConstants.NUMBER) @InheritConfiguration - AccountArrangementItemPost toPresentation(CreditCard creditCard); + PostArrangement toPresentation(CreditCard creditCard); - @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) - @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) + @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.ID) + @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.PRODUCT_ID) + @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.LEGAL_ENTITY_IDS) @Mapping(source = ProductMapperConstants.ACCOUNT_HOLDER_NAME, target = ProductMapperConstants.ACCOUNT_HOLDER_NAMES) @Mapping(source = ProductMapperConstants.PAN_SUFFIX, target = ProductMapperConstants.NUMBER) @InheritConfiguration - AccountArrangementItemPost toPresentation(TermDeposit termDeposit); + PostArrangement toPresentation(TermDeposit termDeposit); - @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) - @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) + @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.ID) + @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.PRODUCT_ID) + @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.LEGAL_ENTITY_IDS) @Mapping(source = "currentInvestment.amount", target = "currentInvestmentValue") @Mapping(source = ProductMapperConstants.PAN_SUFFIX, target = ProductMapperConstants.NUMBER) @InheritConfiguration - AccountArrangementItemPost toPresentation(InvestmentAccount investmentAccount); + PostArrangement toPresentation(InvestmentAccount investmentAccount); - @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_PRODUCT_ID) - @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.EXTERNAL_LEGAL_ENTITY_IDS) + @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.ID) + @Mapping(source = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID, target = ProductMapperConstants.PRODUCT_ID) + @Mapping(source = ProductMapperConstants.LEGAL_ENTITIES, target = ProductMapperConstants.LEGAL_ENTITY_IDS) @Mapping(source = ProductMapperConstants.ACCOUNT_HOLDER_NAME, target = ProductMapperConstants.ACCOUNT_HOLDER_NAMES) @Mapping(source = ProductMapperConstants.PAN_SUFFIX, target = ProductMapperConstants.NUMBER) @InheritConfiguration - AccountArrangementItemPost toPresentation(Loan loan); + PostArrangement toPresentation(Loan loan); - AccountArrangementItem toArrangementItem(AccountArrangementItemPost arrangementItemPost); + @Mapping(source = ProductMapperConstants.STATE_ID, target = "state.state") + @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) + ArrangementItem toArrangementItem(PostArrangement arrangementItemPost); - AccountArrangementItemPut toArrangementItemPut(AccountArrangementItemPost arrangementItemPost); + @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) + ArrangementPutItem toArrangementItemPut(PostArrangement arrangementItemPost); - AccountArrangementItemBase toArrangementItemBase(AccountArrangementItemPost arrangementItemPost); + ArrangementItemBase toArrangementItemBase(ArrangementItemPostRequest arrangementItemPost); - AccountArrangementItem toArrangementItem(AccountArrangementItemBase arrangementItemBase); + ArrangementItem toArrangementItem(ArrangementItemBase arrangementItemBase); - AccountArrangementItem toArrangementItem(AccountArrangementItemPut arrangementItemPut); + ArrangementItem toArrangementItem(ArrangementPutItem arrangementItemPut); @Mapping(source = ProductMapperConstants.EXTERNAL_ID, target = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID) - AccountArrangementItem toPresentationWithWeirdSpellingError(Product product); - -// @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) -// @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) -// @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) -// @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) -// BaseProduct toBaseProduct(ArrangementItem arrangementItem); + ArrangementItem toPresentationWithWeirdSpellingError(Product product); @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) @InheritConfiguration - Product mapCustomProduct(AccountArrangementItem arrangementItem); + Product mapCustomProduct(ArrangementItem arrangementItem); @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) - CurrentAccount mapCurrentAccount(AccountArrangementItem product); + CurrentAccount mapCurrentAccount(ArrangementItem product); @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) - SavingsAccount mapSavingAccount(AccountArrangementItem product); + SavingsAccount mapSavingAccount(ArrangementItem product); @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) - DebitCard mapDebitCard(AccountArrangementItem product); + DebitCard mapDebitCard(ArrangementItem product); @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) - CreditCard mapCreditCard(AccountArrangementItem product); + CreditCard mapCreditCard(ArrangementItem product); @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) - Loan mapLoan(AccountArrangementItem product); + Loan mapLoan(ArrangementItem product); @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) - TermDeposit mapTermDeposit(AccountArrangementItem product); + TermDeposit mapTermDeposit(ArrangementItem product); @Mapping(source = ProductMapperConstants.EXTERNAL_ARRANGEMENT_ID, target = ProductMapperConstants.EXTERNAL_ID) @Mapping(source = ProductMapperConstants.EXTERNAL_PRODUCT_ID, target = ProductMapperConstants.PRODUCT_TYPE_EXTERNAL_ID) @Mapping(source = ProductMapperConstants.LEGAL_ENTITY_IDS, target = ProductMapperConstants.LEGAL_ENTITIES) @Mapping(source = ProductMapperConstants.ID, target = ProductMapperConstants.INTERNAL_ID) @Mapping(source = "currentInvestmentValue", target = "currentInvestment") - InvestmentAccount mapInvestmentAccount(AccountArrangementItem product); + InvestmentAccount mapInvestmentAccount(ArrangementItem product); default List mapLegalEntities(Set externalIds) { - if (externalIds == null) - return null; - return externalIds.stream().map(id -> new LegalEntityReference().externalId(id)).toList(); + if (externalIds == null) { + return emptyList(); + } + return externalIds.stream().map(id -> new LegalEntityReference(null, id)).toList(); } default Set mapLegalEntitiesIds(List externalIds) { - if (externalIds == null) - return null; - return externalIds.stream().map(id -> id.getExternalId()).collect(Collectors.toSet()); + if (externalIds == null) { + return emptySet(); + } + return externalIds.stream().map(LegalEntityReference::getExternalId).collect(Collectors.toSet()); } default BookedBalance mapBookedBalance(BigDecimal bigDecimal) { @@ -248,14 +245,14 @@ default LegalEntity mapLegalEntity(String legalEntityId) { } default OffsetDateTime map(String s) { - if (StringUtils.isEmpty(s)) { + if (isBlank(s)) { return null; - } else { - try { - return OffsetDateTime.parse(s, ProductMapperConstants.formatter); - } catch (java.time.format.DateTimeParseException e) { - return OffsetDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm'Z'")); - } + } + + try { + return OffsetDateTime.parse(s, ProductMapperConstants.formatter); + } catch (java.time.format.DateTimeParseException e) { + return OffsetDateTime.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm'Z'")); } } @@ -266,11 +263,10 @@ default OffsetDateTime map(String s) { * @return BigDecimal */ default BigDecimal map(BookedBalance value) { - if (value != null) { - return value.getAmount(); - } else { + if (value == null) { return null; } + return value.getAmount(); } /** @@ -294,11 +290,10 @@ default BigDecimal map(ReservedAmount value) { * @return BigDecimal */ default BigDecimal map(AvailableBalance value) { - if (value != null) { - return value.getAmount(); - } else { + if (value == null) { return null; } + return value.getAmount(); } /** @@ -344,60 +339,54 @@ default String map(OffsetDateTime offsetDateTime) { } @ValueMappings({ - @ValueMapping(source = "QUARTERLY", target = MappingConstants.NULL), - @ValueMapping(source = ProductMapperConstants.DAILY, target = ProductMapperConstants.D), - @ValueMapping(source = ProductMapperConstants.WEEKLY, target = ProductMapperConstants.W), - @ValueMapping(source = ProductMapperConstants.MONTHLY, target = ProductMapperConstants.M), - @ValueMapping(source = ProductMapperConstants.YEARLY, target = ProductMapperConstants.Y) + @ValueMapping(source = ProductMapperConstants.DAILY, target = ProductMapperConstants.D), + @ValueMapping(source = ProductMapperConstants.WEEKLY, target = ProductMapperConstants.W), + @ValueMapping(source = ProductMapperConstants.MONTHLY, target = ProductMapperConstants.M), + @ValueMapping(source = ProductMapperConstants.QUARTERLY, target = MappingConstants.NULL), + @ValueMapping(source = ProductMapperConstants.YEARLY, target = ProductMapperConstants.Y) }) TimeUnit map(TermUnit termUnit); @ValueMappings({ - @ValueMapping(source = "QUARTERLY", target = MappingConstants.NULL), - @ValueMapping(source = ProductMapperConstants.DAILY, target = ProductMapperConstants.D), - @ValueMapping(source = ProductMapperConstants.WEEKLY, target = ProductMapperConstants.W), - @ValueMapping(source = ProductMapperConstants.MONTHLY, target = ProductMapperConstants.M), - @ValueMapping(source = ProductMapperConstants.YEARLY, target = ProductMapperConstants.Y) + @ValueMapping(source = ProductMapperConstants.DAILY, target = ProductMapperConstants.D), + @ValueMapping(source = ProductMapperConstants.WEEKLY, target = ProductMapperConstants.W), + @ValueMapping(source = ProductMapperConstants.MONTHLY, target = ProductMapperConstants.M), + @ValueMapping(source = ProductMapperConstants.QUARTERLY, target = MappingConstants.NULL), + @ValueMapping(source = ProductMapperConstants.YEARLY, target = ProductMapperConstants.Y) }) TimeUnit map(InterestPaymentFrequencyUnit interestPaymentFrequencyUnit); @ValueMappings({ - @ValueMapping(source = ProductMapperConstants.D, target = ProductMapperConstants.DAILY), - @ValueMapping(source = ProductMapperConstants.W, target = ProductMapperConstants.WEEKLY), - @ValueMapping(source = ProductMapperConstants.M, target = ProductMapperConstants.MONTHLY), - @ValueMapping(source = ProductMapperConstants.Y, target = ProductMapperConstants.YEARLY) + @ValueMapping(source = ProductMapperConstants.D, target = ProductMapperConstants.DAILY), + @ValueMapping(source = ProductMapperConstants.W, target = ProductMapperConstants.WEEKLY), + @ValueMapping(source = ProductMapperConstants.M, target = ProductMapperConstants.MONTHLY), + @ValueMapping(source = ProductMapperConstants.Y, target = ProductMapperConstants.YEARLY) }) TermUnit map(TimeUnit unit); default java.util.List mapLegalEntityId(java.util.List value) { - if (value != null) { - return value.stream().map(LegalEntityReference::getExternalId).collect(Collectors.toList()); - } else { + if (value == null) { return null; } + return value.stream().map(LegalEntityReference::getExternalId).toList(); } default List mapLegalEntityReference(List value) { - if (value != null) { - return value.stream().map(id -> new LegalEntityReference().externalId(id)).collect(Collectors.toList()); - } else { + if (value == null) { return null; } + return value.stream().map(id -> new LegalEntityReference(null, id)).toList(); } - @ValueMappings({ - @ValueMapping(source = ProductMapperConstants.D, target = ProductMapperConstants.DAILY), - @ValueMapping(source = ProductMapperConstants.W, target = ProductMapperConstants.WEEKLY), - @ValueMapping(source = ProductMapperConstants.M, target = ProductMapperConstants.MONTHLY), - @ValueMapping(source = ProductMapperConstants.Y, target = ProductMapperConstants.YEARLY) + @ValueMapping(source = ProductMapperConstants.D, target = ProductMapperConstants.DAILY), + @ValueMapping(source = ProductMapperConstants.W, target = ProductMapperConstants.WEEKLY), + @ValueMapping(source = ProductMapperConstants.M, target = ProductMapperConstants.MONTHLY), + @ValueMapping(source = ProductMapperConstants.Y, target = ProductMapperConstants.YEARLY) }) InterestPaymentFrequencyUnit mapInterestPayment(TimeUnit unit); - @Mapping(source = "userExternalId", target = "userId") - AccountUserPreferencesItemPut mapUserPreference(UserPreferences userPreferences); - @Named("mapDebitCardNumber") default String mapDebitCardNumber(DebitCard debitCard) { if (StringUtils.hasText(debitCard.getNumber())) { @@ -413,4 +402,41 @@ default String mapCreditCardNumber(CreditCard creditCard) { } return creditCard.getPanSuffix(); } + + + @ValueMappings({ + @ValueMapping(source = ProductMapperConstants.DAILY, target = ProductMapperConstants.D), + @ValueMapping(source = ProductMapperConstants.WEEKLY, target = ProductMapperConstants.W), + @ValueMapping(source = ProductMapperConstants.MONTHLY, target = ProductMapperConstants.M), + @ValueMapping(source = ProductMapperConstants.QUARTERLY, target = MappingConstants.NULL), + @ValueMapping(source = ProductMapperConstants.YEARLY, target = ProductMapperConstants.Y) + }) + com.backbase.dbs.arrangement.api.service.v3.model.TimeUnit mapTimeUnitV3(TermUnit termUnit); + + @ValueMappings({ + @ValueMapping(source = ProductMapperConstants.DAILY, target = ProductMapperConstants.D), + @ValueMapping(source = ProductMapperConstants.WEEKLY, target = ProductMapperConstants.W), + @ValueMapping(source = ProductMapperConstants.MONTHLY, target = ProductMapperConstants.M), + @ValueMapping(source = ProductMapperConstants.QUARTERLY, target = MappingConstants.NULL), + @ValueMapping(source = ProductMapperConstants.YEARLY, target = ProductMapperConstants.Y) + }) + com.backbase.dbs.arrangement.api.service.v3.model.TimeUnit mapInterestPaymentFrequencyUnitToTimeUnitV3(InterestPaymentFrequencyUnit interestPaymentFrequencyUnit); + + @ValueMappings({ + @ValueMapping(source = ProductMapperConstants.D, target = ProductMapperConstants.DAILY), + @ValueMapping(source = ProductMapperConstants.W, target = ProductMapperConstants.WEEKLY), + @ValueMapping(source = ProductMapperConstants.M, target = ProductMapperConstants.MONTHLY), + @ValueMapping(source = ProductMapperConstants.Y, target = ProductMapperConstants.YEARLY) + }) + TermUnit mapTimeUnitV3ToTermUnit(com.backbase.dbs.arrangement.api.service.v3.model.TimeUnit timeUnit); + + @ValueMappings({ + @ValueMapping(source = ProductMapperConstants.D, target = ProductMapperConstants.DAILY), + @ValueMapping(source = ProductMapperConstants.W, target = ProductMapperConstants.WEEKLY), + @ValueMapping(source = ProductMapperConstants.M, target = ProductMapperConstants.MONTHLY), + @ValueMapping(source = ProductMapperConstants.Y, target = ProductMapperConstants.YEARLY) + }) + InterestPaymentFrequencyUnit mapTimeUnitV3ToInterestPaymentFrequencyUnit(com.backbase.dbs.arrangement.api.service.v3.model.TimeUnit timeUnit); + + com.backbase.dbs.arrangement.api.service.v3.model.TimeUnit mapTimeUnitV2ToTimeUnitV3(TimeUnit timeUnit); } diff --git a/stream-product/product-core/src/main/java/com/backbase/stream/product/mapping/ProductMapperConstants.java b/stream-product/product-core/src/main/java/com/backbase/stream/product/mapping/ProductMapperConstants.java index ac6471bbd..fdee33e6e 100644 --- a/stream-product/product-core/src/main/java/com/backbase/stream/product/mapping/ProductMapperConstants.java +++ b/stream-product/product-core/src/main/java/com/backbase/stream/product/mapping/ProductMapperConstants.java @@ -12,6 +12,7 @@ class ProductMapperConstants { static final String DAILY = "DAILY"; static final String WEEKLY = "WEEKLY"; static final String MONTHLY = "MONTHLY"; + static final String QUARTERLY = "QUARTERLY"; static final String YEARLY = "YEARLY"; static final String D = "D"; static final String W = "W"; @@ -33,5 +34,9 @@ class ProductMapperConstants { static final String DEBIT_CARDS = "debitCards"; static final String NUMBER = "number"; static final String PAN_SUFFIX = "panSuffix"; + static final String PRODUCT_ID = "productId"; + static final String STATE_ID = "stateId"; + static final String INTEREST_PAYMENT_FREQUENCY_UNIT = "interestPaymentFrequencyUnit"; + static final String TERM_UNIT = "termUnit"; } diff --git a/stream-product/product-core/src/main/java/com/backbase/stream/product/service/ArrangementService.java b/stream-product/product-core/src/main/java/com/backbase/stream/product/service/ArrangementService.java index c96e198c0..8a73839b5 100644 --- a/stream-product/product-core/src/main/java/com/backbase/stream/product/service/ArrangementService.java +++ b/stream-product/product-core/src/main/java/com/backbase/stream/product/service/ArrangementService.java @@ -1,23 +1,30 @@ package com.backbase.stream.product.service; -import com.backbase.dbs.arrangement.api.service.v2.ArrangementsApi; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPost; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItems; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountBatchResponseItemExtended; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountExternalLegalEntityIds; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountInternalIdGetResponseBody; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountUserPreferencesItemPut; -import com.backbase.dbs.arrangement.api.service.v2.model.BatchResponseStatusCode; -import com.backbase.dbs.arrangement.api.service.v2.model.ErrorItem; +import static com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsDeleteItem.SelectorEnum.EXTERNAL_ID; +import static java.lang.String.join; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static reactor.core.publisher.Mono.error; +import static reactor.core.publisher.Mono.fromCallable; + +import com.backbase.dbs.arrangement.api.integration.v2.model.BatchResponseItemExtended; +import com.backbase.dbs.arrangement.api.integration.v2.model.BatchResponseStatusCode; +import com.backbase.dbs.arrangement.api.integration.v2.model.ErrorItem; +import com.backbase.dbs.arrangement.api.integration.v2.model.ExternalLegalEntityIds; +import com.backbase.dbs.arrangement.api.integration.v2.model.PostArrangement; +import com.backbase.dbs.arrangement.api.service.v3.ArrangementsApi; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementSearchesListResponse; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsDeleteItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsDeleteResponseElement; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsSearchesPostRequest; import com.backbase.stream.product.exception.ArrangementCreationException; import com.backbase.stream.product.exception.ArrangementUpdateException; import com.backbase.stream.product.mapping.ProductMapper; -import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.stream.Collectors; +import java.util.Set; import lombok.extern.slf4j.Slf4j; import org.mapstruct.factory.Mappers; import org.springframework.web.reactive.function.client.WebClientResponseException; @@ -32,70 +39,54 @@ public class ArrangementService { private final ArrangementsApi arrangementsApi; + private final com.backbase.dbs.arrangement.api.integration.v2.ArrangementsApi arrangementsIntegrationApi; private final ProductMapper productMapper = Mappers.getMapper(ProductMapper.class); - public ArrangementService(ArrangementsApi arrangementsApi) { + public ArrangementService(ArrangementsApi arrangementsApi, + com.backbase.dbs.arrangement.api.integration.v2.ArrangementsApi arrangementsIntegrationApi) { this.arrangementsApi = arrangementsApi; + this.arrangementsIntegrationApi = arrangementsIntegrationApi; } - public Mono createArrangement(AccountArrangementItemPost arrangementItemPost) { + public Mono createArrangement(PostArrangement postArrangement) { - return arrangementsApi.postArrangements(arrangementItemPost) - .doOnError(WebClientResponseException.class, throwable -> - log.error("Failed to create arrangement: {}\n{}", arrangementItemPost.getExternalArrangementId(), throwable.getResponseBodyAsString())) + return arrangementsIntegrationApi.postArrangements(postArrangement) + .doOnError(WebClientResponseException.class, throwable -> log.error("Failed to create arrangement: {}\n{}", postArrangement.getId(), throwable.getResponseBodyAsString())) .onErrorMap(WebClientResponseException.class, throwable -> new ArrangementCreationException(throwable, "Failed to post arrangements")) .map(arrangementAddedResponse -> { - - AccountArrangementItem arrangementItem = productMapper.toArrangementItem(arrangementItemPost); + ArrangementItem arrangementItem = productMapper.toArrangementItem(postArrangement); arrangementItem.setId(arrangementAddedResponse.getId()); - return arrangementItem; }); } - public Mono updateArrangement( AccountArrangementItemPut accountArrangementItemPut) { - log.info("Updating Arrangement: {}", accountArrangementItemPut.getExternalArrangementId()); - if(accountArrangementItemPut.getDebitCards() == null) - accountArrangementItemPut.setDebitCards(Collections.emptySet()); - return arrangementsApi.putArrangements(accountArrangementItemPut) - .doOnNext(aVoid -> log.info("Updated Arrangement: {}", accountArrangementItemPut.getExternalArrangementId())).map(aVoid -> accountArrangementItemPut) - .thenReturn(accountArrangementItemPut) - .onErrorResume(WebClientResponseException.class, throwable -> - Mono.error(new ArrangementUpdateException(throwable, "Failed to update Arrangement: " + accountArrangementItemPut.getExternalArrangementId()))); - - } - - /** - * Upsert list of arrangements using DBS batch upsert API. - * - * @param arrangementItems list of arrangements to be upserted. - * @return flux of response items. - */ - public Flux upsertBatchArrangements(List arrangementItems) { - return arrangementsApi.postBatchUpsertArrangements(arrangementItems) - .map(r -> { - log.info("Batch Arrangement update result for arrangementId: {}, resourceId: {}, action: {}, result: {}", r.getArrangementId(), r.getResourceId(), r.getAction(), r.getStatus()); - // Check if any failed, then fail everything. - if (!BatchResponseStatusCode.HTTP_STATUS_OK.equals(r.getStatus())) { - List errors = r.getErrors(); - throw new IllegalStateException("Batch arrangement update failed: '" - + r.getResourceId() + "'; errors: " + (errors != null ? (String.join(",", - errors.stream().map(ErrorItem::toString).collect(Collectors.toList()))) : "unknown")); - } - return r; - }) - .onErrorResume(WebClientResponseException.class, throwable -> - Mono.error(new ArrangementUpdateException(throwable, "Batch arrangement update failed: " + arrangementItems))); + public Mono updateArrangement(ArrangementPutItem arrangementPutItem) { + log.info("Updating Arrangement: {}", arrangementPutItem.getExternalArrangementId()); + if(arrangementPutItem.getDebitCards() == null) { + arrangementPutItem.setDebitCards(emptyList()); + } + return arrangementsApi.putArrangementById(arrangementPutItem.getExternalArrangementId(), arrangementPutItem) + .doOnEach(aVoid -> log.info("Updated Arrangement: {}", arrangementPutItem.getExternalArrangementId())) + .thenReturn(fromCallable(() -> arrangementPutItem)) + .thenReturn(arrangementPutItem) + .onErrorResume(WebClientResponseException.class, throwable -> error(new ArrangementUpdateException(throwable, "Failed to update Arrangement: " + arrangementPutItem.getExternalArrangementId()))); } - public Mono updateUserPreferences(AccountUserPreferencesItemPut userPreferencesItemPut){ - return arrangementsApi.putUserPreferences(userPreferencesItemPut) - .doOnNext(arg -> log.info("Arrangement preferences created for User with ID: {}", userPreferencesItemPut.getUserId())) - .onErrorResume(WebClientResponseException.NotFound.class, ex -> { - log.info("Arrangement: {} not found", userPreferencesItemPut.getArrangementId()); - return Mono.empty(); - }); + public Flux upsertBatchArrangements(List arrangementItems) { + return arrangementsIntegrationApi.postBatchUpsertArrangements(arrangementItems) + .handle((r, sink) -> { + log.info("Batch Arrangement update result for arrangementId: {}, resourceId: {}, action: {}, result: {}", r.getArrangementId(), r.getResourceId(), r.getAction(), r.getStatus()); + // Check if any failed, then fail everything. + if (!BatchResponseStatusCode.HTTP_STATUS_OK.equals(r.getStatus())) { + List errors = r.getErrors(); + sink.error(new IllegalStateException("Batch arrangement update failed: '%s'; errors: %s" + .formatted(r.getResourceId(), join(",", errors.stream().map(ErrorItem::toString).toList())))); + return; + } + sink.next(r); + }).onErrorResume(WebClientResponseException.class, throwable -> + error(new ArrangementUpdateException(throwable, "Batch arrangement update failed: " + arrangementItems))); } /** @@ -104,7 +95,7 @@ public Mono updateUserPreferences(AccountUserPreferencesItemPut userPrefer * @param internalId Internal ID * @return Product */ - public Mono getArrangement(String internalId) { + public Mono getArrangement(String internalId) { return arrangementsApi.getArrangementById(internalId, false) .onErrorResume(WebClientResponseException.NotFound.class, ex -> { log.info("Arrangement: {} not found", internalId); @@ -112,32 +103,35 @@ public Mono getArrangement(String internalId) { }); } - public Flux getArrangementByExternalId(List externalId) { - Flux executeRequest = arrangementsApi.getArrangements(null, null, externalId) - .flatMapIterable(AccountArrangementItems::getArrangementElements); - return executeRequest; + public Flux getArrangementByExternalId(List externalId) { + ArrangementsSearchesPostRequest arrangementsSearchesPostRequest = new ArrangementsSearchesPostRequest(); + arrangementsSearchesPostRequest.setExternalArrangementIds(new HashSet<>(externalId)); + return arrangementsApi.postSearchArrangements(arrangementsSearchesPostRequest) + .flatMapIterable(ArrangementSearchesListResponse::getArrangementElements); } - public Mono getArrangementByExternalId(String externalId) { - return getArrangementByExternalId(Collections.singletonList(externalId)).next(); + public Mono getArrangementByExternalId(String externalId) { + return getArrangementByExternalId(singletonList(externalId)).next(); } public Mono getArrangementInternalId(String externalId) { log.info("Checking if arrangement exists with externalId: {}", externalId); - return arrangementsApi.getInternalId(externalId) - .doOnNext(response -> - log.info("Found Arrangement internalId: {} for externalId: {}", response.getInternalId(), externalId)) + ArrangementsSearchesPostRequest arrangementsSearchesPostRequest = new ArrangementsSearchesPostRequest(); + arrangementsSearchesPostRequest.setExternalArrangementIds(Set.of(externalId)); + return arrangementsApi.postSearchArrangements(arrangementsSearchesPostRequest) + .doOnNext(response -> { + String internalId = response.getArrangementElements().getFirst().getId(); + log.info("Found Arrangement internalId: {} for externalId: {}", internalId, externalId); + }) .onErrorResume(WebClientResponseException.NotFound.class, notFound -> { log.info("Arrangement not found with externalId: {}", externalId); return Mono.empty(); - }) - .onErrorResume(WebClientResponseException.class, exception -> { + }).onErrorResume(WebClientResponseException.class, exception -> { log.info("Exception while getting product by externalId: {}, {}", externalId, exception.getResponseBodyAsString()); return Mono.empty(); - }) - - .map(AccountInternalIdGetResponseBody::getInternalId); + }).map(arrangementSearchesListResponse -> arrangementSearchesListResponse.getArrangementElements() + .stream().map(ArrangementItem::getId).toList().getFirst()); } /** @@ -150,7 +144,7 @@ public Mono deleteArrangementByInternalId(String arrangementInternalId) log.debug("Retrieving Arrangement by internal id {}", arrangementInternalId); // get arrangement externalId by internal id. return arrangementsApi.getArrangementById(arrangementInternalId, false) - .map(AccountArrangementItem::getExternalArrangementId) + .mapNotNull(ArrangementItem::getExternalArrangementId) .onErrorResume(WebClientResponseException.class, e -> { log.warn("Failed to retrieve arrangement by internal id {}, {}", arrangementInternalId, e.getMessage()); return Mono.empty(); @@ -168,8 +162,15 @@ public Mono deleteArrangementByInternalId(String arrangementInternalId) */ public Mono deleteArrangementByExternalId(String arrangementExternalId) { log.debug("Removing Arrangement with external id {}", arrangementExternalId); - return arrangementsApi.deleteExternalArrangementId(arrangementExternalId) - .thenReturn(arrangementExternalId); + Set arrangementsDeleteItemSet = new HashSet<>(); + ArrangementsDeleteItem arrangementsDeleteItem = new ArrangementsDeleteItem(); + arrangementsDeleteItem.setSelector(EXTERNAL_ID); + arrangementsDeleteItem.setValue(arrangementExternalId); + arrangementsDeleteItemSet.add(arrangementsDeleteItem); + return arrangementsApi.postDelete(arrangementsDeleteItemSet) + .filter(arrangementsDeleteResponseElement -> EXTERNAL_ID.getValue().equals(arrangementsDeleteResponseElement.getSelector().getValue())) + .map(ArrangementsDeleteResponseElement::getValue) + .collectList().map(List::getFirst); } /** @@ -182,8 +183,8 @@ public Mono deleteArrangementByExternalId(String arrangementExternalId) public Mono addLegalEntitiesForArrangement(String arrangementExternalId, List legalEntitiesExternalIds) { log.debug("Attaching Arrangement {} to Legal Entities: {}", arrangementExternalId, legalEntitiesExternalIds); - return arrangementsApi.postArrangementLegalEntities(arrangementExternalId, - new AccountExternalLegalEntityIds().ids(new HashSet<>(legalEntitiesExternalIds))); + return arrangementsIntegrationApi.postArrangementLegalEntities(arrangementExternalId, new ExternalLegalEntityIds() + .ids(new HashSet<>(legalEntitiesExternalIds))); } /** @@ -196,8 +197,8 @@ public Mono addLegalEntitiesForArrangement(String arrangementExternalId, public Mono removeLegalEntityFromArrangement(String arrangementExternalId, List legalEntityExternalIds) { log.debug("Removing Arrangement {} from Legal Entities {}", arrangementExternalId, legalEntityExternalIds); - return arrangementsApi.deleteArrangementLegalEntities(arrangementExternalId, - new AccountExternalLegalEntityIds().ids(new HashSet<>(legalEntityExternalIds))); + return arrangementsIntegrationApi.deleteArrangementLegalEntities(arrangementExternalId, + new ExternalLegalEntityIds().ids(new HashSet<>(legalEntityExternalIds))); } } diff --git a/stream-product/product-core/src/test/java/com/backbase/stream/product/mapping/ProductMapperTest.java b/stream-product/product-core/src/test/java/com/backbase/stream/product/mapping/ProductMapperTest.java index 6b99d5343..bd1f0dba7 100644 --- a/stream-product/product-core/src/test/java/com/backbase/stream/product/mapping/ProductMapperTest.java +++ b/stream-product/product-core/src/test/java/com/backbase/stream/product/mapping/ProductMapperTest.java @@ -1,26 +1,45 @@ package com.backbase.stream.product.mapping; -import com.backbase.dbs.arrangement.api.service.v2.model.*; -import com.backbase.stream.legalentity.model.*; +import com.backbase.dbs.arrangement.api.integration.v2.model.PostArrangement; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; +import com.backbase.stream.legalentity.model.AvailableBalance; +import com.backbase.stream.legalentity.model.BaseProduct; +import com.backbase.stream.legalentity.model.BaseProductState; +import com.backbase.stream.legalentity.model.BookedBalance; +import com.backbase.stream.legalentity.model.CreditCard; +import com.backbase.stream.legalentity.model.CreditLimit; +import com.backbase.stream.legalentity.model.CurrentAccount; +import com.backbase.stream.legalentity.model.CurrentInvestment; +import com.backbase.stream.legalentity.model.DebitCard; import com.backbase.stream.legalentity.model.DebitCardItem; import com.backbase.stream.legalentity.model.InterestDetails; -import com.backbase.stream.legalentity.model.UserPreferences; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mapstruct.factory.Mappers; - +import com.backbase.stream.legalentity.model.InterestPaymentFrequencyUnit; +import com.backbase.stream.legalentity.model.InvestmentAccount; +import com.backbase.stream.legalentity.model.LegalEntity; +import com.backbase.stream.legalentity.model.LegalEntityReference; +import com.backbase.stream.legalentity.model.Loan; +import com.backbase.stream.legalentity.model.PrincipalAmount; +import com.backbase.stream.legalentity.model.Product; +import com.backbase.stream.legalentity.model.ReservedAmount; +import com.backbase.stream.legalentity.model.SavingsAccount; +import com.backbase.stream.legalentity.model.TermDeposit; +import com.backbase.stream.legalentity.model.TermUnit; import java.math.BigDecimal; import java.time.LocalDate; import java.time.OffsetDateTime; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; -public class ProductMapperTest { +class ProductMapperTest { private final ProductMapper productMapper = Mappers.getMapper(ProductMapper.class); LegalEntityReference buildLegalEntityReference(String legalEntityExternalId) { - return new LegalEntityReference().externalId(legalEntityExternalId); + return new LegalEntityReference(null, legalEntityExternalId); } private void buildBaseProduct(BaseProduct baseProduct) { @@ -117,204 +136,208 @@ private Loan buildLoan() { } @Test - public void map_Product_To_AccountArrangementItemPost() { + void map_Product_To_AccountArrangementItemPost() { Product source = buildProduct(); - AccountArrangementItemPost target = productMapper.toPresentation(source); - Assertions.assertEquals(source.getExternalId(), target.getExternalArrangementId()); - Assertions.assertEquals(source.getProductTypeExternalId(), target.getExternalProductId()); - Assertions.assertNotNull(target.getExternalLegalEntityIds()); - Assertions.assertEquals(source.getLegalEntities().size(), target.getExternalLegalEntityIds().size()); - Assertions.assertEquals(source.getState().getExternalStateId(), target.getExternalStateId()); + PostArrangement target = productMapper.toPresentation(source); + Assertions.assertEquals(source.getExternalId(), target.getId()); + Assertions.assertEquals(source.getProductTypeExternalId(), target.getProductId()); + Assertions.assertNotNull(target.getLegalEntityIds()); + Assertions.assertEquals(source.getLegalEntities().size(), target.getLegalEntityIds().size()); + Assertions.assertEquals(source.getState().getExternalStateId(), target.getStateId()); Assertions.assertEquals(source.getAccountHolderName(), target.getAccountHolderNames()); } @Test - public void map_BaseProduct_To_AccountArrangementItemPost() { + void map_BaseProduct_To_AccountArrangementItemPost() { Product source = buildProduct(); - AccountArrangementItemPost target = productMapper.toPresentation(source); - Assertions.assertEquals(source.getExternalId(), target.getExternalArrangementId()); - Assertions.assertEquals(source.getProductTypeExternalId(), target.getExternalProductId()); - Assertions.assertNotNull(target.getExternalLegalEntityIds()); - Assertions.assertEquals(source.getLegalEntities().size(), target.getExternalLegalEntityIds().size()); - Assertions.assertEquals(source.getState().getExternalStateId(), target.getExternalStateId()); + PostArrangement target = productMapper.toPresentation(source); + Assertions.assertEquals(source.getExternalId(), target.getId()); + Assertions.assertEquals(source.getProductTypeExternalId(), target.getProductId()); + Assertions.assertNotNull(target.getLegalEntityIds()); + Assertions.assertEquals(source.getLegalEntities().size(), target.getLegalEntityIds().size()); + Assertions.assertEquals(source.getState().getExternalStateId(), target.getStateId()); Assertions.assertEquals(source.getAccountHolderName(), target.getAccountHolderNames()); } @Test - public void map_SavingsAccount_To_AccountArrangementItemPost() { + void map_SavingsAccount_To_AccountArrangementItemPost() { SavingsAccount source = buildSavingsAccount(); - AccountArrangementItemPost target = productMapper.toPresentation(source); - Assertions.assertEquals(source.getExternalId(), target.getExternalArrangementId()); - Assertions.assertEquals(source.getProductTypeExternalId(), target.getExternalProductId()); - Assertions.assertNotNull(target.getExternalLegalEntityIds()); - Assertions.assertEquals(source.getLegalEntities().size(), target.getExternalLegalEntityIds().size()); + PostArrangement target = productMapper.toPresentation(source); + Assertions.assertEquals(source.getExternalId(), target.getId()); + Assertions.assertEquals(source.getProductTypeExternalId(), target.getProductId()); + Assertions.assertNotNull(target.getLegalEntityIds()); + Assertions.assertEquals(source.getLegalEntities().size(), target.getLegalEntityIds().size()); Assertions.assertNotNull(target.getDebitCards()); Assertions.assertEquals(source.getDebitCardsItems().size(), target.getDebitCards().size()); - Assertions.assertEquals(source.getState().getExternalStateId(), target.getExternalStateId()); + Assertions.assertEquals(source.getState().getExternalStateId(), target.getStateId()); Assertions.assertEquals(source.getAccountHolderName(), target.getAccountHolderNames()); } @Test - public void map_DebitCard_To_AccountArrangementItemPost() { + void map_DebitCard_To_AccountArrangementItemPost() { DebitCard source = buildDebitCard(); - AccountArrangementItemPost target = productMapper.toPresentation(source); - Assertions.assertEquals(source.getExternalId(), target.getExternalArrangementId()); - Assertions.assertEquals(source.getProductTypeExternalId(), target.getExternalProductId()); - Assertions.assertNotNull(target.getExternalLegalEntityIds()); - Assertions.assertEquals(source.getLegalEntities().size(), target.getExternalLegalEntityIds().size()); - Assertions.assertEquals(source.getState().getExternalStateId(), target.getExternalStateId()); + PostArrangement target = productMapper.toPresentation(source); + Assertions.assertEquals(source.getExternalId(), target.getId()); + Assertions.assertEquals(source.getProductTypeExternalId(), target.getProductId()); + Assertions.assertNotNull(target.getLegalEntityIds()); + Assertions.assertEquals(source.getLegalEntities().size(), target.getLegalEntityIds().size()); + Assertions.assertEquals(source.getState().getExternalStateId(), target.getStateId()); Assertions.assertEquals(source.getAccountHolderName(), target.getAccountHolderNames()); } @Test - public void map_CreditCard_To_AccountArrangementItemPost() { + void map_CreditCard_To_AccountArrangementItemPost() { CreditCard source = buildCreditCard(); - AccountArrangementItemPost target = productMapper.toPresentation(source); - Assertions.assertEquals(source.getExternalId(), target.getExternalArrangementId()); - Assertions.assertEquals(source.getProductTypeExternalId(), target.getExternalProductId()); - Assertions.assertNotNull(target.getExternalLegalEntityIds()); - Assertions.assertEquals(source.getLegalEntities().size(), target.getExternalLegalEntityIds().size()); - Assertions.assertEquals(source.getState().getExternalStateId(), target.getExternalStateId()); + PostArrangement target = productMapper.toPresentation(source); + Assertions.assertEquals(source.getExternalId(), target.getId()); + Assertions.assertEquals(source.getProductTypeExternalId(), target.getProductId()); + Assertions.assertNotNull(target.getLegalEntityIds()); + Assertions.assertEquals(source.getLegalEntities().size(), target.getLegalEntityIds().size()); + Assertions.assertEquals(source.getState().getExternalStateId(), target.getStateId()); Assertions.assertEquals(source.getAccountHolderName(), target.getAccountHolderNames()); } @Test - public void map_TermDeposit_To_AccountArrangementItemPost() { + void map_TermDeposit_To_AccountArrangementItemPost() { TermDeposit source = buildTermDeposit(); - AccountArrangementItemPost target = productMapper.toPresentation(source); - Assertions.assertEquals(source.getExternalId(), target.getExternalArrangementId()); - Assertions.assertEquals(source.getProductTypeExternalId(), target.getExternalProductId()); - Assertions.assertNotNull(target.getExternalLegalEntityIds()); - Assertions.assertEquals(source.getLegalEntities().size(), target.getExternalLegalEntityIds().size()); - Assertions.assertEquals(source.getState().getExternalStateId(), target.getExternalStateId()); + PostArrangement target = productMapper.toPresentation(source); + Assertions.assertEquals(source.getExternalId(), target.getId()); + Assertions.assertEquals(source.getProductTypeExternalId(), target.getProductId()); + Assertions.assertNotNull(target.getLegalEntityIds()); + Assertions.assertEquals(source.getLegalEntities().size(), target.getLegalEntityIds().size()); + Assertions.assertEquals(source.getState().getExternalStateId(), target.getStateId()); Assertions.assertEquals(source.getAccountHolderName(), target.getAccountHolderNames()); } @Test - public void map_InvestmentAccount_To_AccountArrangementItemPost() { + void map_InvestmentAccount_To_AccountArrangementItemPost() { InvestmentAccount source = buildInvestmentAccount(); - AccountArrangementItemPost target = productMapper.toPresentation(source); - Assertions.assertEquals(source.getExternalId(), target.getExternalArrangementId()); - Assertions.assertEquals(source.getProductTypeExternalId(), target.getExternalProductId()); - Assertions.assertNotNull(target.getExternalLegalEntityIds()); - Assertions.assertEquals(source.getLegalEntities().size(), target.getExternalLegalEntityIds().size()); - Assertions.assertEquals(source.getState().getExternalStateId(), target.getExternalStateId()); + PostArrangement target = productMapper.toPresentation(source); + Assertions.assertEquals(source.getExternalId(), target.getId()); + Assertions.assertEquals(source.getProductTypeExternalId(), target.getProductId()); + Assertions.assertNotNull(target.getLegalEntityIds()); + Assertions.assertEquals(source.getLegalEntities().size(), target.getLegalEntityIds().size()); + Assertions.assertEquals(source.getState().getExternalStateId(), target.getStateId()); } @Test - public void map_Loan_To_AccountArrangementItemPost() { + void map_Loan_To_AccountArrangementItemPost() { Loan source = buildLoan(); - AccountArrangementItemPost target = productMapper.toPresentation(source); - Assertions.assertEquals(source.getExternalId(), target.getExternalArrangementId()); - Assertions.assertEquals(source.getProductTypeExternalId(), target.getExternalProductId()); - Assertions.assertNotNull(target.getExternalLegalEntityIds()); - Assertions.assertEquals(source.getLegalEntities().size(), target.getExternalLegalEntityIds().size()); - Assertions.assertEquals(source.getState().getExternalStateId(), target.getExternalStateId()); + PostArrangement target = productMapper.toPresentation(source); + Assertions.assertEquals(source.getExternalId(), target.getId()); + Assertions.assertEquals(source.getProductTypeExternalId(), target.getProductId()); + Assertions.assertNotNull(target.getLegalEntityIds()); + Assertions.assertEquals(source.getLegalEntities().size(), target.getLegalEntityIds().size()); + Assertions.assertEquals(source.getState().getExternalStateId(), target.getStateId()); Assertions.assertEquals(source.getAccountHolderName(), target.getAccountHolderNames()); } @Test - public void map_AccountArrangementItemPost_To_AccountArrangementItem() { - AccountArrangementItemPost source = productMapper.toPresentation(buildProduct()); - AccountArrangementItem target = productMapper.toArrangementItem(source); - Assertions.assertEquals(target.getExternalArrangementId(), source.getExternalArrangementId()); - Assertions.assertEquals(target.getExternalProductId(), source.getExternalProductId()); - Assertions.assertEquals(target.getExternalStateId(), source.getExternalStateId()); + void map_AccountArrangementItemPost_To_AccountArrangementItem() { + PostArrangement source = productMapper.toPresentation(buildProduct()); + source.setStateId("123"); + ArrangementPutItem target = productMapper.toArrangementItemPut(source); + + Assertions.assertEquals(target.getExternalArrangementId(), source.getId()); + Assertions.assertEquals(String.valueOf(target.getStateId()), source.getStateId()); Assertions.assertEquals(target.getAccountHolderNames(), source.getAccountHolderNames()); } @Test - public void map_AccountArrangementItemPost_To_AccountArrangementItemPut() { - AccountArrangementItemPost source = productMapper.toPresentation(buildProduct()); - AccountArrangementItemPut target = productMapper.toArrangementItemPut(source); - Assertions.assertEquals(target.getExternalArrangementId(), source.getExternalArrangementId()); - Assertions.assertEquals(target.getExternalStateId(), source.getExternalStateId()); + void map_AccountArrangementItemPost_To_AccountArrangementItemPut() { + PostArrangement source = productMapper.toPresentation(buildProduct()); + source.setStateId("123"); + ArrangementPutItem target = productMapper.toArrangementItemPut(source); + + Assertions.assertEquals(target.getExternalArrangementId(), source.getId()); + Assertions.assertEquals(String.valueOf(target.getStateId()), source.getStateId()); Assertions.assertEquals(target.getAccountHolderNames(), source.getAccountHolderNames()); } @Test - public void map_AccountArrangementItemBase_To_AccountArrangementItem() { - AccountArrangementItemPost source = productMapper.toPresentation(buildProduct()); - AccountArrangementItem target = productMapper.toArrangementItem(source); - Assertions.assertEquals(target.getExternalArrangementId(), source.getExternalArrangementId()); - Assertions.assertEquals(target.getExternalStateId(), source.getExternalStateId()); + void map_AccountArrangementItemBase_To_AccountArrangementItem() { + PostArrangement source = productMapper.toPresentation(buildProduct()); + ArrangementItem target = productMapper.toArrangementItem(source); + Assertions.assertEquals(target.getId(), source.getId()); + Assertions.assertNotNull(target.getState()); + Assertions.assertEquals(target.getState().getState(), source.getStateId()); Assertions.assertEquals(target.getAccountHolderNames(), source.getAccountHolderNames()); } @Test - public void map_Product_To_AccountArrangementItem() { + void map_Product_To_AccountArrangementItem() { Product source = buildProduct(); - AccountArrangementItem target = productMapper.toPresentationWithWeirdSpellingError(source); + ArrangementItem target = productMapper.toPresentationWithWeirdSpellingError(source); Assertions.assertEquals(target.getExternalArrangementId(), source.getExternalId()); Assertions.assertEquals(target.getExternalStateId(), source.getState().getExternalStateId()); } @Test - public void map_AccountArrangementItem_To_Product() { - AccountArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); + void map_AccountArrangementItem_To_Product() { + ArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); Product target = productMapper.mapCustomProduct(source); Assertions.assertEquals(target.getExternalId(), source.getExternalArrangementId()); Assertions.assertEquals(target.getProductTypeExternalId(), source.getExternalProductId()); } @Test - public void map_AccountArrangementItem_To_CurrentAccount() { - AccountArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); + void map_AccountArrangementItem_To_CurrentAccount() { + ArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); CurrentAccount target = productMapper.mapCurrentAccount(source); Assertions.assertEquals(target.getExternalId(), source.getExternalArrangementId()); Assertions.assertEquals(target.getProductTypeExternalId(), source.getExternalProductId()); } @Test - public void map_AccountArrangementItem_To_SavingsAccount() { - AccountArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); + void map_AccountArrangementItem_To_SavingsAccount() { + ArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); SavingsAccount target = productMapper.mapSavingAccount(source); Assertions.assertEquals(target.getExternalId(), source.getExternalArrangementId()); Assertions.assertEquals(target.getProductTypeExternalId(), source.getExternalProductId()); } @Test - public void map_AccountArrangementItem_To_DebitCard() { - AccountArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); + void map_AccountArrangementItem_To_DebitCard() { + ArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); DebitCard target = productMapper.mapDebitCard(source); Assertions.assertEquals(target.getExternalId(), source.getExternalArrangementId()); Assertions.assertEquals(target.getProductTypeExternalId(), source.getExternalProductId()); } @Test - public void map_AccountArrangementItem_To_CreditCard() { - AccountArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); + void map_AccountArrangementItem_To_CreditCard() { + ArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); CreditCard target = productMapper.mapCreditCard(source); Assertions.assertEquals(target.getExternalId(), source.getExternalArrangementId()); Assertions.assertEquals(target.getProductTypeExternalId(), source.getExternalProductId()); } @Test - public void map_AccountArrangementItem_To_Loan() { - AccountArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); + void map_AccountArrangementItem_To_Loan() { + ArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); Loan target = productMapper.mapLoan(source); Assertions.assertEquals(target.getExternalId(), source.getExternalArrangementId()); Assertions.assertEquals(target.getProductTypeExternalId(), source.getExternalProductId()); } @Test - public void map_AccountArrangementItem_To_TermDeposit() { - AccountArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); + void map_AccountArrangementItem_To_TermDeposit() { + ArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); TermDeposit target = productMapper.mapTermDeposit(source); Assertions.assertEquals(target.getExternalId(), source.getExternalArrangementId()); Assertions.assertEquals(target.getProductTypeExternalId(), source.getExternalProductId()); } @Test - public void map_AccountArrangementItem_To_InvestmentAccount() { - AccountArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); + void map_AccountArrangementItem_To_InvestmentAccount() { + ArrangementItem source = productMapper.toArrangementItem(productMapper.toPresentation(buildProduct())); InvestmentAccount target = productMapper.mapInvestmentAccount(source); Assertions.assertEquals(target.getExternalId(), source.getExternalArrangementId()); Assertions.assertEquals(target.getProductTypeExternalId(), source.getExternalProductId()); } @Test - public void mapBookedBalance() { + void mapBookedBalance() { BigDecimal source = new BigDecimal("130.79"); BookedBalance target = productMapper.mapBookedBalance(source); Assertions.assertEquals(source, target.getAmount()); @@ -328,7 +351,7 @@ public void mapReservedAmount() { } @Test - public void mapAvailable() { + void mapAvailable() { BigDecimal source = new BigDecimal("130.79"); AvailableBalance target = productMapper.mapAvailable(source); Assertions.assertEquals(source, target.getAmount()); @@ -342,62 +365,62 @@ void mapCurrentInvestment() { } @Test - public void mapPrincipal() { + void mapPrincipal() { BigDecimal source = new BigDecimal("130.79"); PrincipalAmount target = productMapper.mapPrincipal(source); Assertions.assertEquals(source, target.getAmount()); } @Test - public void mapCreditLimit() { + void mapCreditLimit() { BigDecimal source = new BigDecimal("130.79"); CreditLimit target = productMapper.mapCreditLimit(source); Assertions.assertEquals(source, target.getAmount()); } @Test - public void mapLegalEntity() { + void mapLegalEntity() { LegalEntity target = productMapper.mapLegalEntity("leid"); Assertions.assertEquals("leid", target.getExternalId()); } @Test - public void map_TermUnit_To_TimeUnit() { + void map_TermUnit_To_TimeUnit() { Assertions.assertNull(productMapper.map(TermUnit.QUARTERLY)); - Assertions.assertEquals(TimeUnit.D, productMapper.map(TermUnit.DAILY)); - Assertions.assertEquals(TimeUnit.W, productMapper.map(TermUnit.WEEKLY)); - Assertions.assertEquals(TimeUnit.M, productMapper.map(TermUnit.MONTHLY)); - Assertions.assertEquals(TimeUnit.Y, productMapper.map(TermUnit.YEARLY)); + Assertions.assertEquals(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.D, productMapper.map(TermUnit.DAILY)); + Assertions.assertEquals(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.W, productMapper.map(TermUnit.WEEKLY)); + Assertions.assertEquals(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.M, productMapper.map(TermUnit.MONTHLY)); + Assertions.assertEquals(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.Y, productMapper.map(TermUnit.YEARLY)); } @Test - public void map_InterestPaymentFrequencyUnit_To_TimeUnit() { + void map_InterestPaymentFrequencyUnit_To_TimeUnit() { Assertions.assertNull(productMapper.map(InterestPaymentFrequencyUnit.QUARTERLY)); - Assertions.assertEquals(TimeUnit.D, productMapper.map(InterestPaymentFrequencyUnit.DAILY)); - Assertions.assertEquals(TimeUnit.W, productMapper.map(InterestPaymentFrequencyUnit.WEEKLY)); - Assertions.assertEquals(TimeUnit.M, productMapper.map(InterestPaymentFrequencyUnit.MONTHLY)); - Assertions.assertEquals(TimeUnit.Y, productMapper.map(InterestPaymentFrequencyUnit.YEARLY)); + Assertions.assertEquals(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.D, productMapper.map(InterestPaymentFrequencyUnit.DAILY)); + Assertions.assertEquals(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.W, productMapper.map(InterestPaymentFrequencyUnit.WEEKLY)); + Assertions.assertEquals(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.M, productMapper.map(InterestPaymentFrequencyUnit.MONTHLY)); + Assertions.assertEquals(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.Y, productMapper.map(InterestPaymentFrequencyUnit.YEARLY)); } @Test - public void map_TimeUnit_TermUnit() { - Assertions.assertEquals(TermUnit.DAILY, productMapper.map(TimeUnit.D)); - Assertions.assertEquals(TermUnit.WEEKLY, productMapper.map(TimeUnit.W)); - Assertions.assertEquals(TermUnit.MONTHLY, productMapper.map(TimeUnit.M)); - Assertions.assertEquals(TermUnit.YEARLY, productMapper.map(TimeUnit.Y)); + void map_TimeUnit_TermUnit() { + Assertions.assertEquals(TermUnit.DAILY, productMapper.map(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.D)); + Assertions.assertEquals(TermUnit.WEEKLY, productMapper.map(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.W)); + Assertions.assertEquals(TermUnit.MONTHLY, productMapper.map(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.M)); + Assertions.assertEquals(TermUnit.YEARLY, productMapper.map(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.Y)); } @Test - public void map_TimeUnit_To_InterestPaymentFrequencyUnit() { + void map_TimeUnit_To_InterestPaymentFrequencyUnit() { Assertions.assertNull(productMapper.mapInterestPayment(null)); - Assertions.assertEquals(InterestPaymentFrequencyUnit.DAILY, productMapper.mapInterestPayment(TimeUnit.D)); - Assertions.assertEquals(InterestPaymentFrequencyUnit.WEEKLY, productMapper.mapInterestPayment(TimeUnit.W)); - Assertions.assertEquals(InterestPaymentFrequencyUnit.MONTHLY, productMapper.mapInterestPayment(TimeUnit.M)); - Assertions.assertEquals(InterestPaymentFrequencyUnit.YEARLY, productMapper.mapInterestPayment(TimeUnit.Y)); + Assertions.assertEquals(InterestPaymentFrequencyUnit.DAILY, productMapper.mapInterestPayment(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.D)); + Assertions.assertEquals(InterestPaymentFrequencyUnit.WEEKLY, productMapper.mapInterestPayment(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.W)); + Assertions.assertEquals(InterestPaymentFrequencyUnit.MONTHLY, productMapper.mapInterestPayment(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.M)); + Assertions.assertEquals(InterestPaymentFrequencyUnit.YEARLY, productMapper.mapInterestPayment(com.backbase.dbs.arrangement.api.integration.v2.model.TimeUnit.Y)); } @Test - public void mapLegalEntityId() { + void mapLegalEntityId() { Assertions.assertNull(productMapper.mapLegalEntityId(null)); List legalEntityReferenceList = List.of(buildLegalEntityReference("leid_1"), buildLegalEntityReference("leid_2")); @@ -407,26 +430,4 @@ public void mapLegalEntityId() { Assertions.assertNull(productMapper.mapLegalEntityReference(null)); Assertions.assertEquals(legalEntityIdList.size(), productMapper.mapLegalEntityReference(legalEntityIdList).size()); } - - @Test - public void mapUserPreference() { - Assertions.assertNull(productMapper.mapUserPreference(null)); - - UserPreferences source = new UserPreferences() - .userExternalId("user_ext_id") - .visible(true) - .alias("user_alias") - .favorite(false) - .putAdditionsItem("k1", "v1") - .putAdditionsItem("k2", "v2"); - - AccountUserPreferencesItemPut target = productMapper.mapUserPreference(source); - Assertions.assertEquals(source.getUserExternalId(), target.getUserId()); - Assertions.assertEquals(source.getVisible(), target.getVisible()); - Assertions.assertEquals(source.getAlias(), target.getAlias()); - Assertions.assertEquals(source.getFavorite(), target.getFavorite()); - Assertions.assertNotNull(target.getAdditions()); - Assertions.assertEquals(source.getAdditions().size(), target.getAdditions().size()); - } - } diff --git a/stream-product/product-core/src/test/java/com/backbase/stream/product/service/ArrangementServiceTest.java b/stream-product/product-core/src/test/java/com/backbase/stream/product/service/ArrangementServiceTest.java index e1807cca9..4b298cb4a 100644 --- a/stream-product/product-core/src/test/java/com/backbase/stream/product/service/ArrangementServiceTest.java +++ b/stream-product/product-core/src/test/java/com/backbase/stream/product/service/ArrangementServiceTest.java @@ -1,27 +1,27 @@ package com.backbase.stream.product.service; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.backbase.dbs.arrangement.api.integration.v2.model.ArrangementAddedResponse; +import com.backbase.dbs.arrangement.api.integration.v2.model.BatchResponseItemExtended; +import com.backbase.dbs.arrangement.api.integration.v2.model.BatchResponseStatusCode; +import com.backbase.dbs.arrangement.api.integration.v2.model.ErrorItem; +import com.backbase.dbs.arrangement.api.integration.v2.model.ExternalLegalEntityIds; +import com.backbase.dbs.arrangement.api.integration.v2.model.PostArrangement; import com.backbase.dbs.arrangement.api.service.ApiClient; -import com.backbase.dbs.arrangement.api.service.v2.ArrangementsApi; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementAddedResponse; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPost; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItems; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountBatchResponseItemExtended; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountExternalLegalEntityIds; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountInternalIdGetResponseBody; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountUserPreferencesItemPut; -import com.backbase.dbs.arrangement.api.service.v2.model.BatchResponseStatusCode; -import com.backbase.dbs.arrangement.api.service.v2.model.ErrorItem; +import com.backbase.dbs.arrangement.api.service.v3.ArrangementsApi; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementSearchesListResponse; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsDeleteItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsDeleteItem.SelectorEnum; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsDeleteResponseElement; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementsSearchesPostRequest; import com.backbase.stream.product.exception.ArrangementCreationException; import com.backbase.stream.product.exception.ArrangementUpdateException; import java.util.ArrayList; @@ -41,7 +41,7 @@ import reactor.test.StepVerifier; @ExtendWith(MockitoExtension.class) -public class ArrangementServiceTest { +class ArrangementServiceTest { @InjectMocks private ArrangementService arrangementService; @@ -49,153 +49,143 @@ public class ArrangementServiceTest { @Mock private ArrangementsApi arrangementsApi; - private static WebClientResponseException buildWebClientResponseException(HttpStatus httpStatus, - String statusText) { + @Mock + private com.backbase.dbs.arrangement.api.integration.v2.ArrangementsApi arrangementsIntegrationApi; + + private static WebClientResponseException buildWebClientResponseException(HttpStatus httpStatus, String statusText) { return WebClientResponseException.create(httpStatus.value(), statusText, null, null, null); } - private static AccountArrangementItemPost buildAccountArrangementItemPost() { - return new AccountArrangementItemPost() - .externalArrangementId("ext_arr_id") - .externalLegalEntityIds(Set.of("ext_leid_1", "ext_leid_2")) - .legalEntityIds(Set.of("leid_1", "leid_2")) - .externalProductId("ext_prod_id") - .externalStateId("ext_state_id") - .productId("prod_id"); + private static PostArrangement buildPostArrangement() { + PostArrangement postArrangement = new PostArrangement(); + postArrangement.setId("ext_arr_id"); + postArrangement.setLegalEntityIds(Set.of("ext_leid_1", "ext_leid_2")); + postArrangement.setProductId("ext_prod_id"); + postArrangement.setStateId("ext_state_id"); + return postArrangement; } - private static AccountArrangementItemPut buildAccountArrangementItemPut() { - return new AccountArrangementItemPut() + private static ArrangementPutItem buildArrangementPutItem() { + return new ArrangementPutItem() .externalArrangementId("ext_arr_id") .productId("prod_id"); } - private static AccountUserPreferencesItemPut buildAccountUserPreferencesItemPut() { - return new AccountUserPreferencesItemPut() - .arrangementId("arr_id") - .userId("user_id"); - } + // USER PREFERENCES UPDATE HAS BEEN REMOVED FROM V3 ENDPOINT ONWARDS BECAUSE USER PREFERENCES + // UPDATE IS AN INTERNAL OPERATION +// private static AccountUserPreferencesItemPut buildAccountUserPreferencesItemPut() { +// return new AccountUserPreferencesItemPut() +// .arrangementId("arr_id") +// .userId("user_id"); +// } @Test void createArrangement() { - AccountArrangementItemPost request = buildAccountArrangementItemPost(); + PostArrangement request = buildPostArrangement(); - AccountArrangementAddedResponse accountArrangementAddedResponse = new AccountArrangementAddedResponse().id( - "arr_response_id"); - when(arrangementsApi.postArrangements(any())) - .thenReturn(Mono.just(accountArrangementAddedResponse)); + ArrangementItem accountArrangementAddedResponse = new ArrangementItem().id("arr_response_id"); + + ArrangementAddedResponse arrangementAddedResponse = new ArrangementAddedResponse().id(accountArrangementAddedResponse.getId()); + when(arrangementsIntegrationApi.postArrangements(request)).thenReturn(Mono.just(arrangementAddedResponse)); StepVerifier.create(arrangementService.createArrangement(request)) .assertNext(response -> { Assertions.assertNotNull(response); Assertions.assertEquals(accountArrangementAddedResponse.getId(), response.getId()); - Assertions.assertEquals(request.getExternalArrangementId(), response.getExternalArrangementId()); - Assertions.assertEquals(request.getExternalProductId(), response.getExternalProductId()); - Assertions.assertEquals(request.getExternalStateId(), response.getExternalStateId()); - Assertions.assertEquals(request.getExternalProductId(), response.getExternalProductId()); + Assertions.assertEquals(request.getProductId(), response.getProductId()); + Assertions.assertNotNull(response.getState()); + Assertions.assertEquals(request.getStateId(), response.getState().getState()); + Assertions.assertEquals(request.getProductId(), response.getProductId()); Assertions.assertEquals(request.getLegalEntityIds(), response.getLegalEntityIds()); - }) - .verifyComplete(); + }).verifyComplete(); - verify(arrangementsApi).postArrangements(any()); + verify(arrangementsIntegrationApi).postArrangements(request); } @Test void createArrangement_Failure() { - AccountArrangementItemPost request = buildAccountArrangementItemPost(); + PostArrangement request = buildPostArrangement(); - WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.BAD_REQUEST, - "Bad Request for create arrangement"); + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.BAD_REQUEST, "Bad Request for create arrangement"); - when(arrangementsApi.postArrangements(any())) - .thenReturn(Mono.error(webClientResponseException)); + when(arrangementsIntegrationApi.postArrangements(any())).thenReturn(Mono.error(webClientResponseException)); StepVerifier.create(arrangementService.createArrangement(request)) .consumeErrorWith(e -> { - Assertions.assertTrue(e instanceof ArrangementCreationException); + Assertions.assertInstanceOf(ArrangementCreationException.class, e); Assertions.assertEquals("Failed to post arrangements", e.getMessage()); Assertions.assertEquals(webClientResponseException.getMessage(), e.getCause().getMessage()); - }) - .verify(); + }).verify(); - verify(arrangementsApi).postArrangements(any()); + verify(arrangementsIntegrationApi).postArrangements(any()); } @Test void updateArrangement() { - AccountArrangementItemPut request = buildAccountArrangementItemPut(); + ArrangementPutItem request = buildArrangementPutItem(); - when(arrangementsApi.putArrangements(any())) - .thenReturn(Mono.empty()); + when(arrangementsApi.putArrangementById(request.getExternalArrangementId(), request)).thenReturn(Mono.empty()); StepVerifier.create(arrangementService.updateArrangement(request)) .assertNext(response -> { Assertions.assertNotNull(response); Assertions.assertEquals(request.getExternalArrangementId(), response.getExternalArrangementId()); Assertions.assertEquals(request.getProductId(), response.getProductId()); - }) - .verifyComplete(); + }).verifyComplete(); - verify(arrangementsApi).putArrangements(any()); + verify(arrangementsApi).putArrangementById(request.getExternalArrangementId(), request); } @Test void updateArrangement_Failure() { - AccountArrangementItemPut request = buildAccountArrangementItemPut(); + ArrangementPutItem request = buildArrangementPutItem(); - WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.BAD_REQUEST, - "Bad Request for update arrangement"); - when(arrangementsApi.putArrangements(any())) - .thenReturn(Mono.error(webClientResponseException)); + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.BAD_REQUEST, "Bad Request for update arrangement"); + when(arrangementsApi.putArrangementById(request.getExternalArrangementId(), request)).thenReturn(Mono.error(webClientResponseException)); StepVerifier.create(arrangementService.updateArrangement(request)) .consumeErrorWith(e -> { - Assertions.assertTrue(e instanceof ArrangementUpdateException); - Assertions.assertEquals("Failed to update Arrangement: " + request.getExternalArrangementId(), - e.getMessage()); + Assertions.assertInstanceOf(ArrangementUpdateException.class, e); + Assertions.assertEquals("Failed to update Arrangement: %s".formatted(request.getExternalArrangementId()), e.getMessage()); Assertions.assertEquals(webClientResponseException.getMessage(), e.getCause().getMessage()); - }) - .verify(); + }).verify(); - verify(arrangementsApi).putArrangements(any()); + verify(arrangementsApi).putArrangementById(request.getExternalArrangementId(), request); } @Test void upsertBatchArrangements() { - AccountArrangementItemPost request = buildAccountArrangementItemPost(); + PostArrangement request = buildPostArrangement(); - AccountBatchResponseItemExtended accountBatchResponseItemExtended = new AccountBatchResponseItemExtended() + BatchResponseItemExtended accountBatchResponseItemExtended = (BatchResponseItemExtended) new BatchResponseItemExtended() .arrangementId("arr_id") .resourceId("resource_id") .status(BatchResponseStatusCode.HTTP_STATUS_OK); - when(arrangementsApi.postBatchUpsertArrangements(any())) - .thenReturn(Flux.just(accountBatchResponseItemExtended)); + when(arrangementsIntegrationApi.postBatchUpsertArrangements(any())).thenReturn(Flux.just(accountBatchResponseItemExtended)); StepVerifier.create(arrangementService.upsertBatchArrangements(List.of(request))) .assertNext(response -> { Assertions.assertNotNull(response); Assertions.assertEquals(accountBatchResponseItemExtended.getArrangementId(), response.getArrangementId()); - }) - .verifyComplete(); + }).verifyComplete(); - verify(arrangementsApi).postBatchUpsertArrangements(any()); + verify(arrangementsIntegrationApi).postBatchUpsertArrangements(any()); } @Test void upsertBatchArrangements_Batch_Error() { - AccountArrangementItemPost request = buildAccountArrangementItemPost(); + PostArrangement request = buildPostArrangement(); - AccountBatchResponseItemExtended accountBatchResponseItemExtended = new AccountBatchResponseItemExtended() - .arrangementId("arr_id") - .resourceId("resource_id") - .status(BatchResponseStatusCode.HTTP_STATUS_BAD_REQUEST) - .addErrorsItem(new ErrorItem().message("Some error")) - .addErrorsItem(new ErrorItem().message("Some other error")); + BatchResponseItemExtended accountBatchResponseItemExtended = new BatchResponseItemExtended(); + accountBatchResponseItemExtended.setArrangementId("arr_id"); + accountBatchResponseItemExtended.setResourceId("resource_id"); + accountBatchResponseItemExtended.setStatus(BatchResponseStatusCode.HTTP_STATUS_BAD_REQUEST); + accountBatchResponseItemExtended.addErrorsItem(new ErrorItem().message("Some error")); + accountBatchResponseItemExtended.addErrorsItem(new ErrorItem().message("Some other error")); - when(arrangementsApi.postBatchUpsertArrangements(any())) - .thenReturn(Flux.just(accountBatchResponseItemExtended)); + when(arrangementsIntegrationApi.postBatchUpsertArrangements(any())).thenReturn(Flux.just(accountBatchResponseItemExtended)); StepVerifier.create(arrangementService.upsertBatchArrangements(List.of(request))) .consumeErrorWith(e -> { @@ -203,76 +193,40 @@ void upsertBatchArrangements_Batch_Error() { Assertions.assertTrue(errorMessage.startsWith("Batch arrangement update failed: 'resource_id'")); Assertions.assertTrue(errorMessage.contains("message: Some error")); Assertions.assertTrue(errorMessage.contains("message: Some other error")); - }) - .verify(); + }).verify(); - verify(arrangementsApi).postBatchUpsertArrangements(any()); + verify(arrangementsIntegrationApi).postBatchUpsertArrangements(any()); } @Test void upsertBatchArrangements_Failure() { - AccountArrangementItemPost request = buildAccountArrangementItemPost(); + PostArrangement request = buildPostArrangement(); - WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.BAD_REQUEST, - "Bad Request for upsert arrangement"); - when(arrangementsApi.postBatchUpsertArrangements(any())) - .thenReturn(Flux.error(webClientResponseException)); + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.BAD_REQUEST, "Bad Request for upsert arrangement"); + when(arrangementsIntegrationApi.postBatchUpsertArrangements(any())).thenReturn(Flux.error(webClientResponseException)); StepVerifier.create(arrangementService.upsertBatchArrangements(List.of(request))) .consumeErrorWith(e -> { - Assertions.assertTrue(e instanceof ArrangementUpdateException); + Assertions.assertInstanceOf(ArrangementUpdateException.class, e); Assertions.assertEquals("Batch arrangement update failed: " + List.of(request), e.getMessage()); Assertions.assertEquals(webClientResponseException.getMessage(), e.getCause().getMessage()); - }) - .verify(); + }).verify(); - verify(arrangementsApi).postBatchUpsertArrangements(any()); - } - - @Test - void updateUserPreferences() { - AccountUserPreferencesItemPut request = buildAccountUserPreferencesItemPut(); - - when(arrangementsApi.putUserPreferences(any())) - .thenReturn(Mono.empty()); - - // arrangementService.updateUserPreferences(request).block(); - - StepVerifier.create(arrangementService.updateUserPreferences(request)) - .verifyComplete(); - - verify(arrangementsApi).putUserPreferences(any()); - } - - @Test - void updateUserPreferences_NotFound() { - AccountUserPreferencesItemPut request = buildAccountUserPreferencesItemPut(); - - WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.NOT_FOUND, - "User Not Found"); - when(arrangementsApi.putUserPreferences(any())) - .thenReturn(Mono.error(webClientResponseException)); - - StepVerifier.create(arrangementService.updateUserPreferences(request)) - .verifyComplete(); - - verify(arrangementsApi).putUserPreferences(any()); + verify(arrangementsIntegrationApi).postBatchUpsertArrangements(any()); } @Test void getArrangement() { String internalId = "internal_id"; - AccountArrangementItem accountArrangementItem = new AccountArrangementItem().id("acct_arr_item_id"); - when(arrangementsApi.getArrangementById(internalId, false)) - .thenReturn(Mono.just(accountArrangementItem)); + ArrangementItem arrangementItem = new ArrangementItem().id("acct_arr_item_id"); + when(arrangementsApi.getArrangementById(internalId, false)).thenReturn(Mono.just(arrangementItem)); StepVerifier.create(arrangementService.getArrangement(internalId)) .assertNext(response -> { Assertions.assertNotNull(response); - Assertions.assertEquals(response.getId(), accountArrangementItem.getId()); - }) - .verifyComplete(); + Assertions.assertEquals(response.getId(), arrangementItem.getId()); + }).verifyComplete(); verify(arrangementsApi).getArrangementById(internalId, false); } @@ -281,13 +235,10 @@ void getArrangement() { void getArrangement_NotFound() { String internalId = "internal_id"; - WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.NOT_FOUND, - "Arrangement Not Found"); - when(arrangementsApi.getArrangementById(internalId, false)) - .thenReturn(Mono.error(webClientResponseException)); + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.NOT_FOUND, "Arrangement Not Found"); + when(arrangementsApi.getArrangementById(internalId, false)).thenReturn(Mono.error(webClientResponseException)); - StepVerifier.create(arrangementService.getArrangement(internalId)) - .verifyComplete(); + StepVerifier.create(arrangementService.getArrangement(internalId)).verifyComplete(); verify(arrangementsApi).getArrangementById(internalId, false); } @@ -296,203 +247,216 @@ void getArrangement_NotFound() { void getArrangementByExternalId() { String externalId = "external_id"; - AccountArrangementItem accountArrangementItem = new AccountArrangementItem().id("acct_arr_item_id"); - AccountArrangementItems accountArrangementItems = new AccountArrangementItems() - .addArrangementElementsItem(accountArrangementItem); - when(arrangementsApi.getArrangements(null, null, List.of(externalId))) - .thenReturn(Mono.just(accountArrangementItems)); + ArrangementsSearchesPostRequest arrangementsSearchesPostRequest = new ArrangementsSearchesPostRequest(); + arrangementsSearchesPostRequest.setExternalArrangementIds(Set.of(externalId)); + + ArrangementSearchesListResponse arrangementSearchesListResponse = new ArrangementSearchesListResponse(); + + ArrangementItem arrangementItem = new ArrangementItem().id("acct_arr_item_id"); + arrangementSearchesListResponse.setArrangementElements(List.of(arrangementItem)); + + when(arrangementsApi.postSearchArrangements(arrangementsSearchesPostRequest)).thenReturn(Mono.just(arrangementSearchesListResponse)); StepVerifier.create(arrangementService.getArrangementByExternalId(externalId)) .assertNext(response -> { Assertions.assertNotNull(response); - Assertions.assertEquals(response.getId(), accountArrangementItem.getId()); - }) - .verifyComplete(); + Assertions.assertEquals(response.getId(), arrangementItem.getId()); + }).verifyComplete(); - verify(arrangementsApi).getArrangements(null, null, List.of(externalId)); + verify(arrangementsApi).postSearchArrangements(arrangementsSearchesPostRequest); } @Test void getArrangementByExternalId_NotFound() { String externalId = "external_id"; - when(arrangementsApi.getArrangements(null, null, List.of(externalId))) - .thenReturn(Mono.empty()); + ArrangementsSearchesPostRequest arrangementsSearchesPostRequest = new ArrangementsSearchesPostRequest(); + arrangementsSearchesPostRequest.setExternalArrangementIds(Set.of(externalId)); + when(arrangementsApi.postSearchArrangements(arrangementsSearchesPostRequest)).thenReturn(Mono.empty()); - StepVerifier.create(arrangementService.getArrangementByExternalId(externalId)) - .verifyComplete(); + StepVerifier.create(arrangementService.getArrangementByExternalId(externalId)).verifyComplete(); - verify(arrangementsApi).getArrangements(null, null, List.of(externalId)); + verify(arrangementsApi).postSearchArrangements(arrangementsSearchesPostRequest); } @Test void getArrangementInternalId() { String externalId = "external_id"; - AccountInternalIdGetResponseBody accountInternalIdGetResponseBody = - new AccountInternalIdGetResponseBody().internalId("internal_id"); - when(arrangementsApi.getInternalId(externalId)) - .thenReturn(Mono.just(accountInternalIdGetResponseBody)); + ArrangementsSearchesPostRequest arrangementsSearchesPostRequest = new ArrangementsSearchesPostRequest(); + arrangementsSearchesPostRequest.setExternalArrangementIds(Set.of(externalId)); + + ArrangementItem arrangementItem = new ArrangementItem(); + arrangementItem.setId("internal_id"); + + ArrangementSearchesListResponse arrangementSearchesListResponse = new ArrangementSearchesListResponse(); + arrangementSearchesListResponse.setArrangementElements(List.of(arrangementItem)); + + when(arrangementsApi.postSearchArrangements(arrangementsSearchesPostRequest)).thenReturn(Mono.just(arrangementSearchesListResponse)); StepVerifier.create(arrangementService.getArrangementInternalId(externalId)) - .assertNext(response -> Assertions.assertEquals(response, accountInternalIdGetResponseBody.getInternalId())) + .assertNext(response -> Assertions.assertEquals(response, arrangementItem.getId())) .verifyComplete(); - verify(arrangementsApi).getInternalId(externalId); + verify(arrangementsApi).postSearchArrangements(arrangementsSearchesPostRequest); } @Test void getArrangementInternalId_NotFound() { String externalId = "external_id"; - WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.NOT_FOUND, - "Arrangement Not Found"); - when(arrangementsApi.getInternalId(externalId)) - .thenReturn(Mono.error(webClientResponseException)); + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.NOT_FOUND, "Arrangement Not Found"); - StepVerifier.create(arrangementService.getArrangementInternalId(externalId)) - .verifyComplete(); + ArrangementsSearchesPostRequest arrangementsSearchesPostRequest = new ArrangementsSearchesPostRequest(); + arrangementsSearchesPostRequest.setExternalArrangementIds(Set.of(externalId)); + + when(arrangementsApi.postSearchArrangements(arrangementsSearchesPostRequest)).thenReturn(Mono.error(webClientResponseException)); + + StepVerifier.create(arrangementService.getArrangementInternalId(externalId)).verifyComplete(); - verify(arrangementsApi).getInternalId(externalId); + verify(arrangementsApi).postSearchArrangements(arrangementsSearchesPostRequest); } @Test void getArrangementInternalId_Failure() { String externalId = "external_id"; - WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.BAD_REQUEST, - "Bad Request to get Internal Id"); - when(arrangementsApi.getInternalId(externalId)) - .thenReturn(Mono.error(webClientResponseException)); + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.BAD_REQUEST, "Bad Request to get Internal Id"); - StepVerifier.create(arrangementService.getArrangementInternalId(externalId)) - .verifyComplete(); + ArrangementsSearchesPostRequest arrangementsSearchesPostRequest = new ArrangementsSearchesPostRequest(); + arrangementsSearchesPostRequest.setExternalArrangementIds(Set.of(externalId)); + + when(arrangementsApi.postSearchArrangements(arrangementsSearchesPostRequest)).thenReturn(Mono.error(webClientResponseException)); + + StepVerifier.create(arrangementService.getArrangementInternalId(externalId)).verifyComplete(); - verify(arrangementsApi).getInternalId(externalId); + verify(arrangementsApi).postSearchArrangements(arrangementsSearchesPostRequest); } @Test void deleteArrangementByInternalId() { String arrangementInternalId = "arr_internal_id"; - AccountArrangementItem accountArrangementItem = new AccountArrangementItem() - .externalArrangementId("ext_arr_id"); - when(arrangementsApi.getArrangementById(arrangementInternalId, false)) - .thenReturn(Mono.just(accountArrangementItem)); + ArrangementItem arrangementItem = new ArrangementItem(); + arrangementItem.setExternalArrangementId("ext_arr_id"); - when(arrangementsApi.deleteExternalArrangementId(accountArrangementItem.getExternalArrangementId())) - .thenReturn(Mono.empty()); + ArrangementsDeleteItem arrangementsDeleteItem = new ArrangementsDeleteItem(); + arrangementsDeleteItem.setSelector(SelectorEnum.EXTERNAL_ID); + arrangementsDeleteItem.setValue("ext_arr_id"); + + Set arrangementsDeleteItemSet = Set.of(arrangementsDeleteItem); + ArrangementsDeleteResponseElement arrangementsDeleteResponseElement = new ArrangementsDeleteResponseElement(); + arrangementsDeleteResponseElement.setValue(arrangementItem.getExternalArrangementId()); + arrangementsDeleteResponseElement.setSelector(ArrangementsDeleteResponseElement.SelectorEnum.EXTERNAL_ID); + + when(arrangementsApi.getArrangementById(arrangementInternalId, false)).thenReturn(Mono.just(arrangementItem)); + when(arrangementsApi.postDelete(arrangementsDeleteItemSet)).thenReturn(Flux.just(arrangementsDeleteResponseElement)); StepVerifier.create(arrangementService.deleteArrangementByInternalId(arrangementInternalId)) - .expectNext(arrangementInternalId) - .verifyComplete(); + .expectNext(arrangementInternalId).verifyComplete(); verify(arrangementsApi).getArrangementById(arrangementInternalId, false); - verify(arrangementsApi).deleteExternalArrangementId(accountArrangementItem.getExternalArrangementId()); + verify(arrangementsApi).postDelete(arrangementsDeleteItemSet); } @Test void deleteArrangementByInternalId_GetArrangement_Failure() { String arrangementInternalId = "arr_internal_id"; - WebClientResponseException webClientResponseException = buildWebClientResponseException( - HttpStatus.INTERNAL_SERVER_ERROR, "Some error"); + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.INTERNAL_SERVER_ERROR, "Some error"); - when(arrangementsApi.getArrangementById(arrangementInternalId, false)) - .thenReturn(Mono.error(webClientResponseException)); + when(arrangementsApi.getArrangementById(arrangementInternalId, false)).thenReturn(Mono.error(webClientResponseException)); StepVerifier.create(arrangementService.deleteArrangementByInternalId(arrangementInternalId)) - .expectNext(arrangementInternalId) - .verifyComplete(); + .expectNext(arrangementInternalId).verifyComplete(); - verify(arrangementsApi, times(1)).getArrangementById(arrangementInternalId, false); - verify(arrangementsApi, times(0)).deleteExternalArrangementId(anyString()); + verify(arrangementsApi).getArrangementById(arrangementInternalId, false); + verify(arrangementsApi, times(0)).postDelete(anySet()); } @Test void deleteArrangementByInternalId_DeleteArrangement_Failure() { String arrangementInternalId = "arr_internal_id"; - AccountArrangementItem accountArrangementItem = new AccountArrangementItem() - .externalArrangementId("ext_arr_id"); - when(arrangementsApi.getArrangementById(arrangementInternalId, false)) - .thenReturn(Mono.just(accountArrangementItem)); + ArrangementItem accountArrangementItem = new ArrangementItem().externalArrangementId("ext_arr_id"); - WebClientResponseException webClientResponseException = buildWebClientResponseException( - HttpStatus.INTERNAL_SERVER_ERROR, "Some error"); - when(arrangementsApi.deleteExternalArrangementId(accountArrangementItem.getExternalArrangementId())) - .thenReturn(Mono.error(webClientResponseException)); + when(arrangementsApi.getArrangementById(arrangementInternalId, false)).thenReturn(Mono.just(accountArrangementItem)); + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.INTERNAL_SERVER_ERROR, "Some error"); + + ArrangementsDeleteItem arrangementsDeleteItem = new ArrangementsDeleteItem(); + arrangementsDeleteItem.setSelector(SelectorEnum.EXTERNAL_ID); + arrangementsDeleteItem.setValue(accountArrangementItem.getExternalArrangementId()); + + Set arrangementsDeleteItemSet = Set.of(arrangementsDeleteItem); + when(arrangementsApi.postDelete(arrangementsDeleteItemSet)).thenReturn(Flux.error(webClientResponseException)); StepVerifier.create(arrangementService.deleteArrangementByInternalId(arrangementInternalId)) .consumeErrorWith(e -> { - Assertions.assertTrue(e instanceof WebClientResponseException); + Assertions.assertInstanceOf(WebClientResponseException.class, e); Assertions.assertEquals("500 Some error", e.getMessage()); - }) - .verify(); + }).verify(); - verify(arrangementsApi, times(1)).getArrangementById(arrangementInternalId, false); - verify(arrangementsApi, times(1)).deleteExternalArrangementId(anyString()); + verify(arrangementsApi).getArrangementById(arrangementInternalId, false); + verify(arrangementsApi).postDelete(arrangementsDeleteItemSet); } @Test void addLegalEntitiesForArrangement() { String arrangementExternalId = "arr_ext_id"; Set legalEntitiesExternalIds = Set.of("leid_1", "leid_2"); - AccountExternalLegalEntityIds accountExternalLegalEntityIds = - new AccountExternalLegalEntityIds().ids(legalEntitiesExternalIds); - when(arrangementsApi.postArrangementLegalEntities(arrangementExternalId, accountExternalLegalEntityIds)) + ExternalLegalEntityIds externalLegalEntityIds = new ExternalLegalEntityIds(); + externalLegalEntityIds.ids(legalEntitiesExternalIds); + + when(arrangementsIntegrationApi.postArrangementLegalEntities(arrangementExternalId, externalLegalEntityIds)) .thenReturn(Mono.empty()); - StepVerifier.create(arrangementService.addLegalEntitiesForArrangement(arrangementExternalId, - new ArrayList<>(legalEntitiesExternalIds))) + StepVerifier.create(arrangementService.addLegalEntitiesForArrangement(arrangementExternalId, new ArrayList<>(legalEntitiesExternalIds))) .verifyComplete(); - verify(arrangementsApi).postArrangementLegalEntities(arrangementExternalId, accountExternalLegalEntityIds); + verify(arrangementsIntegrationApi).postArrangementLegalEntities(arrangementExternalId, externalLegalEntityIds); } @Test void addLegalEntitiesForArrangement_Failure() { String arrangementExternalId = "arr_ext_id"; Set legalEntitiesExternalIds = Set.of("leid_1", "leid_2"); - AccountExternalLegalEntityIds accountExternalLegalEntityIds = - new AccountExternalLegalEntityIds().ids(legalEntitiesExternalIds); - WebClientResponseException webClientResponseException = buildWebClientResponseException( - HttpStatus.INTERNAL_SERVER_ERROR, "Some error"); - when(arrangementsApi.postArrangementLegalEntities(arrangementExternalId, accountExternalLegalEntityIds)) + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.INTERNAL_SERVER_ERROR, "Some error"); + + ExternalLegalEntityIds externalLegalEntityIds = new ExternalLegalEntityIds(); + externalLegalEntityIds.ids(legalEntitiesExternalIds); + + when(arrangementsIntegrationApi.postArrangementLegalEntities(arrangementExternalId, externalLegalEntityIds)) .thenReturn(Mono.error(webClientResponseException)); StepVerifier.create(arrangementService.addLegalEntitiesForArrangement(arrangementExternalId, - new ArrayList<>(legalEntitiesExternalIds))) - .consumeErrorWith(e -> { - Assertions.assertTrue(e instanceof WebClientResponseException); - Assertions.assertEquals("500 Some error", e.getMessage()); - }) - .verify(); + new ArrayList<>(legalEntitiesExternalIds))).consumeErrorWith(e -> { + Assertions.assertInstanceOf(WebClientResponseException.class, e); + Assertions.assertEquals("500 Some error", e.getMessage()); + }).verify(); - verify(arrangementsApi).postArrangementLegalEntities(arrangementExternalId, accountExternalLegalEntityIds); + verify(arrangementsIntegrationApi).postArrangementLegalEntities(arrangementExternalId, externalLegalEntityIds); } @Test @Disabled void removeLegalEntityFromArrangement() { String arrangementExternalId = "arr_ext_id"; - List legalEntityExternalIds = List.of("leid_1", "leid_2"); + Set legalEntityExternalIds = Set.of("leid_1", "leid_2"); ApiClient apiClient = mock(ApiClient.class); - when(arrangementsApi.getApiClient()) - .thenReturn(apiClient); + when(arrangementsApi.getApiClient()).thenReturn(apiClient); + + ExternalLegalEntityIds externalLegalEntityIds = new ExternalLegalEntityIds(); + externalLegalEntityIds.setIds(legalEntityExternalIds); - verify(arrangementsApi).deleteArrangementLegalEntities(eq(arrangementExternalId), - argThat(accountExternalLegalEntityIds -> accountExternalLegalEntityIds.getIds() - .containsAll(legalEntityExternalIds))); + verify(arrangementsIntegrationApi).deleteArrangementLegalEntities(arrangementExternalId, externalLegalEntityIds); StepVerifier.create(arrangementService.removeLegalEntityFromArrangement(arrangementExternalId, - legalEntityExternalIds)) - .verifyComplete(); + legalEntityExternalIds.stream().toList())).verifyComplete(); - verify(arrangementsApi).getApiClient(); + verify(arrangementsIntegrationApi).getApiClient(); } @Test @@ -503,25 +467,21 @@ void removeLegalEntityFromArrangement_Failure() { ApiClient apiClient = mock(ApiClient.class); - when(arrangementsApi.getApiClient()) - .thenReturn(apiClient); + when(arrangementsApi.getApiClient()).thenReturn(apiClient); + + WebClientResponseException webClientResponseException = buildWebClientResponseException(HttpStatus.INTERNAL_SERVER_ERROR, "Some error"); - WebClientResponseException webClientResponseException = buildWebClientResponseException( - HttpStatus.INTERNAL_SERVER_ERROR, "Some error"); + ExternalLegalEntityIds externalLegalEntityIds = new ExternalLegalEntityIds(); + externalLegalEntityIds.setIds(legalEntityExternalIds); - verify(arrangementsApi).deleteArrangementLegalEntities(eq(arrangementExternalId), - argThat(accountExternalLegalEntityIds -> accountExternalLegalEntityIds.getIds() - .containsAll(legalEntityExternalIds))) + verify(arrangementsIntegrationApi).deleteArrangementLegalEntities(arrangementExternalId, externalLegalEntityIds) .thenReturn(Mono.error(webClientResponseException)); - StepVerifier.create( - arrangementService.removeLegalEntityFromArrangement(arrangementExternalId, - new ArrayList<>(legalEntityExternalIds))) + StepVerifier.create(arrangementService.removeLegalEntityFromArrangement(arrangementExternalId, new ArrayList<>(legalEntityExternalIds))) .consumeErrorWith(e -> { - Assertions.assertTrue(e instanceof WebClientResponseException); + Assertions.assertInstanceOf(WebClientResponseException.class, e); Assertions.assertEquals("500 Some error", e.getMessage()); - }) - .verify(); + }).verify(); verify(arrangementsApi).getApiClient(); } diff --git a/stream-product/product-ingestion-saga/src/main/java/com/backbase/stream/product/BatchProductIngestionSaga.java b/stream-product/product-ingestion-saga/src/main/java/com/backbase/stream/product/BatchProductIngestionSaga.java index 8b67ebab1..976e546ce 100644 --- a/stream-product/product-ingestion-saga/src/main/java/com/backbase/stream/product/BatchProductIngestionSaga.java +++ b/stream-product/product-ingestion-saga/src/main/java/com/backbase/stream/product/BatchProductIngestionSaga.java @@ -3,9 +3,9 @@ import static java.util.Comparator.comparing; import static java.util.Comparator.naturalOrder; import static java.util.Comparator.nullsFirst; +import static java.util.stream.Collectors.toMap; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPost; -import com.backbase.stream.legalentity.model.BaseProduct; +import com.backbase.dbs.arrangement.api.integration.v2.model.PostArrangement; import com.backbase.stream.legalentity.model.BaseProductGroup; import com.backbase.stream.legalentity.model.BatchProductGroup; import com.backbase.stream.legalentity.model.BusinessFunctionGroup; @@ -43,7 +43,6 @@ import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; -import org.springframework.web.reactive.function.client.WebClientResponseException; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -110,7 +109,6 @@ private Mono setupLoans(BatchProductGroupTask batchProduc BatchProductGroup data = batchProductGroupTask.getData(); List loans = Optional.ofNullable(data) .map(BatchProductGroup::getProductGroups).stream() - .filter(Objects::nonNull) .flatMap(Collection::stream) .map(BaseProductGroup::getLoans) .filter(Objects::nonNull) @@ -162,13 +160,13 @@ private static Predicate distinctByKeys(final Function... ke return t -> { final List keys = Arrays.stream(keyExtractors) .map(key -> key.apply(t)) - .collect(Collectors.toList()); + .toList(); return seen.putIfAbsent(keys, Boolean.TRUE) == null; }; } protected Mono upsertArrangementsBatch(BatchProductGroupTask batchProductGroupTask) { - List batchArrangements = new ArrayList<>(); + List batchArrangements = new ArrayList<>(); batchProductGroupTask.getData().getProductGroups().forEach(pg -> batchArrangements.addAll( Stream.of( StreamUtils.nullableCollectionToStream(pg.getCurrentAccounts()).map(productMapper::toPresentation), @@ -182,25 +180,24 @@ protected Mono upsertArrangementsBatch(BatchProductGroupT ) .flatMap(i -> i) .map(product -> ensureLegalEntityId(pg.getUsers(), product)) - .collect(Collectors.toList()) + .toList() )); // Insert without duplicates. // TODO: Revert this change when either OpenAPI generated methods can call super in equals // or if the product spec is modified to mitigate the issue - List itemsToUpsert = batchArrangements.stream() + List itemsToUpsert = batchArrangements.stream() .filter(distinctByKeys( - AccountArrangementItemPost::getExternalArrangementId, - AccountArrangementItemPost::getExternalLegalEntityIds, - AccountArrangementItemPost::getExternalProductId, - AccountArrangementItemPost::getExternalStateId, - AccountArrangementItemPost::getProductId, + PostArrangement::getId, + PostArrangement::getLegalEntityIds, + PostArrangement::getProductId, + PostArrangement::getStateId, /* AccountArrangementItemPost::getAlias,*/ - AccountArrangementItemPost::getAdditions - )).collect(Collectors.toList()); + PostArrangement::getAdditions + )).toList(); Set upsertedInternalIds = new HashSet<>(); return Flux.fromIterable(itemsToUpsert) - .sort(comparing(AccountArrangementItemPost::getExternalParentId, nullsFirst(naturalOrder()))) // Avoiding child to be created before parent + .sort(comparing(PostArrangement::getParentId, nullsFirst(naturalOrder()))) // Avoiding child to be created before parent .buffer(50) // hardcoded to match DBS limitation .concatMap(batch -> arrangementService.upsertBatchArrangements(batch) .doOnNext(r -> batchProductGroupTask.info(ARRANGEMENT, UPSERT_ARRANGEMENT, UPDATED, r.getResourceId(), r.getArrangementId(), "Updated Arrangements (in batch)")) @@ -208,7 +205,7 @@ protected Mono upsertArrangementsBatch(BatchProductGroupT ).map(batchResponses -> { // Update products with internal IDs. return batchProductGroupTask.getData().getProductGroups().stream() - .flatMap(pg -> StreamUtils.getAllProducts(pg)) + .flatMap(StreamUtils::getAllProducts) .map(product -> { batchResponses.forEach(result -> { if (result.getResourceId().equalsIgnoreCase(product.getExternalId())) { @@ -218,10 +215,7 @@ protected Mono upsertArrangementsBatch(BatchProductGroupT }); return product; }); - }) - .flatMap(baseProductStream -> Flux.fromStream(baseProductStream) - .filter(baseProduct -> !CollectionUtils.isEmpty(baseProduct.getUsersPreferences())) - .flatMap(this::updateUsersPreferences)) + }).flatMap(Flux::fromStream) .collectList() .thenReturn(batchProductGroupTask) .flatMap(task -> { @@ -241,27 +235,6 @@ protected Mono upsertArrangementsBatch(BatchProductGroupT }); } - protected Mono updateUsersPreferences(BaseProduct product) { - return Flux.fromIterable(product.getUsersPreferences()) - .map(productMapper::mapUserPreference) - .flatMap(userPreferencesItem -> - userService.getUserByExternalId(userPreferencesItem.getUserId()) - .flatMap(user -> arrangementService.updateUserPreferences( - userPreferencesItem - .userId(user.getInternalId()) - .arrangementId(product.getInternalId()))) - .onErrorResume(WebClientResponseException.NotFound.class, throwable -> { - log.info("User Id not found for: {}. Request:[{}] {} Response: {}", - userPreferencesItem.getUserId(), throwable.getRequest().getMethod(), - throwable.getRequest().getURI(), throwable.getResponseBodyAsString()); - return Mono.empty(); - }) - .thenReturn(userPreferencesItem) - ) - .collectList() - .thenReturn(product); - } - protected Mono setupProductGroupsBatch(BatchProductGroupTask task) { List productGroups = task.getData().getProductGroups(); return accessGroupService.getExistingDataGroups(task.getData().getServiceAgreement().getInternalId(), null) @@ -286,7 +259,6 @@ protected Mono setupProductGroupsBatch(BatchProductGroupT .flatMap(existingGroups -> accessGroupService.updateExistingDataGroupsBatch(task, existingGroups, productGroups)); } - protected Mono setupBusinessFunctionsAndPermissionsBatch(BatchProductGroupTask task) { List profileUsers = task.getData().getProductGroups().stream().flatMap(g -> g.getUsers().stream()).distinct().collect(Collectors.toList()); @@ -294,7 +266,7 @@ protected Mono setupBusinessFunctionsAndPermissionsBatch( .flatMap(functionGroups -> { Collection uniqueUsers = profileUsers.stream() .filter(jpu -> jpu.getUser().getExternalId() != null) - .collect(Collectors.toMap(jpu -> jpu.getUser().getExternalId(), u -> u, (u, id) -> u)).values(); + .collect(toMap(jpu -> jpu.getUser().getExternalId(), u -> u, (u, id) -> u)).values(); return Flux.fromIterable(uniqueUsers) .flatMap(user -> processUser(task, user)) .collectList() @@ -332,7 +304,7 @@ protected Mono> setupBusinessFunctions(BatchProductG .map(businessFunctionGroups -> { // remove duplicates return new ArrayList<>(businessFunctionGroups.stream() - .collect(Collectors.toMap(BusinessFunctionGroup::getName, p -> p, (p, q) -> p)).values()); + .collect(toMap(BusinessFunctionGroup::getName, p -> p, (p, q) -> p)).values()); }) .flatMap(businessFunctionGroups -> accessGroupService.setupFunctionGroups(streamTask, serviceAgreement, businessFunctionGroups)) .map(businessFunctionGroups -> { @@ -374,6 +346,6 @@ protected List getUsersGroupWithFunction(BatchProductGroup bat .map(JobProfileUser::getBusinessFunctionGroups) .flatMap(Collection::stream) .anyMatch(bfg -> bfg.getName().equals(functionGroup.getName())) - ).collect(Collectors.toList()); + ).toList(); } } diff --git a/stream-product/product-ingestion-saga/src/main/java/com/backbase/stream/product/ProductIngestionSaga.java b/stream-product/product-ingestion-saga/src/main/java/com/backbase/stream/product/ProductIngestionSaga.java index 5afcc90ee..c56115666 100644 --- a/stream-product/product-ingestion-saga/src/main/java/com/backbase/stream/product/ProductIngestionSaga.java +++ b/stream-product/product-ingestion-saga/src/main/java/com/backbase/stream/product/ProductIngestionSaga.java @@ -3,12 +3,13 @@ import static java.util.Comparator.comparing; import static java.util.Comparator.naturalOrder; import static java.util.Comparator.nullsFirst; +import static java.util.stream.Collectors.toMap; import static org.springframework.util.CollectionUtils.isEmpty; import com.backbase.dbs.accesscontrol.api.service.v3.model.FunctionGroupItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItem; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPost; -import com.backbase.dbs.arrangement.api.service.v2.model.AccountArrangementItemPut; +import com.backbase.dbs.arrangement.api.integration.v2.model.PostArrangement; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementItem; +import com.backbase.dbs.arrangement.api.service.v3.model.ArrangementPutItem; import com.backbase.stream.legalentity.model.BusinessFunctionGroup; import com.backbase.stream.legalentity.model.CreditCard; import com.backbase.stream.legalentity.model.CurrentAccount; @@ -129,7 +130,7 @@ private Mono validateProductGroup(ProductGroupTask streamTask) streamTask.warn(PRODUCT_GROUP, VALIDATE, REJECTED, name, null, "Product Group with Custom Data Group Items must have a Product Group Defined!"); return Mono.error(new StreamTaskException(streamTask, "Product Group with Custom Data Group Items must have a Product Group Defined!")); } - if (productGroup.getProductGroupType() == null && StreamUtils.getAllProducts(productGroup).count() > 0) { + if (productGroup.getProductGroupType() == null && StreamUtils.getAllProducts(productGroup).findAny().isPresent()) { streamTask.warn(PRODUCT_GROUP, VALIDATE, REJECTED, name, null, "Product Group: {} does not have type setup. As Product Group contains products setting type to ARRANGEMENTS"); productGroup.setProductGroupType(ProductGroup.ProductGroupTypeEnum.ARRANGEMENTS); } @@ -153,11 +154,8 @@ protected Mono> getBusinessFunctionGroups(JobProfile if (!isEmpty(jobProfileUser.getReferenceJobRoleNames())) { return accessGroupService.getFunctionGroupsForServiceAgreement(serviceAgreement.getInternalId()) .map(functionGroups -> { - Map idByFunctionGroupName = functionGroups - .stream() - .filter(fg -> Objects.nonNull(fg.getId())) - .collect(Collectors - .toMap(FunctionGroupItem::getName, Function.identity())); + Map idByFunctionGroupName = functionGroups.stream() + .collect(toMap(FunctionGroupItem::getName, Function.identity())); return jobProfileUser.getReferenceJobRoleNames().stream() .map(idByFunctionGroupName::get) .filter(Objects::nonNull) @@ -251,97 +249,92 @@ public Mono upsertArrangements(ProductGroupTask streamTask) { Flux productFlux = getProductFlux(productGroup); - Mono> currentAccountsRequests = upsertArrangements(streamTask, currentAccountFlux.map(productMapper::toPresentation)); - Mono> savingAccountsRequests = upsertArrangements(streamTask, savingsAccountFlux.map(productMapper::toPresentation)); - Mono> debitCardsRequests = upsertArrangements(streamTask, debitCardFlux.map(productMapper::toPresentation)); - Mono> creditCardsRequests = upsertArrangements(streamTask, creditCardFlux.map(productMapper::toPresentation)); - Mono> loansRequests = upsertArrangements(streamTask, loanFlux.map(productMapper::toPresentation)); - Mono> termDepositsRequests = upsertArrangements(streamTask, termDepositFlux.map(productMapper::toPresentation)); - Mono> investmentAccountsRequests = upsertArrangements(streamTask, investmentAccountFlux.map(productMapper::toPresentation)); - Mono> customProductsRequests = upsertArrangements(streamTask, productFlux.map(productMapper::toPresentation)); + Mono> currentAccountsRequests = upsertArrangements(streamTask, currentAccountFlux.map(productMapper::toPresentation)); + Mono> savingAccountsRequests = upsertArrangements(streamTask, savingsAccountFlux.map(productMapper::toPresentation)); + Mono> debitCardsRequests = upsertArrangements(streamTask, debitCardFlux.map(productMapper::toPresentation)); + Mono> creditCardsRequests = upsertArrangements(streamTask, creditCardFlux.map(productMapper::toPresentation)); + Mono> loansRequests = upsertArrangements(streamTask, loanFlux.map(productMapper::toPresentation)); + Mono> termDepositsRequests = upsertArrangements(streamTask, termDepositFlux.map(productMapper::toPresentation)); + Mono> investmentAccountsRequests = upsertArrangements(streamTask, investmentAccountFlux.map(productMapper::toPresentation)); + Mono> customProductsRequests = upsertArrangements(streamTask, productFlux.map(productMapper::toPresentation)); return Mono.just(productGroup) .zipWith(currentAccountsRequests, (actual, arrangements) -> { - List collect = arrangements.stream().map(productMapper::mapCurrentAccount) - .collect(Collectors.toList()); + List collect = arrangements.stream().map(productMapper::mapCurrentAccount).toList(); return actual.currentAccounts(collect); }) - .zipWith(savingAccountsRequests, (actual, arrangements) -> actual.savingAccounts(arrangements.stream().map(productMapper::mapSavingAccount).collect(Collectors.toList()))) - .zipWith(debitCardsRequests, (actual, arrangements) -> actual.debitCards(arrangements.stream().map(productMapper::mapDebitCard).collect(Collectors.toList()))) - .zipWith(creditCardsRequests, (actual, arrangements) -> actual.creditCards(arrangements.stream().map(productMapper::mapCreditCard).collect(Collectors.toList()))) - .zipWith(loansRequests, (actual, arrangements) -> actual.loans(arrangements.stream().map(productMapper::mapLoan).collect(Collectors.toList()))) - .zipWith(termDepositsRequests, (actual, arrangements) -> actual.termDeposits(arrangements.stream().map(productMapper::mapTermDeposit).collect(Collectors.toList()))) - .zipWith(investmentAccountsRequests, (actual, arrangements) -> actual.investmentAccounts(arrangements.stream().map(productMapper::mapInvestmentAccount).collect(Collectors.toList()))) - .zipWith(customProductsRequests, (actual, arrangements) -> actual.customProducts(arrangements.stream().map(productMapper::mapCustomProduct).collect(Collectors.toList()))) + .zipWith(savingAccountsRequests, (actual, arrangements) -> actual.savingAccounts(arrangements.stream().map(productMapper::mapSavingAccount).toList())) + .zipWith(debitCardsRequests, (actual, arrangements) -> actual.debitCards(arrangements.stream().map(productMapper::mapDebitCard).toList())) + .zipWith(creditCardsRequests, (actual, arrangements) -> actual.creditCards(arrangements.stream().map(productMapper::mapCreditCard).toList())) + .zipWith(loansRequests, (actual, arrangements) -> actual.loans(arrangements.stream().map(productMapper::mapLoan).toList())) + .zipWith(termDepositsRequests, (actual, arrangements) -> actual.termDeposits(arrangements.stream().map(productMapper::mapTermDeposit).toList())) + .zipWith(investmentAccountsRequests, (actual, arrangements) -> actual.investmentAccounts(arrangements.stream().map(productMapper::mapInvestmentAccount).toList())) + .zipWith(customProductsRequests, (actual, arrangements) -> actual.customProducts(arrangements.stream().map(productMapper::mapCustomProduct).toList())) .cast(ProductGroup.class) .map(streamTask::data); } - private Mono> upsertArrangements(ProductGroupTask streamTask, - Flux productFlux) { + private Mono> upsertArrangements(ProductGroupTask streamTask, Flux productFlux) { ProductGroup productGroup = streamTask.getData(); return productFlux .map(p -> ensureLegalEntityId(productGroup.getUsers(), p)) - .sort(comparing(AccountArrangementItemPost::getExternalParentId, nullsFirst(naturalOrder()))) // Avoiding child to be created before parent + .sort(comparing(PostArrangement::getParentId, nullsFirst(naturalOrder()))) // Avoiding child to be created before parent .flatMapSequential(arrangementItemPost -> upsertArrangement(streamTask, arrangementItemPost)) .collectList(); } /** - * Create a arrangementItemPost in DBS. If arrangementItemPost already exists, return existing arrangementItemPost + * Create a postArrangement in DBS. If postArrangement already exists, return existing postArrangement * - * @param arrangementItemPost Product to create + * @param postArrangement Product to create * @return Created or Existing Product */ - public Mono upsertArrangement(ProductGroupTask streamTask, AccountArrangementItemPost arrangementItemPost) { - streamTask.info(ARRANGEMENT, UPSERT_ARRANGEMENT, "", arrangementItemPost.getExternalArrangementId(), null, "Inserting or updating arrangement: %s", arrangementItemPost.getExternalArrangementId()); - log.info("Upsert Arrangement: {} in Product Group: {}", arrangementItemPost.getExternalArrangementId(), streamTask.getData().getName()); - Mono updateArrangement = arrangementService.getArrangementInternalId(arrangementItemPost.getExternalArrangementId()) - - .flatMap(internalId -> { - log.info("Arrangement already exists: {}", internalId); - streamTask.info(ARRANGEMENT, UPSERT_ARRANGEMENT, EXISTS, arrangementItemPost.getExternalArrangementId(), internalId, "Arrangement %s already exists", arrangementItemPost.getExternalArrangementId()); - AccountArrangementItemPut arrangemenItemBase = productMapper.toArrangementItemPut(arrangementItemPost); + public Mono upsertArrangement(ProductGroupTask streamTask, PostArrangement postArrangement) { + streamTask.info(ARRANGEMENT, UPSERT_ARRANGEMENT, "", postArrangement.getId(), null, "Inserting or updating arrangement: %s", postArrangement.getId()); + log.info("Upsert Arrangement: {} in Product Group: {}", postArrangement.getId(), streamTask.getData().getName()); + Mono updateArrangement = arrangementService.getArrangementInternalId(postArrangement.getId()) + .flatMap(internalIdList -> { + String internalIds = String.join(",", internalIdList); + log.info("Arrangement already exists: {}", internalIdList); + streamTask.info(ARRANGEMENT, UPSERT_ARRANGEMENT, EXISTS, postArrangement.getId(), internalIds, "Arrangement %s already exists", postArrangement.getId()); + ArrangementPutItem arrangemenItemBase = productMapper.toArrangementItemPut(postArrangement); return arrangementService.updateArrangement(arrangemenItemBase) .onErrorResume(ArrangementUpdateException.class, e -> { - streamTask.error(ARRANGEMENT, UPDATE_ARRANGEMENT, FAILED, arrangementItemPost.getExternalArrangementId(), internalId, e, e.getHttpResponse(), "Failed to update arrangement: %s", arrangementItemPost.getExternalArrangementId()); + streamTask.error(ARRANGEMENT, UPDATE_ARRANGEMENT, FAILED, postArrangement.getId(), internalIds, e, e.getHttpResponse(), "Failed to update arrangement: %s", postArrangement.getId()); return Mono.error(new StreamTaskException(streamTask, e.getCause(), e.getMessage() + " " + e.getCause().getMessage())); }) .map(actual -> { log.info("Updated arrangement: {}", actual.getExternalArrangementId()); - streamTask.info(ARRANGEMENT, UPSERT_ARRANGEMENT, UPDATED, arrangementItemPost.getExternalArrangementId(), internalId, "Updated Arrangement"); - AccountArrangementItem arrangementItem = productMapper.toArrangementItem(actual); - arrangementItem.setId(internalId); + streamTask.info(ARRANGEMENT, UPSERT_ARRANGEMENT, UPDATED, postArrangement.getId(), internalIdList, "Updated Arrangement"); + ArrangementItem arrangementItem = productMapper.toArrangementItem(actual); + arrangementItem.setId(internalIdList); return arrangementItem; }); }); - Mono createNewArrangement = createArrangement(arrangementItemPost) - .map(arrangementItem -> { - streamTask.info(ARRANGEMENT, "insert-arrangement", "created", arrangementItemPost.getExternalArrangementId(), arrangementItem.getId(), "Created Arrangement"); - log.info("Created arrangement: {} with internalId: {} ", arrangementItem.getExternalArrangementId(), arrangementItem.getId()); - return arrangementItem; - }) - .onErrorResume(ArrangementCreationException.class, e -> { - streamTask.error("ARRANGEMENT", "insert-arrangement", "failed", arrangementItemPost.getExternalArrangementId(), null, e, e.getHttpResponse(), "Failed to update arrangement: %s", arrangementItemPost.getExternalArrangementId()); - return Mono.error(new StreamTaskException(streamTask, e, "Failed to create arrangement")); - }); + + Mono createNewArrangement = createArrangement(postArrangement) + .map(arrangementItem -> { + streamTask.info(ARRANGEMENT, "insert-arrangement", CREATED, postArrangement.getId(), arrangementItem.getId(), "Created Arrangement"); + log.info("Created arrangement: {} with internalId: {} ", arrangementItem.getExternalArrangementId(), arrangementItem.getId()); + return arrangementItem; + }) + .onErrorResume(ArrangementCreationException.class, e -> { + streamTask.error(ARRANGEMENT, "insert-arrangement", FAILED, postArrangement.getId(), null, e, e.getHttpResponse(), "Failed to update arrangement: %s", postArrangement.getId()); + return Mono.error(new StreamTaskException(streamTask, e, "Failed to create arrangement")); + }); return updateArrangement.switchIfEmpty(createNewArrangement); } - private Mono createArrangement(AccountArrangementItemPost arrangementItemPost) { - - return arrangementService.createArrangement(arrangementItemPost) + private Mono createArrangement(PostArrangement postArrangement) { + return arrangementService.createArrangement(postArrangement) .doOnError(WebClientResponseException.class, throwable -> - log.error("Failed to create product: {}\n{}", arrangementItemPost.getExternalArrangementId(), throwable.getResponseBodyAsString())) + log.error("Failed to create product: {}\n{}", postArrangement.getId(), throwable.getResponseBodyAsString())) .map(arrangementAddedResponse -> { - - AccountArrangementItem arrangementItem = productMapper.toArrangementItem(arrangementItemPost); + ArrangementItem arrangementItem = productMapper.toArrangementItem(postArrangement); arrangementItem.setId(arrangementAddedResponse.getId()); - return arrangementItem; - }); } @@ -393,15 +386,15 @@ private Flux getCurrentAccountFlux(ProductGroup productGroup) { : Flux.fromIterable(productGroup.getCurrentAccounts()); } - protected AccountArrangementItemPost ensureLegalEntityId(List users, AccountArrangementItemPost product) { + protected PostArrangement ensureLegalEntityId(List users, PostArrangement product) { Set legalEntityExternalIds = users.stream() .map(jobProfileUser -> jobProfileUser.getLegalEntityReference().getExternalId()) .collect(Collectors.toSet()); // Make sure that we take into consideration Legal Entity Ids provided in Arrangement Item itself. - if (!isEmpty(product.getExternalLegalEntityIds())) { - legalEntityExternalIds.addAll(product.getExternalLegalEntityIds()); + if (!isEmpty(product.getLegalEntityIds())) { + legalEntityExternalIds.addAll(product.getLegalEntityIds()); } - product.setExternalLegalEntityIds(new HashSet<>(legalEntityExternalIds)); + product.setLegalEntityIds(new HashSet<>(legalEntityExternalIds)); return product; }