From f3bf01bb0c0cfbd1d66a09e5e79cfef4af681bbf Mon Sep 17 00:00:00 2001 From: Dilip Dhankecha Date: Tue, 3 Dec 2024 16:46:04 +0530 Subject: [PATCH 1/3] feat: endpoint to return bpnl/s/a based on the requested identifiers --- DEPENDENCIES | 12 ++-- .../pool/BusinessPartnerVerboseValues.kt | 10 +-- .../tractusx/bpdm/pool/api/PoolBpnApi.kt | 14 ++++ .../bpdm/pool/api/client/BpnApiClient.kt | 4 ++ .../BpnRequestIdentifierMappingDto.kt | 32 +++++++++ .../bpdm/pool/controller/BpnController.kt | 10 +++ .../service/BusinessPartnerFetchService.kt | 23 ++++-- .../bpdm/pool/controller/BpnControllerIT.kt | 70 ++++++++++++++++++- docs/api/pool.json | 58 +++++++++++++++ docs/api/pool.yaml | 39 +++++++++++ 10 files changed, 257 insertions(+), 15 deletions(-) create mode 100644 bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/response/BpnRequestIdentifierMappingDto.kt diff --git a/DEPENDENCIES b/DEPENDENCIES index 84b9add9c..b9989b3f5 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -117,12 +117,12 @@ maven/mavencentral/org.awaitility/awaitility/4.2.2, Apache-2.0, approved, #14178 maven/mavencentral/org.checkerframework/checker-qual/3.42.0, MIT, approved, clearlydefined maven/mavencentral/org.eclipse.angus/angus-activation/2.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.angus maven/mavencentral/org.eclipse.angus/angus-mail/2.0.3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.angus -maven/mavencentral/org.eclipse.tractusx/bpdm-common-test/6.2.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx/bpdm-common/6.2.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx/bpdm-gate-api/6.2.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx/bpdm-orchestrator-api/6.2.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx/bpdm-orchestrator/6.2.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx/bpdm-pool-api/6.2.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx/bpdm-common-test/6.3.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx/bpdm-common/6.3.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx/bpdm-gate-api/6.3.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx/bpdm-orchestrator-api/6.3.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx/bpdm-orchestrator/6.3.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx/bpdm-pool-api/6.3.0-SNAPSHOT, Apache-2.0, approved, automotive.tractusx maven/mavencentral/org.flywaydb/flyway-core/10.10.0, Apache-2.0, approved, #14163 maven/mavencentral/org.flywaydb/flyway-database-postgresql/10.10.0, Apache-2.0, approved, #14158 maven/mavencentral/org.glassfish.jaxb/codemodel/4.0.5, BSD-3-Clause, approved, ee4j.jaxb-impl diff --git a/bpdm-common-test/src/main/kotlin/org/eclipse/tractusx/bpdm/test/testdata/pool/BusinessPartnerVerboseValues.kt b/bpdm-common-test/src/main/kotlin/org/eclipse/tractusx/bpdm/test/testdata/pool/BusinessPartnerVerboseValues.kt index 8b7fb3cb3..5feed8a30 100644 --- a/bpdm-common-test/src/main/kotlin/org/eclipse/tractusx/bpdm/test/testdata/pool/BusinessPartnerVerboseValues.kt +++ b/bpdm-common-test/src/main/kotlin/org/eclipse/tractusx/bpdm/test/testdata/pool/BusinessPartnerVerboseValues.kt @@ -27,13 +27,11 @@ import org.eclipse.tractusx.bpdm.common.model.BusinessStateType import org.eclipse.tractusx.bpdm.common.model.ClassificationType import org.eclipse.tractusx.bpdm.common.service.toDto import org.eclipse.tractusx.bpdm.pool.api.model.* -import org.eclipse.tractusx.bpdm.pool.api.model.response.AddressPartnerCreateVerboseDto -import org.eclipse.tractusx.bpdm.pool.api.model.response.LegalEntityPartnerCreateVerboseDto -import org.eclipse.tractusx.bpdm.pool.api.model.response.LegalEntityWithLegalAddressVerboseDto -import org.eclipse.tractusx.bpdm.pool.api.model.response.SitePartnerCreateVerboseDto +import org.eclipse.tractusx.bpdm.pool.api.model.response.* import java.time.Instant import java.time.LocalDateTime import java.time.ZoneOffset +import java.util.UUID /** * Test values for response DTOs @@ -68,6 +66,10 @@ object BusinessPartnerVerboseValues { val identifierType3 = TypeKeyNameVerboseDto("VAT_FR", "VAT France") val identifierType4 = TypeKeyNameVerboseDto("VAT_NL", "VAT Netherlands") + val bpnLRequestMapping = BpnRequestIdentifierMappingDto(UUID.randomUUID().toString(), bpn = secondBpnL) + val bpnSRequestMapping = BpnRequestIdentifierMappingDto(UUID.randomUUID().toString(), bpn = secondBpnS) + val bpnARequestMapping = BpnRequestIdentifierMappingDto(UUID.randomUUID().toString(), bpn = secondBpnA) + val identifierTypeAbbreviation1 = "abbreviation1" val identifierTypeAbbreviation2 = "abbreviation2" val identifierTypeAbbreviation3 = "abbreviation3" diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolBpnApi.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolBpnApi.kt index fd67bcb7a..e29cf9abd 100644 --- a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolBpnApi.kt +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolBpnApi.kt @@ -29,6 +29,7 @@ import org.eclipse.tractusx.bpdm.common.util.CommonApiPathNames import org.eclipse.tractusx.bpdm.pool.api.PoolBpnApi.Companion.BPN_PATH import org.eclipse.tractusx.bpdm.pool.api.model.request.IdentifiersSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnIdentifierMappingDto +import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnRequestIdentifierMappingDto import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.PostMapping @@ -62,4 +63,17 @@ interface PoolBpnApi { @Tag(name = ApiCommons.BPN_NAME, description = ApiCommons.BPN_DESCRIPTION) @PostMapping(CommonApiPathNames.SUBPATH_SEARCH) fun findBpnsByIdentifiers(@RequestBody request: IdentifiersSearchRequest): ResponseEntity> + + @Operation( + summary = "Return BPNL/S/A based on the requested identifiers", + description = "Find business partner numbers by requested-identifiers." + ) + @ApiResponses( + value = [ + ApiResponse(responseCode = "200", description = "Found bpn to based on the requested identifiers"), + ] + ) + @Tag(name = ApiCommons.BPN_NAME, description = ApiCommons.BPN_DESCRIPTION) + @PostMapping("/request-ids") + fun findBpnByRequestedIdentifiers(@RequestBody request: Set): ResponseEntity> } \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/BpnApiClient.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/BpnApiClient.kt index 5c4f61330..76df36d53 100644 --- a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/BpnApiClient.kt +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/BpnApiClient.kt @@ -23,6 +23,7 @@ import org.eclipse.tractusx.bpdm.common.util.CommonApiPathNames import org.eclipse.tractusx.bpdm.pool.api.PoolBpnApi import org.eclipse.tractusx.bpdm.pool.api.model.request.IdentifiersSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnIdentifierMappingDto +import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnRequestIdentifierMappingDto import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.service.annotation.HttpExchange @@ -32,4 +33,7 @@ import org.springframework.web.service.annotation.PostExchange interface BpnApiClient: PoolBpnApi { @PostExchange(CommonApiPathNames.SUBPATH_SEARCH) override fun findBpnsByIdentifiers(@RequestBody request: IdentifiersSearchRequest): ResponseEntity> + + @PostExchange(value = "/request-ids") + override fun findBpnByRequestedIdentifiers(@RequestBody identifiers: Set): ResponseEntity> } \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/response/BpnRequestIdentifierMappingDto.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/response/BpnRequestIdentifierMappingDto.kt new file mode 100644 index 000000000..76a58f9a3 --- /dev/null +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/response/BpnRequestIdentifierMappingDto.kt @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ******************************************************************************/ + +package org.eclipse.tractusx.bpdm.pool.api.model.response + +import io.swagger.v3.oas.annotations.media.Schema + +@Schema(name = "BpnRequestIdentifierMappingDto", description = "Mapping of Business Partner Number to requested-identifier value") +data class BpnRequestIdentifierMappingDto( + + @Schema(description = "Value of the requested-identifier") + val requestedIdentifier: String, + + @Schema(description = "Business Partner Number") + val bpn: String +) \ No newline at end of file diff --git a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnController.kt b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnController.kt index ff85682f9..832d08a62 100644 --- a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnController.kt +++ b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnController.kt @@ -22,6 +22,7 @@ package org.eclipse.tractusx.bpdm.pool.controller import org.eclipse.tractusx.bpdm.pool.api.PoolBpnApi import org.eclipse.tractusx.bpdm.pool.api.model.request.IdentifiersSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnIdentifierMappingDto +import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnRequestIdentifierMappingDto import org.eclipse.tractusx.bpdm.pool.config.ControllerConfigProperties import org.eclipse.tractusx.bpdm.pool.config.PermissionConfigProperties import org.eclipse.tractusx.bpdm.pool.service.BusinessPartnerFetchService @@ -45,4 +46,13 @@ class BpnController( val bpnIdentifierMappings = businessPartnerFetchService.findBpnsByIdentifiers(request.idType, request.businessPartnerType, request.idValues) return ResponseEntity(bpnIdentifierMappings, HttpStatus.OK) } + + @PreAuthorize("hasAuthority(${PermissionConfigProperties.READ_PARTNER})") + override fun findBpnByRequestedIdentifiers(@RequestBody request: Set): ResponseEntity> { + if (request.size > controllerConfigProperties.searchRequestLimit) { + return ResponseEntity(HttpStatus.BAD_REQUEST) + } + val bpnIdentifierMappings = businessPartnerFetchService.findBpnByRequestedIdentifiers(request) + return ResponseEntity(bpnIdentifierMappings, HttpStatus.OK) + } } diff --git a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/BusinessPartnerFetchService.kt b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/BusinessPartnerFetchService.kt index 503332ff6..9bb70bf76 100644 --- a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/BusinessPartnerFetchService.kt +++ b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/service/BusinessPartnerFetchService.kt @@ -25,18 +25,17 @@ import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest import org.eclipse.tractusx.bpdm.common.exception.BpdmNotFoundException import org.eclipse.tractusx.bpdm.pool.api.model.IdentifierBusinessPartnerType import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnIdentifierMappingDto +import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnRequestIdentifierMappingDto import org.eclipse.tractusx.bpdm.pool.api.model.response.LegalEntityWithLegalAddressVerboseDto import org.eclipse.tractusx.bpdm.pool.entity.IdentifierTypeDb import org.eclipse.tractusx.bpdm.pool.entity.LegalEntityDb import org.eclipse.tractusx.bpdm.pool.entity.LegalEntityIdentifierDb -import org.eclipse.tractusx.bpdm.pool.repository.AddressIdentifierRepository -import org.eclipse.tractusx.bpdm.pool.repository.IdentifierTypeRepository -import org.eclipse.tractusx.bpdm.pool.repository.LegalEntityIdentifierRepository -import org.eclipse.tractusx.bpdm.pool.repository.LegalEntityRepository +import org.eclipse.tractusx.bpdm.pool.repository.* import org.springframework.data.domain.PageRequest import org.springframework.data.jpa.domain.Specification import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import java.util.stream.Collectors /** * Service for fetching business partner records from the database @@ -45,6 +44,7 @@ import org.springframework.transaction.annotation.Transactional class BusinessPartnerFetchService( private val legalEntityRepository: LegalEntityRepository, private val identifierTypeRepository: IdentifierTypeRepository, + private val bpnRequestIdentifierRepository: BpnRequestIdentifierRepository, private val legalEntityIdentifierRepository: LegalEntityIdentifierRepository, private val addressIdentifierRepository: AddressIdentifierRepository, private val addressService: AddressService @@ -121,6 +121,21 @@ class BusinessPartnerFetchService( } } + /** + * Find bpn based on request-identifier value + */ + @Transactional + fun findBpnByRequestedIdentifiers(request: Set): Set { + logger.debug { "Executing findBpnByRequestedIdentifiers() with parameters $request" } + if (request.isEmpty()) { + return emptySet() + } + var bpnRequestIdentifierMapping = bpnRequestIdentifierRepository.findDistinctByRequestIdentifierIn(request) + return bpnRequestIdentifierMapping.stream() + .map { BpnRequestIdentifierMappingDto(it.requestIdentifier, it.bpn) } + .collect(Collectors.toSet()) + } + fun fetchDependenciesWithLegalAddress(partners: Set): Set { fetchLegalEntityDependencies(partners) legalEntityRepository.joinLegalAddresses(partners) diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnControllerIT.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnControllerIT.kt index fc5488edd..0fbabf38d 100644 --- a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnControllerIT.kt +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnControllerIT.kt @@ -25,19 +25,27 @@ import org.eclipse.tractusx.bpdm.pool.api.client.PoolClientImpl import org.eclipse.tractusx.bpdm.pool.api.model.IdentifierBusinessPartnerType import org.eclipse.tractusx.bpdm.pool.api.model.LegalEntityIdentifierDto import org.eclipse.tractusx.bpdm.pool.api.model.request.IdentifiersSearchRequest - +import org.eclipse.tractusx.bpdm.pool.entity.BpnRequestIdentifierMappingDb +import org.eclipse.tractusx.bpdm.pool.repository.BpnRequestIdentifierRepository import org.eclipse.tractusx.bpdm.pool.util.TestHelpers import org.eclipse.tractusx.bpdm.test.containers.PostgreSQLContextInitializer import org.eclipse.tractusx.bpdm.test.testdata.pool.BusinessPartnerNonVerboseValues +import org.eclipse.tractusx.bpdm.test.testdata.pool.BusinessPartnerVerboseValues import org.eclipse.tractusx.bpdm.test.testdata.pool.LegalEntityStructureRequest import org.eclipse.tractusx.bpdm.test.util.DbTestHelpers import org.eclipse.tractusx.bpdm.test.util.PoolDataHelpers +import org.junit.Assert +import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest +import org.springframework.http.HttpStatus import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ContextConfiguration +import org.springframework.web.reactive.function.client.WebClientResponseException +import java.util.* @SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = [Application::class, TestHelpers::class], @@ -48,6 +56,7 @@ import org.springframework.test.context.ContextConfiguration class BpnControllerIT @Autowired constructor( val testHelpers: TestHelpers, val poolClient: PoolClientImpl, + val bpnRequestIdentifierRepository: BpnRequestIdentifierRepository, val dbTestHelpers: DbTestHelpers, val poolDataHelpers: PoolDataHelpers, ) { @@ -81,6 +90,23 @@ class BpnControllerIT @Autowired constructor( LegalEntityStructureRequest(legalEntity = legalEntityCreate3), ) ) + + bpnRequestIdentifierRepository.saveAll( + mutableListOf( + BpnRequestIdentifierMappingDb( + BusinessPartnerVerboseValues.bpnLRequestMapping.requestedIdentifier, + BusinessPartnerVerboseValues.bpnLRequestMapping.bpn + ), + BpnRequestIdentifierMappingDb( + BusinessPartnerVerboseValues.bpnSRequestMapping.requestedIdentifier, + BusinessPartnerVerboseValues.bpnSRequestMapping.bpn + ), + BpnRequestIdentifierMappingDb( + BusinessPartnerVerboseValues.bpnARequestMapping.requestedIdentifier, + BusinessPartnerVerboseValues.bpnARequestMapping.bpn + ) + ) + ) } /** @@ -138,4 +164,46 @@ class BpnControllerIT @Autowired constructor( testHelpers.`find bpns by nonexistent identifier type`(identifiersSearchRequest) } + + /** + * Fetch the BPNL/S/A based on the provided request identifier + */ + @Test + fun `find bpn by requested identifier`() { + val requestedIdentifiers = setOf( + BusinessPartnerVerboseValues.bpnLRequestMapping.requestedIdentifier, + BusinessPartnerVerboseValues.bpnSRequestMapping.requestedIdentifier, + ) + val response = poolClient.bpns.findBpnByRequestedIdentifiers(requestedIdentifiers) + response.body?.let { Assertions.assertEquals(requestedIdentifiers.size, it.size) } + } + + /** + * Find BPN based on the requested identifiers but with the set more than the search limit. + */ + @Test + fun `find bpn by requested identifier with extended search limit`() { + val requestedIdentifiers = setOf( + BusinessPartnerVerboseValues.bpnLRequestMapping.requestedIdentifier, + BusinessPartnerVerboseValues.bpnSRequestMapping.requestedIdentifier, + BusinessPartnerVerboseValues.bpnARequestMapping.requestedIdentifier, + ) + try { + val result = poolClient.bpns.findBpnByRequestedIdentifiers(requestedIdentifiers) + assertThrows { result } + } catch (e: WebClientResponseException) { + Assert.assertEquals(HttpStatus.BAD_REQUEST, e.statusCode) + } + } + + /** + * Fetch the BPNL/S/A based on the invalid request identifier + */ + @Test + fun `find bpn by invalid requested identifier`() { + val requestedIdentifiers = setOf(UUID.randomUUID().toString()) + val response = poolClient.bpns.findBpnByRequestedIdentifiers(requestedIdentifiers) + response.body?.let { Assertions.assertNotEquals(requestedIdentifiers.size, it.size) } + response.body?.let { Assertions.assertTrue(it.isEmpty()) } + } } \ No newline at end of file diff --git a/docs/api/pool.json b/docs/api/pool.json index dfcfa10be..4e46389dc 100644 --- a/docs/api/pool.json +++ b/docs/api/pool.json @@ -1528,6 +1528,46 @@ } } }, + "/v6/bpn/request-ids": { + "post": { + "tags": [ + "Bpn Controller" + ], + "summary": "Return BPNL/S/A based on the requested identifiers", + "description": "Find business partner numbers by requested-identifiers.", + "operationId": "findBpnByRequestedIdentifiers", + "requestBody": { + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Found bpn to based on the requested identifiers", + "content": { + "application/json": { + "schema": { + "uniqueItems": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/BpnRequestIdentifierMappingDto" + } + } + } + } + } + } + } + }, "/v6/addresses/search": { "post": { "tags": [ @@ -2817,6 +2857,24 @@ }, "description": "Mapping of Business Partner Number to identifier value" }, + "BpnRequestIdentifierMappingDto": { + "required": [ + "bpn", + "requestedIdentifier" + ], + "type": "object", + "properties": { + "requestedIdentifier": { + "type": "string", + "description": "Value of the requested-identifier" + }, + "bpn": { + "type": "string", + "description": "Business Partner Number" + } + }, + "description": "Mapping of Business Partner Number to requested-identifier value" + }, "ChangelogEntryVerboseDto": { "required": [ "bpn", diff --git a/docs/api/pool.yaml b/docs/api/pool.yaml index aabf4da14..c9f436213 100644 --- a/docs/api/pool.yaml +++ b/docs/api/pool.yaml @@ -1087,6 +1087,32 @@ paths: description: On malformed request parameters or if number of requested bpns exceeds limit '404': description: Specified identifier type not found + /v6/bpn/request-ids: + post: + tags: + - Bpn Controller + summary: Return BPNL/S/A based on the requested identifiers + description: Find business partner numbers by requested-identifiers. + operationId: findBpnByRequestedIdentifiers + requestBody: + content: + application/json: + schema: + uniqueItems: true + type: array + items: + type: string + required: true + responses: + '200': + description: Found bpn to based on the requested identifiers + content: + application/json: + schema: + uniqueItems: true + type: array + items: + $ref: '#/components/schemas/BpnRequestIdentifierMappingDto' /v6/addresses/search: post: tags: @@ -2144,6 +2170,19 @@ components: type: string description: Business Partner Number description: Mapping of Business Partner Number to identifier value + BpnRequestIdentifierMappingDto: + required: + - bpn + - requestedIdentifier + type: object + properties: + requestedIdentifier: + type: string + description: Value of the requested-identifier + bpn: + type: string + description: Business Partner Number + description: Mapping of Business Partner Number to requested-identifier value ChangelogEntryVerboseDto: required: - bpn From e439e83990c6cc3205085ec46e2996071140b6a6 Mon Sep 17 00:00:00 2001 From: Dilip Dhankecha Date: Wed, 4 Dec 2024 11:54:31 +0530 Subject: [PATCH 2/3] fix: update the endpoint mapping and the docs --- CHANGELOG.md | 1 + .../tractusx/bpdm/pool/api/PoolBpnApi.kt | 5 ++-- .../bpdm/pool/api/client/BpnApiClient.kt | 5 ++-- .../BpnRequestIdentifierSearchRequest.kt | 28 +++++++++++++++++++ .../bpdm/pool/controller/BpnController.kt | 7 +++-- docs/api/pool.json | 26 +++++++++++++---- docs/api/pool.yaml | 20 +++++++++---- 7 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/BpnRequestIdentifierSearchRequest.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e2f83bc..60297d4d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ For changes to the BPDM Helm charts please consult the [changelog](charts/bpdm/C ### Added +- BPDM Pool: Post endpoint to fetch the BPNL/S/A based on the requested identifiers.([#1052](https://github.com/eclipse-tractusx/bpdm/issues/1052)) ### Changed diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolBpnApi.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolBpnApi.kt index e29cf9abd..0f21195e5 100644 --- a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolBpnApi.kt +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/PoolBpnApi.kt @@ -27,6 +27,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag import org.eclipse.tractusx.bpdm.common.util.CommonApiPathNames import org.eclipse.tractusx.bpdm.pool.api.PoolBpnApi.Companion.BPN_PATH +import org.eclipse.tractusx.bpdm.pool.api.model.request.BpnRequestIdentifierSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.request.IdentifiersSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnIdentifierMappingDto import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnRequestIdentifierMappingDto @@ -74,6 +75,6 @@ interface PoolBpnApi { ] ) @Tag(name = ApiCommons.BPN_NAME, description = ApiCommons.BPN_DESCRIPTION) - @PostMapping("/request-ids") - fun findBpnByRequestedIdentifiers(@RequestBody request: Set): ResponseEntity> + @PostMapping("/request-ids/search") + fun findBpnByRequestedIdentifiers(@RequestBody request: BpnRequestIdentifierSearchRequest): ResponseEntity> } \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/BpnApiClient.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/BpnApiClient.kt index 76df36d53..87b27a7ba 100644 --- a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/BpnApiClient.kt +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/client/BpnApiClient.kt @@ -21,6 +21,7 @@ package org.eclipse.tractusx.bpdm.pool.api.client import org.eclipse.tractusx.bpdm.common.util.CommonApiPathNames import org.eclipse.tractusx.bpdm.pool.api.PoolBpnApi +import org.eclipse.tractusx.bpdm.pool.api.model.request.BpnRequestIdentifierSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.request.IdentifiersSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnIdentifierMappingDto import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnRequestIdentifierMappingDto @@ -34,6 +35,6 @@ interface BpnApiClient: PoolBpnApi { @PostExchange(CommonApiPathNames.SUBPATH_SEARCH) override fun findBpnsByIdentifiers(@RequestBody request: IdentifiersSearchRequest): ResponseEntity> - @PostExchange(value = "/request-ids") - override fun findBpnByRequestedIdentifiers(@RequestBody identifiers: Set): ResponseEntity> + @PostExchange(value = "/request-ids/search") + override fun findBpnByRequestedIdentifiers(@RequestBody request: BpnRequestIdentifierSearchRequest): ResponseEntity> } \ No newline at end of file diff --git a/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/BpnRequestIdentifierSearchRequest.kt b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/BpnRequestIdentifierSearchRequest.kt new file mode 100644 index 000000000..c0ea05457 --- /dev/null +++ b/bpdm-pool-api/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/api/model/request/BpnRequestIdentifierSearchRequest.kt @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ******************************************************************************/ + +package org.eclipse.tractusx.bpdm.pool.api.model.request + +import io.swagger.v3.oas.annotations.media.Schema + +@Schema(name = "BpnRequestIdentifierSearchRequest", description = "Mapping of Business Partner Number to requested-identifier value") +data class BpnRequestIdentifierSearchRequest ( + @Schema(description = "Value of the requested-identifier") + val requestedIdentifiers: Set +) \ No newline at end of file diff --git a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnController.kt b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnController.kt index 832d08a62..f521c8614 100644 --- a/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnController.kt +++ b/bpdm-pool/src/main/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnController.kt @@ -20,6 +20,7 @@ package org.eclipse.tractusx.bpdm.pool.controller import org.eclipse.tractusx.bpdm.pool.api.PoolBpnApi +import org.eclipse.tractusx.bpdm.pool.api.model.request.BpnRequestIdentifierSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.request.IdentifiersSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnIdentifierMappingDto import org.eclipse.tractusx.bpdm.pool.api.model.response.BpnRequestIdentifierMappingDto @@ -48,11 +49,11 @@ class BpnController( } @PreAuthorize("hasAuthority(${PermissionConfigProperties.READ_PARTNER})") - override fun findBpnByRequestedIdentifiers(@RequestBody request: Set): ResponseEntity> { - if (request.size > controllerConfigProperties.searchRequestLimit) { + override fun findBpnByRequestedIdentifiers(@RequestBody request: BpnRequestIdentifierSearchRequest): ResponseEntity> { + if (request.requestedIdentifiers.size > controllerConfigProperties.searchRequestLimit) { return ResponseEntity(HttpStatus.BAD_REQUEST) } - val bpnIdentifierMappings = businessPartnerFetchService.findBpnByRequestedIdentifiers(request) + val bpnIdentifierMappings = businessPartnerFetchService.findBpnByRequestedIdentifiers(request.requestedIdentifiers) return ResponseEntity(bpnIdentifierMappings, HttpStatus.OK) } } diff --git a/docs/api/pool.json b/docs/api/pool.json index 4e46389dc..3f9b7b49e 100644 --- a/docs/api/pool.json +++ b/docs/api/pool.json @@ -1528,7 +1528,7 @@ } } }, - "/v6/bpn/request-ids": { + "/v6/bpn/request-ids/search": { "post": { "tags": [ "Bpn Controller" @@ -1540,11 +1540,7 @@ "content": { "application/json": { "schema": { - "uniqueItems": true, - "type": "array", - "items": { - "type": "string" - } + "$ref": "#/components/schemas/BpnRequestIdentifierSearchRequest" } } }, @@ -2875,6 +2871,24 @@ }, "description": "Mapping of Business Partner Number to requested-identifier value" }, + "BpnRequestIdentifierSearchRequest": { + "required": [ + "requestedIdentifiers" + ], + "type": "object", + "properties": { + "requestedIdentifiers": { + "uniqueItems": true, + "type": "array", + "description": "Value of the requested-identifier", + "items": { + "type": "string", + "description": "Value of the requested-identifier" + } + } + }, + "description": "Mapping of Business Partner Number to requested-identifier value" + }, "ChangelogEntryVerboseDto": { "required": [ "bpn", diff --git a/docs/api/pool.yaml b/docs/api/pool.yaml index c9f436213..40fd6b52f 100644 --- a/docs/api/pool.yaml +++ b/docs/api/pool.yaml @@ -1087,7 +1087,7 @@ paths: description: On malformed request parameters or if number of requested bpns exceeds limit '404': description: Specified identifier type not found - /v6/bpn/request-ids: + /v6/bpn/request-ids/search: post: tags: - Bpn Controller @@ -1098,10 +1098,7 @@ paths: content: application/json: schema: - uniqueItems: true - type: array - items: - type: string + $ref: '#/components/schemas/BpnRequestIdentifierSearchRequest' required: true responses: '200': @@ -2183,6 +2180,19 @@ components: type: string description: Business Partner Number description: Mapping of Business Partner Number to requested-identifier value + BpnRequestIdentifierSearchRequest: + required: + - requestedIdentifiers + type: object + properties: + requestedIdentifiers: + uniqueItems: true + type: array + description: Value of the requested-identifier + items: + type: string + description: Value of the requested-identifier + description: Mapping of Business Partner Number to requested-identifier value ChangelogEntryVerboseDto: required: - bpn From dad2516f3d022bd6680d115e304245cea8fb7632 Mon Sep 17 00:00:00 2001 From: Dilip Dhankecha Date: Wed, 4 Dec 2024 12:13:38 +0530 Subject: [PATCH 3/3] fix: update test cases based on the latest changes --- DEPENDENCIES | 20 +++++++++---------- .../bpdm/pool/controller/BpnControllerIT.kt | 7 ++++--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index b152f9979..6cffc658e 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -149,11 +149,11 @@ maven/mavencentral/org.jboss.shrinkwrap/shrinkwrap-api/1.2.6, Apache-2.0, approv maven/mavencentral/org.jboss.shrinkwrap/shrinkwrap-impl-base/1.2.6, Apache-2.0, approved, clearlydefined maven/mavencentral/org.jboss.shrinkwrap/shrinkwrap-spi/1.2.6, Apache-2.0, approved, clearlydefined maven/mavencentral/org.jboss/jandex/2.4.3.Final, Apache-2.0, approved, clearlydefined -maven/mavencentral/org.jetbrains.kotlin/kotlin-reflect/2.1.0, , restricted, clearlydefined +maven/mavencentral/org.jetbrains.kotlin/kotlin-reflect/2.1.0, Apache-2.0, approved, #17637 maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-common/1.8.0, Apache-2.0, approved, #8910 -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk7/2.1.0, , restricted, clearlydefined -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk8/2.1.0, , restricted, clearlydefined -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.1.0, , restricted, clearlydefined +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk7/2.1.0, None, restricted, #17633 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk8/2.1.0, None, restricted, #17635 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.1.0, Apache-2.0, approved, #17634 maven/mavencentral/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.8.1, Apache-2.0, approved, clearlydefined maven/mavencentral/org.jetbrains.kotlinx/kotlinx-coroutines-core/1.8.1, Apache-2.0, approved, clearlydefined maven/mavencentral/org.jetbrains/annotations/13.0, Apache-2.0, approved, clearlydefined @@ -227,11 +227,11 @@ maven/mavencentral/org.springframework/spring-tx/6.2.0, Apache-2.0, approved, #1 maven/mavencentral/org.springframework/spring-web/6.2.0, Apache-2.0, approved, #17558 maven/mavencentral/org.springframework/spring-webflux/6.2.0, Apache-2.0, approved, #17567 maven/mavencentral/org.springframework/spring-webmvc/6.2.0, Apache-2.0, approved, #17532 -maven/mavencentral/org.testcontainers/database-commons/1.20.3, Apache-2.0, approved, #16630 -maven/mavencentral/org.testcontainers/jdbc/1.20.3, Apache-2.0, approved, #16621 -maven/mavencentral/org.testcontainers/junit-jupiter/1.20.3, MIT, approved, #16552 -maven/mavencentral/org.testcontainers/postgresql/1.20.3, MIT, approved, #16627 -maven/mavencentral/org.testcontainers/testcontainers/1.20.3, MIT, approved, #15747 +maven/mavencentral/org.testcontainers/database-commons/1.20.4, Apache-2.0, approved, #16630 +maven/mavencentral/org.testcontainers/jdbc/1.20.4, Apache-2.0, approved, #16621 +maven/mavencentral/org.testcontainers/junit-jupiter/1.20.4, MIT, approved, #16552 +maven/mavencentral/org.testcontainers/postgresql/1.20.4, MIT, approved, #16627 +maven/mavencentral/org.testcontainers/testcontainers/1.20.4, MIT, approved, #15747 maven/mavencentral/org.webjars/swagger-ui/5.17.14, Apache-2.0 AND MIT, approved, #15701 maven/mavencentral/org.xmlunit/xmlunit-core/2.10.0, Apache-2.0, approved, #14590 -maven/mavencentral/org.yaml/snakeyaml/2.3, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #16046 \ No newline at end of file +maven/mavencentral/org.yaml/snakeyaml/2.3, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #16046 diff --git a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnControllerIT.kt b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnControllerIT.kt index 0fbabf38d..56ae68403 100644 --- a/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnControllerIT.kt +++ b/bpdm-pool/src/test/kotlin/org/eclipse/tractusx/bpdm/pool/controller/BpnControllerIT.kt @@ -24,6 +24,7 @@ import org.eclipse.tractusx.bpdm.pool.Application import org.eclipse.tractusx.bpdm.pool.api.client.PoolClientImpl import org.eclipse.tractusx.bpdm.pool.api.model.IdentifierBusinessPartnerType import org.eclipse.tractusx.bpdm.pool.api.model.LegalEntityIdentifierDto +import org.eclipse.tractusx.bpdm.pool.api.model.request.BpnRequestIdentifierSearchRequest import org.eclipse.tractusx.bpdm.pool.api.model.request.IdentifiersSearchRequest import org.eclipse.tractusx.bpdm.pool.entity.BpnRequestIdentifierMappingDb import org.eclipse.tractusx.bpdm.pool.repository.BpnRequestIdentifierRepository @@ -174,7 +175,7 @@ class BpnControllerIT @Autowired constructor( BusinessPartnerVerboseValues.bpnLRequestMapping.requestedIdentifier, BusinessPartnerVerboseValues.bpnSRequestMapping.requestedIdentifier, ) - val response = poolClient.bpns.findBpnByRequestedIdentifiers(requestedIdentifiers) + val response = poolClient.bpns.findBpnByRequestedIdentifiers(BpnRequestIdentifierSearchRequest(requestedIdentifiers)) response.body?.let { Assertions.assertEquals(requestedIdentifiers.size, it.size) } } @@ -189,7 +190,7 @@ class BpnControllerIT @Autowired constructor( BusinessPartnerVerboseValues.bpnARequestMapping.requestedIdentifier, ) try { - val result = poolClient.bpns.findBpnByRequestedIdentifiers(requestedIdentifiers) + val result = poolClient.bpns.findBpnByRequestedIdentifiers(BpnRequestIdentifierSearchRequest(requestedIdentifiers)) assertThrows { result } } catch (e: WebClientResponseException) { Assert.assertEquals(HttpStatus.BAD_REQUEST, e.statusCode) @@ -202,7 +203,7 @@ class BpnControllerIT @Autowired constructor( @Test fun `find bpn by invalid requested identifier`() { val requestedIdentifiers = setOf(UUID.randomUUID().toString()) - val response = poolClient.bpns.findBpnByRequestedIdentifiers(requestedIdentifiers) + val response = poolClient.bpns.findBpnByRequestedIdentifiers(BpnRequestIdentifierSearchRequest(requestedIdentifiers)) response.body?.let { Assertions.assertNotEquals(requestedIdentifiers.size, it.size) } response.body?.let { Assertions.assertTrue(it.isEmpty()) } }