Skip to content

Commit

Permalink
Merge pull request #1146 from dilipdhankecha2530/feat-fetch-bpn-based…
Browse files Browse the repository at this point in the history
…-on-request-identifiers

feat: endpoint to return bpnl/s/a based on the requested identifiers
  • Loading branch information
nicoprow authored Dec 4, 2024
2 parents 6623495 + dad2516 commit 93ac725
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
18 changes: 9 additions & 9 deletions DEPENDENCIES
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ 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
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.PostMapping
Expand Down Expand Up @@ -62,4 +64,17 @@ interface PoolBpnApi {
@Tag(name = ApiCommons.BPN_NAME, description = ApiCommons.BPN_DESCRIPTION)
@PostMapping(CommonApiPathNames.SUBPATH_SEARCH)
fun findBpnsByIdentifiers(@RequestBody request: IdentifiersSearchRequest): ResponseEntity<Set<BpnIdentifierMappingDto>>

@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/search")
fun findBpnByRequestedIdentifiers(@RequestBody request: BpnRequestIdentifierSearchRequest): ResponseEntity<Set<BpnRequestIdentifierMappingDto>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ 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
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.service.annotation.HttpExchange
Expand All @@ -32,4 +34,7 @@ import org.springframework.web.service.annotation.PostExchange
interface BpnApiClient: PoolBpnApi {
@PostExchange(CommonApiPathNames.SUBPATH_SEARCH)
override fun findBpnsByIdentifiers(@RequestBody request: IdentifiersSearchRequest): ResponseEntity<Set<BpnIdentifierMappingDto>>

@PostExchange(value = "/request-ids/search")
override fun findBpnByRequestedIdentifiers(@RequestBody request: BpnRequestIdentifierSearchRequest): ResponseEntity<Set<BpnRequestIdentifierMappingDto>>
}
Original file line number Diff line number Diff line change
@@ -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<String>
)
Original file line number Diff line number Diff line change
@@ -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
)
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
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
import org.eclipse.tractusx.bpdm.pool.config.ControllerConfigProperties
import org.eclipse.tractusx.bpdm.pool.config.PermissionConfigProperties
import org.eclipse.tractusx.bpdm.pool.service.BusinessPartnerFetchService
Expand All @@ -45,4 +47,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: BpnRequestIdentifierSearchRequest): ResponseEntity<Set<BpnRequestIdentifierMappingDto>> {
if (request.requestedIdentifiers.size > controllerConfigProperties.searchRequestLimit) {
return ResponseEntity(HttpStatus.BAD_REQUEST)
}
val bpnIdentifierMappings = businessPartnerFetchService.findBpnByRequestedIdentifiers(request.requestedIdentifiers)
return ResponseEntity(bpnIdentifierMappings, HttpStatus.OK)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -121,6 +121,21 @@ class BusinessPartnerFetchService(
}
}

/**
* Find bpn based on request-identifier value
*/
@Transactional
fun findBpnByRequestedIdentifiers(request: Set<String>): Set<BpnRequestIdentifierMappingDto> {
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<LegalEntityDb>): Set<LegalEntityDb> {
fetchLegalEntityDependencies(partners)
legalEntityRepository.joinLegalAddresses(partners)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,29 @@ 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
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],
Expand All @@ -48,6 +57,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,
) {
Expand Down Expand Up @@ -81,6 +91,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
)
)
)
}

/**
Expand Down Expand Up @@ -138,4 +165,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(BpnRequestIdentifierSearchRequest(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(BpnRequestIdentifierSearchRequest(requestedIdentifiers))
assertThrows<WebClientResponseException> { 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(BpnRequestIdentifierSearchRequest(requestedIdentifiers))
response.body?.let { Assertions.assertNotEquals(requestedIdentifiers.size, it.size) }
response.body?.let { Assertions.assertTrue(it.isEmpty()) }
}
}
Loading

0 comments on commit 93ac725

Please sign in to comment.