Skip to content

Commit

Permalink
feat(Gate): generic business partners can now be shared on demand
Browse files Browse the repository at this point in the history
- created API endpoint to set sharing state to ready
- created scheduled function to poll ready business partners and share them to the orchestrator
- moved all scheduled functions to their own golden record task service
- aligned the configuration properties and made them less error prone
  • Loading branch information
nicoprow committed Dec 22, 2023
1 parent 5586fdd commit 1835ac5
Show file tree
Hide file tree
Showing 18 changed files with 590 additions and 217 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class CleaningServiceDummy(

val addressPartner = createAddressRepresentation(genericBusinessPartner)

val addressType = genericBusinessPartner.address.addressType ?: AddressType.AdditionalAddress
val addressType = genericBusinessPartner.postalAddress.addressType ?: AddressType.AdditionalAddress

val legalEntityDto = createLegalEntityRepresentation(addressPartner, addressType, genericBusinessPartner)

Expand All @@ -99,7 +99,7 @@ class CleaningServiceDummy(
fun createSiteDtoIfNeeded(businessPartner: BusinessPartnerGenericDto, addressPartner: LogisticAddressDto): SiteDto? {
if (!shouldCreateSite(businessPartner)) return null

val siteAddressReference = when (businessPartner.address.addressType) {
val siteAddressReference = when (businessPartner.postalAddress.addressType) {
AddressType.SiteMainAddress, AddressType.LegalAndSiteMainAddress -> addressPartner.bpnAReference
else -> generateNewBpnRequestIdentifier()
}
Expand All @@ -121,20 +121,20 @@ class CleaningServiceDummy(

val legalAddress = addressPartner.copy(bpnAReference = legalAddressBpnReference)

val bpnReferenceDto = createBpnReference(genericPartner.legalEntity.bpnL)
val bpnReferenceDto = createBpnReference(genericPartner.legalEntityBpn)

return genericPartner.toLegalEntityDto(bpnReferenceDto, legalAddress)

}

fun createAddressRepresentation(genericPartner: BusinessPartnerGenericDto): LogisticAddressDto {
val bpnReferenceDto = createBpnReference(genericPartner.address.bpnA)
val bpnReferenceDto = createBpnReference(genericPartner.addressBpn)
return genericPartner.toLogisticAddressDto(bpnReferenceDto)
}

fun createSiteRepresentation(genericPartner: BusinessPartnerGenericDto, siteAddressReference: LogisticAddressDto): SiteDto {
val legalName = genericPartner.nameParts.joinToString(" ")
val bpnReferenceDto = createBpnReference(genericPartner.site.bpnS)
val bpnReferenceDto = createBpnReference(genericPartner.siteBpn)
return genericPartner.toSiteDto(bpnReferenceDto, legalName, siteAddressReference)
}

Expand All @@ -150,9 +150,9 @@ class CleaningServiceDummy(
private fun generateNewBpnRequestIdentifier() = BpnReferenceDto(UUID.randomUUID().toString(), BpnReferenceType.BpnRequestIdentifier)

fun shouldCreateSite(genericPartner: BusinessPartnerGenericDto): Boolean {
return genericPartner.address.addressType == AddressType.SiteMainAddress ||
genericPartner.address.addressType == AddressType.LegalAndSiteMainAddress ||
genericPartner.site.bpnS != null
return genericPartner.postalAddress.addressType == AddressType.SiteMainAddress ||
genericPartner.postalAddress.addressType == AddressType.LegalAndSiteMainAddress ||
genericPartner.siteBpn != null
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ fun BusinessPartnerGenericDto.toLegalEntityDto(bpnReferenceDto: BpnReferenceDto,

return LegalEntityDto(
bpnLReference = bpnReferenceDto,
hasChanged = address.addressType in setOf(AddressType.LegalAddress, AddressType.LegalAndSiteMainAddress),
hasChanged = postalAddress.addressType in setOf(AddressType.LegalAddress, AddressType.LegalAndSiteMainAddress),
legalName = nameParts.joinToString(" "),
legalShortName = legalEntity.shortName,
legalShortName = shortName,
identifiers = identifiers.mapNotNull { it.toLegalEntityIdentifierDto() },
legalForm = legalEntity.legalForm,
legalForm = legalForm,
states = states.mapNotNull { it.toLegalEntityState() },
classifications = legalEntity.classifications.map { it.toLegalEntityClassificationDto() },
classifications = classifications.map { it.toLegalEntityClassificationDto() },
legalAddress = legalAddress

)
Expand Down Expand Up @@ -70,12 +70,12 @@ fun BusinessPartnerGenericDto.toLogisticAddressDto(bpnReferenceDto: BpnReference

return LogisticAddressDto(
bpnAReference = bpnReferenceDto,
hasChanged = address.addressType == AddressType.AdditionalAddress,
hasChanged = postalAddress.addressType == AddressType.AdditionalAddress,
name = nameParts.joinToString(" "),
states = emptyList(),
identifiers = emptyList(),
physicalPostalAddress = address.physicalPostalAddress,
alternativePostalAddress = address.alternativePostalAddress
physicalPostalAddress = postalAddress.physicalPostalAddress,
alternativePostalAddress = postalAddress.alternativePostalAddress
)
}

Expand All @@ -84,7 +84,7 @@ fun BusinessPartnerGenericDto.toSiteDto(bpnReferenceDto: BpnReferenceDto, legalN

return SiteDto(
bpnSReference = bpnReferenceDto,
hasChanged = address.addressType in setOf(AddressType.SiteMainAddress, AddressType.LegalAndSiteMainAddress),
hasChanged = postalAddress.addressType in setOf(AddressType.SiteMainAddress, AddressType.LegalAndSiteMainAddress),
name = legalName,
states = states.mapNotNull { it.toSiteState() },
mainAddress = siteAddressReference
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class CleaningServiceDummyTest @Autowired constructor(

val result = cleaningServiceDummy.processCleaningTask(taskStepReservationEntryDto)

val expectedBpnA = taskStepReservationEntryDto.businessPartner.generic.address.bpnA
val expectedBpnA = taskStepReservationEntryDto.businessPartner.generic.addressBpn

val resultedAddress = result.businessPartner?.address

Expand Down Expand Up @@ -112,9 +112,9 @@ class CleaningServiceDummyTest @Autowired constructor(

val result = cleaningServiceDummy.processCleaningTask(taskStepReservationEntryDto)

val expectedBpnA = taskStepReservationEntryDto.businessPartner.generic.address.bpnA
val expectedBpnA = taskStepReservationEntryDto.businessPartner.generic.addressBpn

val expectedBpnL = taskStepReservationEntryDto.businessPartner.generic.legalEntity.bpnL
val expectedBpnL = taskStepReservationEntryDto.businessPartner.generic.legalEntityBpn

val resultedAddress = result.businessPartner?.address

Expand Down Expand Up @@ -153,9 +153,9 @@ class CleaningServiceDummyTest @Autowired constructor(

val resultedSite = result.businessPartner?.site

val expectedBpnA = taskStepReservationResponse.businessPartner.generic.address.bpnA
val expectedBpnA = taskStepReservationResponse.businessPartner.generic.addressBpn

val expectedBpnS = taskStepReservationResponse.businessPartner.generic.site.bpnS
val expectedBpnS = taskStepReservationResponse.businessPartner.generic.siteBpn


// legalEntity should Generate new bpnL and legalAddress should use passed bpnA since address type is LegalAndSiteMainAddress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,77 +101,41 @@ object CommonValues {

private val businessPartnerWithEmptyBpns = BusinessPartnerGenericDto(
nameParts = nameParts,
shortName = shortName,
identifiers = identifiers,
legalForm = legalForm,
states = states,
classifications = classifications,
roles = roles,
ownerBpnL = "ownerBpnL2",
legalEntity = LegalEntityComponent(
shortName = shortName,
legalForm = legalForm,
classifications = classifications
)
ownerBpnL = "ownerBpnL2"
)


val businessPartnerWithBpnA = with(businessPartnerWithEmptyBpns) {
copy(
address = address.copy(
bpnA = "FixedBPNA",
addressType = postalAddressForAdditional.addressType,
physicalPostalAddress = postalAddressForAdditional.physicalPostalAddress,
alternativePostalAddress = postalAddressForAdditional.alternativePostalAddress
)
)
}


val businessPartnerWithBpnLAndBpnAAndLegalAddressType = with(businessPartnerWithEmptyBpns) {
copy(
address = address.copy(
bpnA = "FixedBPNA",
addressType = postalAddressForLegal.addressType,
physicalPostalAddress = postalAddressForLegal.physicalPostalAddress,
alternativePostalAddress = postalAddressForLegal.alternativePostalAddress
),
legalEntity = legalEntity.copy(
bpnL = "FixedBPNL"
)
)
}

val businessPartnerWithEmptyBpnLAndAdditionalAddressType = with(businessPartnerWithEmptyBpns) {
copy(
address = address.copy(
addressType = postalAddressForAdditional.addressType,
physicalPostalAddress = postalAddressForAdditional.physicalPostalAddress,
alternativePostalAddress = postalAddressForAdditional.alternativePostalAddress
)
)
}

val businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType = with(businessPartnerWithEmptyBpns) {
copy(
address = address.copy(
bpnA = "FixedBPNA",
addressType = postalAddressForLegalAndSite.addressType,
physicalPostalAddress = postalAddressForLegalAndSite.physicalPostalAddress,
alternativePostalAddress = postalAddressForLegalAndSite.alternativePostalAddress
),
site = site.copy(
bpnS = "FixedBPNS"
)
)
}

val businessPartnerWithEmptyBpnAndSiteMainAddressType = with(businessPartnerWithEmptyBpns) {
copy(
address = address.copy(
addressType = postalAddressForSite.addressType,
physicalPostalAddress = postalAddressForSite.physicalPostalAddress,
alternativePostalAddress = postalAddressForSite.alternativePostalAddress
)
)
}
val businessPartnerWithBpnA = businessPartnerWithEmptyBpns.copy(
postalAddress = postalAddressForAdditional,
addressBpn = "FixedBPNA"
)


val businessPartnerWithBpnLAndBpnAAndLegalAddressType = businessPartnerWithEmptyBpns.copy(
postalAddress = postalAddressForLegal,
addressBpn = "FixedBPNA",
legalEntityBpn = "FixedBPNL"
)

val businessPartnerWithEmptyBpnLAndAdditionalAddressType = businessPartnerWithEmptyBpns.copy(
postalAddress = postalAddressForAdditional,
)

val businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType = businessPartnerWithEmptyBpns.copy(
postalAddress = postalAddressForLegalAndSite,
addressBpn = "FixedBPNA",
siteBpn = "FixedBPNS"
)

val businessPartnerWithEmptyBpnAndSiteMainAddressType = businessPartnerWithEmptyBpns.copy(
postalAddress = postalAddressForSite
)

val expectedLegalEntityDto = LegalEntityDto(
hasChanged = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ import jakarta.validation.Valid
import org.eclipse.tractusx.bpdm.common.dto.BusinessPartnerType
import org.eclipse.tractusx.bpdm.common.dto.PageDto
import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest
import org.eclipse.tractusx.bpdm.gate.api.model.request.PostSharingStateReadyRequest
import org.eclipse.tractusx.bpdm.gate.api.model.response.SharingStateDto
import org.springdoc.core.annotations.ParameterObject
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.*
import org.springframework.web.service.annotation.GetExchange
import org.springframework.web.service.annotation.HttpExchange
import org.springframework.web.service.annotation.PostExchange
import org.springframework.web.service.annotation.PutExchange

@RequestMapping("/api/catena/sharing-state", produces = [MediaType.APPLICATION_JSON_VALUE])
Expand All @@ -56,6 +58,22 @@ interface GateSharingStateApi {
@Parameter(description = "External IDs") @RequestParam(required = false) externalIds: Collection<String>?
): PageDto<SharingStateDto>

@Operation(
summary = "Sets the given business partners into ready to be shared state",
description = "The business partners to set the ready state for are identified by their external-id. Only business partners in an initial or error state can be set to ready. If any given business partner could not be set into ready state for any reason (for example, it has not been found or it is in the wrong state) the whole request fails (all or nothing approach)."
)
@ApiResponses(
value = [
ApiResponse(responseCode = "204", description = "All business partners put in ready to be shared state"),
ApiResponse(responseCode = "404", description = "Business partners can't be put into ready state (e.g. external-ID not found, wrong sharing state)")
]
)
@PostMapping
@PostExchange
fun postSharingStateReady(@RequestBody request: PostSharingStateReadyRequest)



@Operation(
summary = "Creates or updates a sharing state of a business partner",
deprecated = true
Expand All @@ -69,4 +87,6 @@ interface GateSharingStateApi {
@PutMapping
@PutExchange
fun upsertSharingState(@RequestBody request: SharingStateDto)


}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ enum class SharingStateType {
Pending,
Success,
Error,
Initial
Initial,
Ready
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2021,2023 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.gate.api.model.request

import io.swagger.v3.oas.annotations.media.Schema

@Schema(description = "Request for setting business partners into ready to be shared to golden record state")
data class PostSharingStateReadyRequest(
val externalIds: List<String>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2021,2023 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.gate.config

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.stereotype.Component

@Component
@ConfigurationProperties(prefix = "bpdm.tasks")
data class GoldenRecordTaskConfigProperties(
val creation: CreationProperties = CreationProperties(),
val check: TaskProcessProperties = TaskProcessProperties()
) {
data class CreationProperties(
val fromSharingMember: TaskProcessProperties = TaskProcessProperties(),
val fromPool: TaskProcessProperties = TaskProcessProperties()
)

data class TaskProcessProperties(
var batchSize: Int = 100,
var cron: String = "-",
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import org.eclipse.tractusx.bpdm.common.dto.BusinessPartnerType
import org.eclipse.tractusx.bpdm.common.dto.PageDto
import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest
import org.eclipse.tractusx.bpdm.gate.api.GateSharingStateApi
import org.eclipse.tractusx.bpdm.gate.api.model.request.PostSharingStateReadyRequest
import org.eclipse.tractusx.bpdm.gate.api.model.response.SharingStateDto
import org.eclipse.tractusx.bpdm.gate.service.SharingStateService
import org.springframework.security.access.prepost.PreAuthorize
Expand All @@ -44,6 +45,10 @@ class SharingStateController(
return sharingStateService.findSharingStates(paginationRequest, businessPartnerType, externalIds)
}

override fun postSharingStateReady(request: PostSharingStateReadyRequest) {
sharingStateService.setReady(request.externalIds)
}

@PreAuthorize("hasAuthority(@gateSecurityConfigProperties.getChangeCompanyOutputDataAsRole())")
override fun upsertSharingState(request: SharingStateDto) {
logger.info { "upsertSharingState() called with $request" }
Expand Down
Loading

0 comments on commit 1835ac5

Please sign in to comment.