From b2465f0fea28b1b94217cc99c4b52327f3032151 Mon Sep 17 00:00:00 2001 From: pawana_backbase Date: Tue, 7 Apr 2026 13:50:27 +0530 Subject: [PATCH 1/2] WLNP-12183 : BSJ: Remove custom workaround to connect with Investment service --- CHANGELOG.md | 4 + .../configuration/IngestConfigProperties.java | 1 - .../InvestmentServiceConfiguration.java | 16 +- .../service/CustomIntegrationApiService.java | 179 ------------------ .../InvestmentModelPortfolioService.java | 5 +- .../InvestmentPortfolioAllocationService.java | 3 +- .../InvestmentModelPortfolioServiceTest.java | 49 +++-- ...estmentPortfolioAllocationServiceTest.java | 30 ++- 8 files changed, 47 insertions(+), 240 deletions(-) delete mode 100644 stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/CustomIntegrationApiService.java diff --git a/CHANGELOG.md b/CHANGELOG.md index eb02ccf1d..3f7b9977f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All notable changes to this project will be documented in this file. +## [9.13.0] +### Changed +- Remove custom workaround to connect with Investment service + ## [9.12.0] ### Added - Implement Portfolio Risk assessments data ingestion; diff --git a/stream-investment/investment-core/src/main/java/com/backbase/stream/configuration/IngestConfigProperties.java b/stream-investment/investment-core/src/main/java/com/backbase/stream/configuration/IngestConfigProperties.java index 5131db13f..cd294fc1e 100644 --- a/stream-investment/investment-core/src/main/java/com/backbase/stream/configuration/IngestConfigProperties.java +++ b/stream-investment/investment-core/src/main/java/com/backbase/stream/configuration/IngestConfigProperties.java @@ -2,7 +2,6 @@ import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; /** * Fine-grained configuration properties for {@code InvestmentPortfolioService}. diff --git a/stream-investment/investment-core/src/main/java/com/backbase/stream/configuration/InvestmentServiceConfiguration.java b/stream-investment/investment-core/src/main/java/com/backbase/stream/configuration/InvestmentServiceConfiguration.java index f5efeac1b..9b5d00d25 100644 --- a/stream-investment/investment-core/src/main/java/com/backbase/stream/configuration/InvestmentServiceConfiguration.java +++ b/stream-investment/investment-core/src/main/java/com/backbase/stream/configuration/InvestmentServiceConfiguration.java @@ -1,6 +1,5 @@ package com.backbase.stream.configuration; -import com.backbase.investment.api.service.ApiClient; import com.backbase.investment.api.service.v1.AllocationsApi; import com.backbase.investment.api.service.v1.AssetUniverseApi; import com.backbase.investment.api.service.v1.AsyncBulkGroupsApi; @@ -18,7 +17,6 @@ import com.backbase.stream.investment.saga.InvestmentContentSaga; import com.backbase.stream.investment.saga.InvestmentSaga; import com.backbase.stream.investment.service.AsyncTaskService; -import com.backbase.stream.investment.service.CustomIntegrationApiService; import com.backbase.stream.investment.service.InvestmentAssetPriceService; import com.backbase.stream.investment.service.InvestmentAssetUniverseService; import com.backbase.stream.investment.service.InvestmentClientService; @@ -57,11 +55,6 @@ public InvestmentClientService investmentClientService(ClientApi clientApi) { return new InvestmentClientService(clientApi); } - @Bean - public CustomIntegrationApiService customIntegrationApiService(ApiClient apiClient) { - return new CustomIntegrationApiService(apiClient); - } - @Bean public InvestmentPortfolioService investmentPortfolioService(PortfolioApi portfolioApi, InvestmentProductsApi investmentProductsApi, PaymentsApi paymentsApi, @@ -83,9 +76,8 @@ public AsyncTaskService asyncTaskService(AsyncBulkGroupsApi asyncBulkGroupsApi) } @Bean - public InvestmentModelPortfolioService investmentModelPortfolioService(FinancialAdviceApi financialAdviceApi, - CustomIntegrationApiService customIntegrationApiService) { - return new InvestmentModelPortfolioService(financialAdviceApi, customIntegrationApiService); + public InvestmentModelPortfolioService investmentModelPortfolioService(FinancialAdviceApi financialAdviceApi) { + return new InvestmentModelPortfolioService(financialAdviceApi); } @Bean @@ -101,9 +93,9 @@ public InvestmentIntradayAssetPriceService investmentIntradayAssetPriceService(A @Bean public InvestmentPortfolioAllocationService investmentPortfolioAllocationService(AllocationsApi allocationsApi, AssetUniverseApi assetUniverseApi, InvestmentApi investmentApi, - CustomIntegrationApiService customIntegrationApiService, IngestConfigProperties portfolioProperties) { + IngestConfigProperties portfolioProperties) { return new InvestmentPortfolioAllocationService(allocationsApi, assetUniverseApi, investmentApi, - customIntegrationApiService, portfolioProperties); + portfolioProperties); } @Bean diff --git a/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/CustomIntegrationApiService.java b/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/CustomIntegrationApiService.java deleted file mode 100644 index b334ae3f2..000000000 --- a/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/CustomIntegrationApiService.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.backbase.stream.investment.service; - -import com.backbase.investment.api.service.ApiClient; -import com.backbase.investment.api.service.v1.model.OASAllocationCreateRequest; -import com.backbase.investment.api.service.v1.model.OASModelPortfolioRequestDataRequest; -import com.backbase.investment.api.service.v1.model.OASModelPortfolioResponse; -import com.backbase.investment.api.service.v1.model.OASPortfolioAllocation; -import java.io.File; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.io.FileSystemResource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.reactive.function.client.WebClientResponseException; -import reactor.core.publisher.Mono; - -@Deprecated(forRemoval = true, since = "8.6.0") -@Slf4j -@RequiredArgsConstructor -public class CustomIntegrationApiService { - - private final ApiClient apiClient; - - public Mono patchModelPortfolioRequestCreation(String uuid, List expand, - String fields, String omit, OASModelPortfolioRequestDataRequest data, File image) - throws WebClientResponseException { - // verify the required parameter 'uuid' is set - if (uuid == null) { - throw new WebClientResponseException( - "Missing the required parameter 'uuid' when calling patchModelPortfolio", - HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); - } - // create path and map variables - final Map pathParams = new HashMap(); - - pathParams.put("uuid", uuid); - - final MultiValueMap queryParams = new LinkedMultiValueMap(); - final HttpHeaders headerParams = new HttpHeaders(); - final MultiValueMap cookieParams = new LinkedMultiValueMap(); - final MultiValueMap formParams = new LinkedMultiValueMap(); - - queryParams.putAll( - apiClient.parameterToMultiValueMap(ApiClient.CollectionFormat.valueOf("multi".toUpperCase(Locale.ROOT)), - "expand", expand)); - queryParams.putAll(apiClient.parameterToMultiValueMap(null, "fields", fields)); - queryParams.putAll(apiClient.parameterToMultiValueMap(null, "omit", omit)); - - if (data != null) { - formParams.add("data", data); - } - if (image != null) { - formParams.add("image", new FileSystemResource(image)); - } - - final String[] localVarAccepts = { - "application/json" - }; - final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); - final String[] localVarContentTypes = { - "application/json" - }; - final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); - - String[] localVarAuthNames = new String[]{}; - - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() { - }; - return apiClient.invokeAPI("/integration-api/v2/advice-engines/model-portfolio/model_portfolios/{uuid}/", - HttpMethod.PATCH, pathParams, queryParams, data, headerParams, cookieParams, formParams, localVarAccept, - localVarContentType, localVarAuthNames, localVarReturnType) - .bodyToMono(localVarReturnType); - } - - public Mono createModelPortfolioRequestCreation( - List expand, String fields, String omit, OASModelPortfolioRequestDataRequest data, File image) - throws WebClientResponseException { - // create path and map variables - final Map pathParams = new HashMap(); - - final MultiValueMap queryParams = new LinkedMultiValueMap(); - final HttpHeaders headerParams = new HttpHeaders(); - final MultiValueMap cookieParams = new LinkedMultiValueMap(); - final MultiValueMap formParams = new LinkedMultiValueMap(); - - queryParams.putAll( - apiClient.parameterToMultiValueMap(ApiClient.CollectionFormat.valueOf("multi".toUpperCase(Locale.ROOT)), - "expand", expand)); - queryParams.putAll(apiClient.parameterToMultiValueMap(null, "fields", fields)); - queryParams.putAll(apiClient.parameterToMultiValueMap(null, "omit", omit)); - - if (data != null) { - formParams.add("data", data); - } - if (image != null) { - formParams.add("image", new FileSystemResource(image)); - } - - final String[] localVarAccepts = { - "application/json" - }; - final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); - final String[] localVarContentTypes = { - "application/json" - }; - final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); - - String[] localVarAuthNames = new String[]{}; - - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() { - }; - return apiClient.invokeAPI("/integration-api/v2/advice-engines/model-portfolio/model_portfolios/", - HttpMethod.POST, - pathParams, queryParams, data, headerParams, cookieParams, formParams, localVarAccept, - localVarContentType, localVarAuthNames, localVarReturnType) - .bodyToMono(localVarReturnType); - } - - public Mono createPortfolioAllocation(String portfolioUuid, - OASAllocationCreateRequest oaSAllocationCreateRequest, List expand, String fields, String omit) - throws WebClientResponseException { - Object postBody = oaSAllocationCreateRequest; - // verify the required parameter 'portfolioUuid' is set - if (portfolioUuid == null) { - throw new WebClientResponseException( - "Missing the required parameter 'portfolioUuid' when calling createPortfolioAllocation", - HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); - } - // verify the required parameter 'oaSAllocationCreateRequest' is set - if (oaSAllocationCreateRequest == null) { - throw new WebClientResponseException( - "Missing the required parameter 'oaSAllocationCreateRequest' when calling createPortfolioAllocation", - HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); - } - // create path and map variables - final Map pathParams = new HashMap(); - - pathParams.put("portfolio_uuid", portfolioUuid); - - final MultiValueMap queryParams = new LinkedMultiValueMap(); - final HttpHeaders headerParams = new HttpHeaders(); - final MultiValueMap cookieParams = new LinkedMultiValueMap(); - final MultiValueMap formParams = new LinkedMultiValueMap(); - - queryParams.putAll( - apiClient.parameterToMultiValueMap(ApiClient.CollectionFormat.valueOf("multi".toUpperCase(Locale.ROOT)), - "expand", expand)); - queryParams.putAll(apiClient.parameterToMultiValueMap(null, "fields", fields)); - queryParams.putAll(apiClient.parameterToMultiValueMap(null, "omit", omit)); - - final String[] localVarAccepts = { - "application/json" - }; - final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); - final String[] localVarContentTypes = { - "application/json", "application/x-www-form-urlencoded", "multipart/form-data" - }; - final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); - - String[] localVarAuthNames = new String[]{}; - - ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference() { - }; - return apiClient.invokeAPI("/integration-api/v2/portfolios/{portfolio_uuid}/allocations/", HttpMethod.POST, - pathParams, queryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, - localVarContentType, localVarAuthNames, localVarReturnType) - .bodyToMono(localVarReturnType); - } - -} diff --git a/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/InvestmentModelPortfolioService.java b/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/InvestmentModelPortfolioService.java index 162bc59f5..4843852d5 100644 --- a/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/InvestmentModelPortfolioService.java +++ b/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/InvestmentModelPortfolioService.java @@ -42,7 +42,6 @@ public class InvestmentModelPortfolioService { private final FinancialAdviceApi financialAdviceApi; - private final CustomIntegrationApiService customIntegrationApiService; public Flux upsertModels(InvestmentData investmentData) { return Flux.fromIterable(Objects.requireNonNullElse(investmentData.getModelPortfolios(), List.of())) @@ -153,7 +152,7 @@ private Mono createNewModelPortfolio( log.info("Creating new model portfolio: name={}, riskLevel={}", modelPortfolio.getName(), modelPortfolio.getRiskLevel()); - return customIntegrationApiService.createModelPortfolioRequestCreation(null, null, null, + return financialAdviceApi.createModelPortfolio(null, null, null, modelPortfolio, null) .doOnSuccess(created -> log.info( "Successfully created model portfolio: uuid={}, name={}, riskLevel={}", @@ -168,7 +167,7 @@ private Mono patchModelPortfolio(UUID uuid, log.info("Patch model portfolio: name={}, riskLevel={}", modelPortfolio.getName(), modelPortfolio.getRiskLevel()); log.debug("Patch model portfolio: uuid={}, object={}", uuid, modelPortfolio); - return customIntegrationApiService.patchModelPortfolioRequestCreation(uuid.toString(), + return financialAdviceApi.patchModelPortfolio(uuid.toString(), null, null, null, modelPortfolio, null) .doOnSuccess(created -> log.info( "Successfully patched model portfolio: uuid={}, name={}, riskLevel={}", diff --git a/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/InvestmentPortfolioAllocationService.java b/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/InvestmentPortfolioAllocationService.java index c4744e712..f16957325 100644 --- a/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/InvestmentPortfolioAllocationService.java +++ b/stream-investment/investment-core/src/main/java/com/backbase/stream/investment/service/InvestmentPortfolioAllocationService.java @@ -76,7 +76,6 @@ public class InvestmentPortfolioAllocationService { private final AllocationsApi allocationsApi; private final AssetUniverseApi assetUniverseApi; private final InvestmentApi investmentApi; - private final CustomIntegrationApiService customIntegrationApiService; private final IngestConfigProperties ingestProperties; public Mono removeAllocations(PortfolioList portfolio) { @@ -156,7 +155,7 @@ private Mono> generateAllocations( private Mono> upsertAllocations(String portfolioId, List allocations) { return Flux.fromIterable(allocations) - .flatMap(a -> customIntegrationApiService.createPortfolioAllocation(portfolioId, a, null, null, null), + .flatMap(a -> allocationsApi.createPortfolioAllocation(portfolioId, a, null, null, null), ingestProperties.getAllocation().getAllocationConcurrency()) .collectList().doOnSuccess( diff --git a/stream-investment/investment-core/src/test/java/com/backbase/stream/investment/service/InvestmentModelPortfolioServiceTest.java b/stream-investment/investment-core/src/test/java/com/backbase/stream/investment/service/InvestmentModelPortfolioServiceTest.java index fdf8fe477..caaa9a9c4 100644 --- a/stream-investment/investment-core/src/test/java/com/backbase/stream/investment/service/InvestmentModelPortfolioServiceTest.java +++ b/stream-investment/investment-core/src/test/java/com/backbase/stream/investment/service/InvestmentModelPortfolioServiceTest.java @@ -52,19 +52,14 @@ * *

Mocked dependencies: *

    - *
  • {@link FinancialAdviceApi} – list model portfolios
  • - *
  • {@link CustomIntegrationApiService} – create / patch model portfolios
  • + *
  • {@link FinancialAdviceApi} – list / create / patch model portfolios
  • *
*/ -@SuppressWarnings({"deprecation", "removal"}) class InvestmentModelPortfolioServiceTest { @Mock private FinancialAdviceApi financialAdviceApi; - @Mock - private CustomIntegrationApiService customIntegrationApiService; - private InvestmentModelPortfolioService service; private AutoCloseable mocks; @@ -75,7 +70,7 @@ class InvestmentModelPortfolioServiceTest { @BeforeEach void setUp() { mocks = MockitoAnnotations.openMocks(this); - service = new InvestmentModelPortfolioService(financialAdviceApi, customIntegrationApiService); + service = new InvestmentModelPortfolioService(financialAdviceApi); } /** @@ -117,7 +112,7 @@ void upsertModels_nullModelPortfolios_emitsNothing() { verify(financialAdviceApi, never()).listModelPortfolio( any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); - verify(customIntegrationApiService, never()).createModelPortfolioRequestCreation( + verify(financialAdviceApi, never()).createModelPortfolio( any(), any(), any(), any(), any()); } @@ -159,7 +154,7 @@ void upsertModels_singlePortfolio_noExisting_createsAndSetsUuid() { stubListReturnsEmpty("Conservative", 3); OASModelPortfolioResponse created = buildResponse(expectedUuid, "Conservative", 3); - when(customIntegrationApiService.createModelPortfolioRequestCreation( + when(financialAdviceApi.createModelPortfolio( isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.just(created)); @@ -192,7 +187,7 @@ void upsertModels_singlePortfolio_existingFound_patches() { stubListReturnsOne("Balanced", 5, existing); OASModelPortfolioResponse patched = buildResponse(existingUuid, "Balanced", 5); - when(customIntegrationApiService.patchModelPortfolioRequestCreation( + when(financialAdviceApi.patchModelPortfolio( eq(existingUuid.toString()), isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.just(patched)); @@ -202,7 +197,7 @@ void upsertModels_singlePortfolio_existingFound_patches() { .assertNext(response -> assertThat(response.getUuid()).isEqualTo(existingUuid)) .verifyComplete(); - verify(customIntegrationApiService, never()).createModelPortfolioRequestCreation( + verify(financialAdviceApi, never()).createModelPortfolio( any(), any(), any(), any(), any()); } @@ -226,7 +221,7 @@ void upsertModels_multiplePortfolios_processesAll() { stubListReturnsEmpty("Conservative", 3); stubListReturnsEmpty("Aggressive", 8); - when(customIntegrationApiService.createModelPortfolioRequestCreation( + when(financialAdviceApi.createModelPortfolio( isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn( Mono.just(buildResponse(uuid1, "Conservative", 3)), @@ -256,7 +251,7 @@ void upsertModels_createFails_propagatesError() { .build(); stubListReturnsEmpty("Conservative", 3); - when(customIntegrationApiService.createModelPortfolioRequestCreation( + when(financialAdviceApi.createModelPortfolio( isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.error(new RuntimeException("create failed"))); @@ -292,7 +287,7 @@ void upsertModels_allocationMapping_correctlyMapsFields() { ArgumentCaptor requestCaptor = ArgumentCaptor.forClass(OASModelPortfolioRequestDataRequest.class); - when(customIntegrationApiService.createModelPortfolioRequestCreation( + when(financialAdviceApi.createModelPortfolio( isNull(), isNull(), isNull(), requestCaptor.capture(), isNull())) .thenReturn(Mono.just(buildResponse(expectedUuid, "Growth", 7))); @@ -341,7 +336,7 @@ void listExisting_emptyResults_createsNew() { .build(); stubListReturnsEmpty("Conservative", 2); - when(customIntegrationApiService.createModelPortfolioRequestCreation( + when(financialAdviceApi.createModelPortfolio( isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.just(buildResponse(expectedUuid, "Conservative", 2))); @@ -368,7 +363,7 @@ void listExisting_oneResult_patchesFirstResult() { OASModelPortfolioResponse existing = buildResponse(existingUuid, "Moderate", 5); stubListReturnsOne("Moderate", 5, existing); OASModelPortfolioResponse patched = buildResponse(existingUuid, "Moderate", 5); - when(customIntegrationApiService.patchModelPortfolioRequestCreation( + when(financialAdviceApi.patchModelPortfolio( eq(existingUuid.toString()), isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.just(patched)); @@ -378,7 +373,7 @@ void listExisting_oneResult_patchesFirstResult() { .assertNext(r -> assertThat(r.getUuid()).isEqualTo(existingUuid)) .verifyComplete(); - verify(customIntegrationApiService, never()).createModelPortfolioRequestCreation( + verify(financialAdviceApi, never()).createModelPortfolio( any(), any(), any(), any(), any()); } @@ -409,7 +404,7 @@ void listExisting_multipleResults_patchesFirstResult() { .thenReturn(Mono.just(page)); OASModelPortfolioResponse patched = buildResponse(firstUuid, "Balanced", 6); - when(customIntegrationApiService.patchModelPortfolioRequestCreation( + when(financialAdviceApi.patchModelPortfolio( eq(firstUuid.toString()), isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.just(patched)); @@ -419,7 +414,7 @@ void listExisting_multipleResults_patchesFirstResult() { .assertNext(r -> assertThat(r.getUuid()).isEqualTo(firstUuid)) .verifyComplete(); - verify(customIntegrationApiService, never()).createModelPortfolioRequestCreation( + verify(financialAdviceApi, never()).createModelPortfolio( any(), any(), any(), any(), any()); } @@ -476,7 +471,7 @@ void createNew_success_returnsCreatedResponse() { stubListReturnsEmpty("Income", 2); OASModelPortfolioResponse created = buildResponse(newUuid, "Income", 2); - when(customIntegrationApiService.createModelPortfolioRequestCreation( + when(financialAdviceApi.createModelPortfolio( isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.just(created)); @@ -506,7 +501,7 @@ void createNew_webClientResponseException_propagatesError() { stubListReturnsEmpty("Income", 2); WebClientResponseException ex = WebClientResponseException.create( HttpStatus.BAD_REQUEST.value(), "Bad Request", null, null, null); - when(customIntegrationApiService.createModelPortfolioRequestCreation( + when(financialAdviceApi.createModelPortfolio( isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.error(ex)); @@ -530,7 +525,7 @@ void createNew_genericException_propagatesError() { .build(); stubListReturnsEmpty("Income", 2); - when(customIntegrationApiService.createModelPortfolioRequestCreation( + when(financialAdviceApi.createModelPortfolio( isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.error(new IllegalStateException("unexpected"))); @@ -570,7 +565,7 @@ void patch_success_returnsPatchedResponse() { OASModelPortfolioResponse existing = buildResponse(existingUuid, "Dynamic", 9); stubListReturnsOne("Dynamic", 9, existing); OASModelPortfolioResponse patched = buildResponse(existingUuid, "Dynamic", 9); - when(customIntegrationApiService.patchModelPortfolioRequestCreation( + when(financialAdviceApi.patchModelPortfolio( eq(existingUuid.toString()), isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.just(patched)); @@ -584,7 +579,7 @@ void patch_success_returnsPatchedResponse() { }) .verifyComplete(); - verify(customIntegrationApiService, never()).createModelPortfolioRequestCreation( + verify(financialAdviceApi, never()).createModelPortfolio( any(), any(), any(), any(), any()); } @@ -606,7 +601,7 @@ void patch_usesCorrectUuidFromExistingPortfolio() { ArgumentCaptor uuidCaptor = ArgumentCaptor.forClass(String.class); OASModelPortfolioResponse patched = buildResponse(existingUuid, "Stable", 4); - when(customIntegrationApiService.patchModelPortfolioRequestCreation( + when(financialAdviceApi.patchModelPortfolio( uuidCaptor.capture(), isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.just(patched)); @@ -637,7 +632,7 @@ void patch_webClientResponseException_propagatesError() { stubListReturnsOne("Dynamic", 9, existing); WebClientResponseException ex = WebClientResponseException.create( HttpStatus.NOT_FOUND.value(), "Not Found", null, null, null); - when(customIntegrationApiService.patchModelPortfolioRequestCreation( + when(financialAdviceApi.patchModelPortfolio( eq(existingUuid.toString()), isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.error(ex)); @@ -664,7 +659,7 @@ void patch_genericException_propagatesError() { OASModelPortfolioResponse existing = buildResponse(existingUuid, "Dynamic", 9); stubListReturnsOne("Dynamic", 9, existing); - when(customIntegrationApiService.patchModelPortfolioRequestCreation( + when(financialAdviceApi.patchModelPortfolio( eq(existingUuid.toString()), isNull(), isNull(), isNull(), any(OASModelPortfolioRequestDataRequest.class), isNull())) .thenReturn(Mono.error(new RuntimeException("patch failed"))); diff --git a/stream-investment/investment-core/src/test/java/com/backbase/stream/investment/service/InvestmentPortfolioAllocationServiceTest.java b/stream-investment/investment-core/src/test/java/com/backbase/stream/investment/service/InvestmentPortfolioAllocationServiceTest.java index 5013ce8fa..4d5fa639d 100644 --- a/stream-investment/investment-core/src/test/java/com/backbase/stream/investment/service/InvestmentPortfolioAllocationServiceTest.java +++ b/stream-investment/investment-core/src/test/java/com/backbase/stream/investment/service/InvestmentPortfolioAllocationServiceTest.java @@ -67,7 +67,6 @@ class InvestmentPortfolioAllocationServiceTest { private AllocationsApi allocationsApi; private AssetUniverseApi assetUniverseApi; private InvestmentApi investmentApi; - private CustomIntegrationApiService customIntegrationApiService; private InvestmentPortfolioAllocationService service; private IngestConfigProperties ingestProperties; @@ -76,10 +75,9 @@ void setUp() { allocationsApi = mock(AllocationsApi.class); assetUniverseApi = mock(AssetUniverseApi.class); investmentApi = mock(InvestmentApi.class); - customIntegrationApiService = mock(CustomIntegrationApiService.class); ingestProperties = new IngestConfigProperties(); service = new InvestmentPortfolioAllocationService( - allocationsApi, assetUniverseApi, investmentApi, customIntegrationApiService, ingestProperties); + allocationsApi, assetUniverseApi, investmentApi, ingestProperties); } // ========================================================================= @@ -220,7 +218,7 @@ void createDepositAllocation_emptyPositionsFound_returnsDepositWithoutUpsert() { .expectNextMatches(d -> d == deposit) .verifyComplete(); - verify(customIntegrationApiService, never()) + verify(allocationsApi, never()) .createPortfolioAllocation(any(), any(), any(), any(), any()); } @@ -243,7 +241,7 @@ void createDepositAllocation_allPositionsNonEmpty_createsCashAllocationAndReturn .thenReturn(Mono.just(page)); OASPortfolioAllocation created = mock(OASPortfolioAllocation.class); - when(customIntegrationApiService.createPortfolioAllocation( + when(allocationsApi.createPortfolioAllocation( eq(portfolioUuid.toString()), any(OASAllocationCreateRequest.class), isNull(), isNull(), isNull())) .thenReturn(Mono.just(created)); @@ -252,7 +250,7 @@ void createDepositAllocation_allPositionsNonEmpty_createsCashAllocationAndReturn .expectNextMatches(d -> d == deposit) .verifyComplete(); - verify(customIntegrationApiService) + verify(allocationsApi) .createPortfolioAllocation(eq(portfolioUuid.toString()), any(OASAllocationCreateRequest.class), isNull(), isNull(), isNull()); } @@ -273,7 +271,7 @@ void createDepositAllocation_noAllocations_createsCashAllocationAndReturnsDeposi .thenReturn(Mono.just(emptyPage)); OASPortfolioAllocation created = mock(OASPortfolioAllocation.class); - when(customIntegrationApiService.createPortfolioAllocation( + when(allocationsApi.createPortfolioAllocation( eq(portfolioUuid.toString()), any(OASAllocationCreateRequest.class), isNull(), isNull(), isNull())) .thenReturn(Mono.just(created)); @@ -282,7 +280,7 @@ void createDepositAllocation_noAllocations_createsCashAllocationAndReturnsDeposi .expectNextMatches(d -> d == deposit) .verifyComplete(); - verify(customIntegrationApiService) + verify(allocationsApi) .createPortfolioAllocation(eq(portfolioUuid.toString()), any(OASAllocationCreateRequest.class), isNull(), isNull(), isNull()); } @@ -305,7 +303,7 @@ void createDepositAllocation_upsertFails_errorSwallowed_returnsEmpty() { eq(completedAt.minusDays(4)), eq(completedAt.plusDays(5)))) .thenReturn(Mono.just(page)); - when(customIntegrationApiService.createPortfolioAllocation( + when(allocationsApi.createPortfolioAllocation( eq(portfolioUuid.toString()), any(OASAllocationCreateRequest.class), isNull(), isNull(), isNull())) .thenReturn(Mono.error(new RuntimeException("downstream failure"))); @@ -331,7 +329,7 @@ void createDepositAllocation_listFails_errorSwallowed_returnsEmpty() { StepVerifier.create(service.createDepositAllocation(deposit)) .verifyComplete(); - verify(customIntegrationApiService, never()) + verify(allocationsApi, never()) .createPortfolioAllocation(any(), any(), any(), any(), any()); } @@ -358,7 +356,7 @@ void createDepositAllocation_nullCompletedAt_usesTodayAsValuationDate() { .thenReturn(Mono.just(page)); OASPortfolioAllocation created = mock(OASPortfolioAllocation.class); - when(customIntegrationApiService.createPortfolioAllocation( + when(allocationsApi.createPortfolioAllocation( eq(portfolioUuid.toString()), any(OASAllocationCreateRequest.class), isNull(), isNull(), isNull())) .thenReturn(Mono.just(created)); @@ -463,7 +461,7 @@ void generateAllocations_noExistingAllocations_createsNewAllocations() { .thenReturn(Mono.just(mock(OASOrder.class))); OASPortfolioAllocation createdAlloc = mock(OASPortfolioAllocation.class); - when(customIntegrationApiService.createPortfolioAllocation( + when(allocationsApi.createPortfolioAllocation( eq(portfolioUuid.toString()), any(OASAllocationCreateRequest.class), isNull(), isNull(), isNull())) .thenReturn(Mono.just(createdAlloc)); @@ -476,7 +474,7 @@ void generateAllocations_noExistingAllocations_createsNewAllocations() { .expectNextMatches(result -> !result.isEmpty()) .verifyComplete(); - verify(customIntegrationApiService, atLeastOnce()) + verify(allocationsApi, atLeastOnce()) .createPortfolioAllocation(eq(portfolioUuid.toString()), any(), isNull(), isNull(), isNull()); } @@ -534,7 +532,7 @@ void generateAllocations_lastValuationIsToday_noPendingDays_returnsEmptyList() { .expectNextMatches(List::isEmpty) .verifyComplete(); - verify(customIntegrationApiService, never()) + verify(allocationsApi, never()) .createPortfolioAllocation(any(), any(), any(), any(), any()); } @@ -596,7 +594,7 @@ void generateAllocations_noMatchingPortfolioProduct_fallsBackToDefaultModel() { .thenReturn(Mono.just(mock(OASOrder.class))); OASPortfolioAllocation createdAlloc = mock(OASPortfolioAllocation.class); - when(customIntegrationApiService.createPortfolioAllocation( + when(allocationsApi.createPortfolioAllocation( eq(portfolioUuid.toString()), any(OASAllocationCreateRequest.class), isNull(), isNull(), isNull())) .thenReturn(Mono.just(createdAlloc)); @@ -609,7 +607,7 @@ void generateAllocations_noMatchingPortfolioProduct_fallsBackToDefaultModel() { .expectNextMatches(result -> !result.isEmpty()) .verifyComplete(); - verify(customIntegrationApiService, atLeastOnce()) + verify(allocationsApi, atLeastOnce()) .createPortfolioAllocation(eq(portfolioUuid.toString()), any(), isNull(), isNull(), isNull()); } } From c0e8a5aece955ecc8f7d2d454fac78959432468c Mon Sep 17 00:00:00 2001 From: pawana_backbase Date: Tue, 7 Apr 2026 17:34:09 +0530 Subject: [PATCH 2/2] code coverage --- .../InvestmentServiceConfigurationTest.java | 216 ++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 stream-investment/investment-core/src/test/java/com/backbase/stream/configuration/InvestmentServiceConfigurationTest.java diff --git a/stream-investment/investment-core/src/test/java/com/backbase/stream/configuration/InvestmentServiceConfigurationTest.java b/stream-investment/investment-core/src/test/java/com/backbase/stream/configuration/InvestmentServiceConfigurationTest.java new file mode 100644 index 000000000..4636f4fcb --- /dev/null +++ b/stream-investment/investment-core/src/test/java/com/backbase/stream/configuration/InvestmentServiceConfigurationTest.java @@ -0,0 +1,216 @@ +package com.backbase.stream.configuration; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import com.backbase.investment.api.service.v1.AllocationsApi; +import com.backbase.investment.api.service.v1.AssetUniverseApi; +import com.backbase.investment.api.service.v1.AsyncBulkGroupsApi; +import com.backbase.investment.api.service.v1.ClientApi; +import com.backbase.investment.api.service.v1.CurrencyApi; +import com.backbase.investment.api.service.v1.FinancialAdviceApi; +import com.backbase.investment.api.service.v1.InvestmentApi; +import com.backbase.investment.api.service.v1.InvestmentProductsApi; +import com.backbase.investment.api.service.v1.PaymentsApi; +import com.backbase.investment.api.service.v1.PortfolioApi; +import com.backbase.investment.api.service.v1.PortfolioTradingAccountsApi; +import com.backbase.investment.api.service.v1.RiskAssessmentApi; +import com.backbase.stream.investment.saga.InvestmentAssetUniverseSaga; +import com.backbase.stream.investment.saga.InvestmentContentSaga; +import com.backbase.stream.investment.saga.InvestmentSaga; +import com.backbase.stream.investment.service.AsyncTaskService; +import com.backbase.stream.investment.service.InvestmentAssetPriceService; +import com.backbase.stream.investment.service.InvestmentAssetUniverseService; +import com.backbase.stream.investment.service.InvestmentClientService; +import com.backbase.stream.investment.service.InvestmentCurrencyService; +import com.backbase.stream.investment.service.InvestmentIntradayAssetPriceService; +import com.backbase.stream.investment.service.InvestmentModelPortfolioService; +import com.backbase.stream.investment.service.InvestmentPortfolioAllocationService; +import com.backbase.stream.investment.service.InvestmentPortfolioService; +import com.backbase.stream.investment.service.InvestmentRiskAssessmentService; +import com.backbase.stream.investment.service.InvestmentRiskQuestionaryService; +import com.backbase.stream.investment.service.resttemplate.InvestmentRestAssetUniverseService; +import com.backbase.stream.investment.service.resttemplate.InvestmentRestDocumentContentService; +import com.backbase.stream.investment.service.resttemplate.InvestmentRestNewsContentService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +/** + * Unit tests for {@link InvestmentServiceConfiguration}. + * + *

Each {@code @Bean} factory method is called directly (no Spring context) to verify: + *

    + *
  • The method returns a non-null, correctly typed bean instance.
  • + *
+ * + *

All collaborators are Mockito mocks so no Spring wiring or network calls occur. + */ +@DisplayName("InvestmentServiceConfiguration") +class InvestmentServiceConfigurationTest { + + private InvestmentServiceConfiguration config; + + @BeforeEach + void setUp() { + config = new InvestmentServiceConfiguration(); + } + + // ------------------------------------------------------------------------- + // Simple single-arg service beans + // ------------------------------------------------------------------------- + + @Nested + @DisplayName("Simple service bean factory methods") + class SimpleServiceBeans { + + @Test + @DisplayName("investmentClientService — returns non-null InvestmentClientService") + void investmentClientService_returnsNonNull() { + assertThat(config.investmentClientService(mock(ClientApi.class))) + .isNotNull().isInstanceOf(InvestmentClientService.class); + } + + @Test + @DisplayName("asyncTaskService — returns non-null AsyncTaskService") + void asyncTaskService_returnsNonNull() { + assertThat(config.asyncTaskService(mock(AsyncBulkGroupsApi.class))) + .isNotNull().isInstanceOf(AsyncTaskService.class); + } + + @Test + @DisplayName("investmentModelPortfolioService — returns non-null InvestmentModelPortfolioService") + void investmentModelPortfolioService_returnsNonNull() { + assertThat(config.investmentModelPortfolioService(mock(FinancialAdviceApi.class))) + .isNotNull().isInstanceOf(InvestmentModelPortfolioService.class); + } + + @Test + @DisplayName("investmentAssetPriceService — returns non-null InvestmentAssetPriceService") + void investmentAssetPriceService_returnsNonNull() { + assertThat(config.investmentAssetPriceService(mock(AssetUniverseApi.class))) + .isNotNull().isInstanceOf(InvestmentAssetPriceService.class); + } + + @Test + @DisplayName("investmentIntradayAssetPriceService — returns non-null InvestmentIntradayAssetPriceService") + void investmentIntradayAssetPriceService_returnsNonNull() { + assertThat(config.investmentIntradayAssetPriceService(mock(AssetUniverseApi.class))) + .isNotNull().isInstanceOf(InvestmentIntradayAssetPriceService.class); + } + + @Test + @DisplayName("investmentCurrencyService — returns non-null InvestmentCurrencyService") + void investmentCurrencyService_returnsNonNull() { + assertThat(config.investmentCurrencyService(mock(CurrencyApi.class))) + .isNotNull().isInstanceOf(InvestmentCurrencyService.class); + } + + @Test + @DisplayName("investmentRiskAssessmentService — returns non-null InvestmentRiskAssessmentService") + void investmentRiskAssessmentService_returnsNonNull() { + assertThat(config.investmentRiskAssessmentService(mock(RiskAssessmentApi.class))) + .isNotNull().isInstanceOf(InvestmentRiskAssessmentService.class); + } + } + + // ------------------------------------------------------------------------- + // Multi-arg service beans + // ------------------------------------------------------------------------- + + @Nested + @DisplayName("Multi-arg service bean factory methods") + class MultiArgServiceBeans { + + @Test + @DisplayName("investmentPortfolioService — returns non-null InvestmentPortfolioService") + void investmentPortfolioService_returnsNonNull() { + assertThat(config.investmentPortfolioService( + mock(PortfolioApi.class), + mock(InvestmentProductsApi.class), + mock(PaymentsApi.class), + mock(PortfolioTradingAccountsApi.class), + mock(IngestConfigProperties.class))) + .isNotNull().isInstanceOf(InvestmentPortfolioService.class); + } + + @Test + @DisplayName("investmentAssetUniverseService — returns non-null InvestmentAssetUniverseService") + void investmentAssetUniverseService_returnsNonNull() { + assertThat(config.investmentAssetUniverseService( + mock(AssetUniverseApi.class), + mock(InvestmentRestAssetUniverseService.class))) + .isNotNull().isInstanceOf(InvestmentAssetUniverseService.class); + } + + @Test + @DisplayName("investmentPortfolioAllocationService — returns non-null InvestmentPortfolioAllocationService") + void investmentPortfolioAllocationService_returnsNonNull() { + assertThat(config.investmentPortfolioAllocationService( + mock(AllocationsApi.class), + mock(AssetUniverseApi.class), + mock(InvestmentApi.class), + mock(IngestConfigProperties.class))) + .isNotNull().isInstanceOf(InvestmentPortfolioAllocationService.class); + } + + @Test + @DisplayName("investmentRiskQuestionaryService — returns non-null InvestmentRiskQuestionaryService") + void investmentRiskQuestionaryService_returnsNonNull() { + assertThat(config.investmentRiskQuestionaryService( + mock(RiskAssessmentApi.class), + mock(IngestConfigProperties.class))) + .isNotNull().isInstanceOf(InvestmentRiskQuestionaryService.class); + } + } + + // ------------------------------------------------------------------------- + // Saga bean factory methods + // ------------------------------------------------------------------------- + + @Nested + @DisplayName("Saga bean factory methods") + class SagaBeans { + + @Test + @DisplayName("investmentSaga — returns non-null InvestmentSaga") + void investmentSaga_returnsNonNull() { + assertThat(config.investmentSaga( + mock(InvestmentClientService.class), + mock(InvestmentRiskAssessmentService.class), + mock(InvestmentRiskQuestionaryService.class), + mock(InvestmentPortfolioService.class), + mock(InvestmentModelPortfolioService.class), + mock(InvestmentPortfolioAllocationService.class), + mock(AsyncTaskService.class), + mock(InvestmentIngestionConfigurationProperties.class))) + .isNotNull().isInstanceOf(InvestmentSaga.class); + } + + @Test + @DisplayName("investmentStaticDataSaga — returns non-null InvestmentAssetUniverseSaga") + void investmentStaticDataSaga_returnsNonNull() { + assertThat(config.investmentStaticDataSaga( + mock(InvestmentAssetUniverseService.class), + mock(InvestmentAssetPriceService.class), + mock(InvestmentIntradayAssetPriceService.class), + mock(InvestmentCurrencyService.class), + mock(AsyncTaskService.class), + mock(InvestmentIngestionConfigurationProperties.class), + mock(IngestConfigProperties.class))) + .isNotNull().isInstanceOf(InvestmentAssetUniverseSaga.class); + } + + @Test + @DisplayName("investmentContentSaga — returns non-null InvestmentContentSaga") + void investmentContentSaga_returnsNonNull() { + assertThat(config.investmentContentSaga( + mock(InvestmentRestNewsContentService.class), + mock(InvestmentRestDocumentContentService.class), + mock(InvestmentIngestionConfigurationProperties.class))) + .isNotNull().isInstanceOf(InvestmentContentSaga.class); + } + } +} +