diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/config/GoldenRecordTaskConfiguration.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/config/GoldenRecordTaskConfiguration.kt index 68ff12d9c..b52416f24 100644 --- a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/config/GoldenRecordTaskConfiguration.kt +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/config/GoldenRecordTaskConfiguration.kt @@ -21,6 +21,7 @@ package org.eclipse.tractusx.bpdm.gate.config import jakarta.annotation.PostConstruct import org.eclipse.tractusx.bpdm.gate.service.GoldenRecordTaskService +import org.eclipse.tractusx.bpdm.gate.service.GoldenRecordUpdateService import org.springframework.context.annotation.Configuration import org.springframework.scheduling.TaskScheduler import org.springframework.scheduling.support.CronTrigger @@ -29,23 +30,24 @@ import org.springframework.scheduling.support.CronTrigger class GoldenRecordTaskConfiguration( private val configProperties: GoldenRecordTaskConfigProperties, private val taskScheduler: TaskScheduler, - private val service: GoldenRecordTaskService + private val taskService: GoldenRecordTaskService, + private val updateService: GoldenRecordUpdateService ) { @PostConstruct fun scheduleGoldenRecordTasks() { taskScheduler.scheduleIfEnabled( - { service.createTasksForReadyBusinessPartners() }, + { taskService.createTasksForReadyBusinessPartners() }, configProperties.creation.fromSharingMember.cron ) taskScheduler.scheduleIfEnabled( - { service.createTasksForGoldenRecordUpdates() }, + { updateService.updateOutputOnGoldenRecordChange() }, configProperties.creation.fromPool.cron ) taskScheduler.scheduleIfEnabled( - { service.resolvePendingTasks() }, + { taskService.resolvePendingTasks() }, configProperties.check.cron ) } diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/ConfidenceCriteriaDb.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/ConfidenceCriteriaDb.kt index 8b29547d8..1a51e4cec 100644 --- a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/ConfidenceCriteriaDb.kt +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/ConfidenceCriteriaDb.kt @@ -30,15 +30,15 @@ import java.time.LocalDateTime @Table(name = "confidence_criteria") class ConfidenceCriteriaDb( @Column(name = "shared_by_owner", nullable = false) - val sharedByOwner: Boolean, + var sharedByOwner: Boolean, @Column(name = "checked_by_external_data_source", nullable = false) - val checkedByExternalDataSource: Boolean, + var checkedByExternalDataSource: Boolean, @Column(name = "number_of_business_partners", nullable = false) - val numberOfBusinessPartners: Int, + var numberOfBusinessPartners: Int, @Column(name = "last_confidence_check_at", nullable = false) - val lastConfidenceCheckAt: LocalDateTime, + var lastConfidenceCheckAt: LocalDateTime, @Column(name = "next_confidence_check_at", nullable = false) - val nextConfidenceCheckAt: LocalDateTime, + var nextConfidenceCheckAt: LocalDateTime, @Column(name = "confidence_level", nullable = false) - val confidenceLevel: Int, + var confidenceLevel: Int, ) : BaseEntity() \ No newline at end of file diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/IdentifierDb.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/IdentifierDb.kt index f76714ff8..28ea4c3f0 100644 --- a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/IdentifierDb.kt +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/IdentifierDb.kt @@ -21,6 +21,9 @@ package org.eclipse.tractusx.bpdm.gate.entity.generic import jakarta.persistence.Column import jakarta.persistence.Embeddable +import jakarta.persistence.EnumType +import jakarta.persistence.Enumerated +import org.eclipse.tractusx.bpdm.common.dto.BusinessPartnerType @Embeddable @@ -33,7 +36,11 @@ data class IdentifierDb( var value: String, @Column(name = "issuing_body") - var issuingBody: String? + var issuingBody: String?, + + @Enumerated(EnumType.STRING) + @Column(name = "business_partner_type", nullable = false) + var businessPartnerType: BusinessPartnerType ) : Comparable { @@ -41,6 +48,7 @@ data class IdentifierDb( override fun compareTo(other: IdentifierDb) = compareBy( IdentifierDb::type, IdentifierDb::value, - IdentifierDb::issuingBody + IdentifierDb::issuingBody, + IdentifierDb::businessPartnerType ).compare(this, other) } diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/repository/generic/BusinessPartnerRepository.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/repository/generic/BusinessPartnerRepository.kt index 9636334da..14e317c31 100644 --- a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/repository/generic/BusinessPartnerRepository.kt +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/repository/generic/BusinessPartnerRepository.kt @@ -28,6 +28,7 @@ import org.springframework.data.jpa.repository.Query import org.springframework.data.repository.CrudRepository import org.springframework.data.repository.query.Param import org.springframework.stereotype.Repository +import java.time.Instant @Repository @@ -50,6 +51,10 @@ interface BusinessPartnerRepository : JpaRepository, Cr @Query("SELECT b.stage as stage, COUNT(b.stage) as count FROM BusinessPartnerDb AS b GROUP BY b.stage") fun countPerStages(): List + fun findByStageAndBpnLIn(stage: StageType, bpnL: Collection): Set + fun findByStageAndBpnSIn(stage: StageType, bpnS: Collection): Set + fun findByStageAndBpnAIn(stage: StageType, bpnA: Collection): Set + interface PartnersPerStageCount { val stage: StageType val count: Int diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/BusinessPartnerMappings.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/BusinessPartnerMappings.kt index e216cdf09..4e6e6689d 100644 --- a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/BusinessPartnerMappings.kt +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/BusinessPartnerMappings.kt @@ -76,7 +76,7 @@ class BusinessPartnerMappings { externalId = dto.externalId, nameParts = dto.nameParts.toMutableList(), roles = dto.roles.toSortedSet(), - identifiers = dto.identifiers.mapNotNull(::toIdentifier).toSortedSet(), + identifiers = dto.identifiers.mapNotNull{toIdentifier(it, BusinessPartnerType.GENERIC)}.toSortedSet(), states = dto.states.asSequence().mapNotNull{toState(it, BusinessPartnerType.GENERIC)} .plus(dto.legalEntity.states.mapNotNull { toState(it, BusinessPartnerType.LEGAL_ENTITY) }) .plus(dto.site.states.mapNotNull { toState(it, BusinessPartnerType.SITE) }) @@ -284,10 +284,10 @@ class BusinessPartnerMappings { private fun toIdentifierDto(entity: IdentifierDb) = BusinessPartnerIdentifierDto(type = entity.type, value = entity.value, issuingBody = entity.issuingBody) - private fun toIdentifier(dto: BusinessPartnerIdentifierDto) = + private fun toIdentifier(dto: BusinessPartnerIdentifierDto, businessPartnerType: BusinessPartnerType) = dto.type?.let { type -> dto.value?.let { value -> - IdentifierDb(type = type, value = value, issuingBody = dto.issuingBody) + IdentifierDb(type = type, value = value, issuingBody = dto.issuingBody, businessPartnerType) } } diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/BusinessPartnerService.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/BusinessPartnerService.kt index fddf31328..214d9a769 100644 --- a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/BusinessPartnerService.kt +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/BusinessPartnerService.kt @@ -36,6 +36,8 @@ import org.eclipse.tractusx.bpdm.gate.exception.BpdmMissingStageException import org.eclipse.tractusx.bpdm.gate.repository.ChangelogRepository import org.eclipse.tractusx.bpdm.gate.repository.SharingStateRepository import org.eclipse.tractusx.bpdm.gate.repository.generic.BusinessPartnerRepository +import org.eclipse.tractusx.bpdm.gate.util.BusinessPartnerComparisonUtil +import org.eclipse.tractusx.bpdm.gate.util.BusinessPartnerCopyUtil import org.eclipse.tractusx.orchestrator.api.client.OrchestrationApiClient import org.eclipse.tractusx.orchestrator.api.model.TaskCreateRequest import org.eclipse.tractusx.orchestrator.api.model.TaskCreateResponse @@ -53,6 +55,8 @@ class BusinessPartnerService( private val sharingStateService: SharingStateService, private val changelogRepository: ChangelogRepository, private val sharingStateRepository: SharingStateRepository, + private val copyUtil: BusinessPartnerCopyUtil, + private val compareUtil: BusinessPartnerComparisonUtil ) { private val logger = KotlinLogging.logger { } @@ -182,38 +186,10 @@ class BusinessPartnerService( val matchingBusinessPartner = persistedBusinessPartnerMap[entity.externalId] val hasErrorSharingState = sharingStatesMap[entity.externalId]?.sharingStateType == SharingStateType.Error - matchingBusinessPartner?.let { hasChanges(entity, it) } ?: true || hasErrorSharingState //If there are difference return true, else returns false + matchingBusinessPartner?.let { compareUtil.hasChanges(entity, it) } ?: true || hasErrorSharingState //If there are difference return true, else returns false } } - private fun hasChanges(entity: BusinessPartnerDb, persistedBP: BusinessPartnerDb): Boolean { - - return entity.nameParts != persistedBP.nameParts || - entity.roles != persistedBP.roles || - entity.shortName != persistedBP.shortName || - entity.legalName != persistedBP.legalName || - entity.siteName != persistedBP.siteName || - entity.addressName != persistedBP.addressName || - entity.legalForm != persistedBP.legalForm || - entity.isOwnCompanyData != persistedBP.isOwnCompanyData || - entity.bpnL != persistedBP.bpnL || - entity.bpnS != persistedBP.bpnS || - entity.bpnA != persistedBP.bpnA || - entity.stage != persistedBP.stage || - entity.parentId != persistedBP.parentId || - entity.parentType != persistedBP.parentType || - entity.identifiers != persistedBP.identifiers || - entity.states != persistedBP.states || - entity.classifications != persistedBP.classifications || - postalAddressHasChanges(entity.postalAddress, persistedBP.postalAddress) - } - - private fun postalAddressHasChanges(entityPostalAddress: PostalAddressDb, persistedPostalAddress: PostalAddressDb): Boolean { - return (entityPostalAddress.addressType != persistedPostalAddress.addressType) || - (entityPostalAddress.alternativePostalAddress != persistedPostalAddress.alternativePostalAddress) || - (entityPostalAddress.physicalPostalAddress != persistedPostalAddress.physicalPostalAddress) - } - /** * Resolve all [entityCandidates] by looking for existing business partner data in the given [stage] * @@ -227,70 +203,12 @@ class BusinessPartnerService( return entityCandidates.map { candidate -> val existingEntity = existingPartnersByExternalId[candidate.externalId] if (existingEntity != null) - ResolutionResult(copyValues(candidate, existingEntity), true) + ResolutionResult(copyUtil.copyValues(candidate, existingEntity), true) else ResolutionResult(candidate, false) } } - private fun copyValues(fromPartner: BusinessPartnerDb, toPartner: BusinessPartnerDb): BusinessPartnerDb { - return toPartner.apply { - stage = fromPartner.stage - shortName = fromPartner.shortName - legalName = fromPartner.legalName - siteName = fromPartner.siteName - addressName = fromPartner.addressName - legalForm = fromPartner.legalForm - isOwnCompanyData = fromPartner.isOwnCompanyData - bpnL = fromPartner.bpnL - bpnS = fromPartner.bpnS - bpnA = fromPartner.bpnA - parentId = fromPartner.parentId - parentType = fromPartner.parentType - legalEntityConfidence = fromPartner.legalEntityConfidence - siteConfidence = fromPartner.siteConfidence - addressConfidence = fromPartner.addressConfidence - - nameParts.replace(fromPartner.nameParts) - roles.replace(fromPartner.roles) - - states.copyAndSync(fromPartner.states, ::copyValues) - classifications.copyAndSync(fromPartner.classifications, ::copyValues) - identifiers.copyAndSync(fromPartner.identifiers, ::copyValues) - - copyValues(fromPartner.postalAddress, postalAddress) - } - } - - private fun copyValues(fromState: StateDb, toState: StateDb) = - toState.apply { - validFrom = fromState.validFrom - validTo = fromState.validTo - type = fromState.type - } - - private fun copyValues(fromClassification: ClassificationDb, toClassification: ClassificationDb) = - toClassification.apply { - value = fromClassification.value - type = fromClassification.type - code = fromClassification.code - } - - private fun copyValues(fromIdentifier: IdentifierDb, toIdentifier: IdentifierDb) = - toIdentifier.apply { - type = fromIdentifier.type - value = fromIdentifier.value - issuingBody = fromIdentifier.issuingBody - } - - private fun copyValues(fromPostalAddress: PostalAddressDb, toPostalAddress: PostalAddressDb) = - toPostalAddress.apply { - addressType = fromPostalAddress.addressType - physicalPostalAddress = fromPostalAddress.physicalPostalAddress - alternativePostalAddress = fromPostalAddress.alternativePostalAddress - } - - } data class ResolutionResult( diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/GoldenRecordTaskService.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/GoldenRecordTaskService.kt index adfc6af04..7e51a932f 100644 --- a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/GoldenRecordTaskService.kt +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/GoldenRecordTaskService.kt @@ -48,9 +48,7 @@ class GoldenRecordTaskService( private val businessPartnerService: BusinessPartnerService, private val orchestratorMappings: OrchestratorMappings, private val orchestrationApiClient: OrchestrationApiClient, - private val properties: GoldenRecordTaskConfigProperties, - private val syncRecordService: SyncRecordService, - private val poolClient: PoolApiClient + private val properties: GoldenRecordTaskConfigProperties ) { private val logger = KotlinLogging.logger { } @@ -102,50 +100,6 @@ class GoldenRecordTaskService( } } - @Transactional - fun createTasksForGoldenRecordUpdates() { - logger.info { "Started scheduled task to create golden record tasks from Pool updates" } - - val syncRecord = syncRecordService.getOrCreateRecord(SyncTypeDb.POOL_TO_GATE_OUTPUT) - - val pageRequest = PaginationRequest(0, properties.creation.fromPool.batchSize) - val changelogSearchRequest = ChangelogSearchRequest(syncRecord.finishedAt) - val poolChangelogEntries = poolClient.changelogs.getChangelogEntries(changelogSearchRequest, pageRequest) - - val poolUpdatedEntries = poolChangelogEntries.content.filter { it.changelogType == ChangelogType.UPDATE } - - val bpnA = - poolUpdatedEntries.filter { it.businessPartnerType == BusinessPartnerType.ADDRESS }.map { it.bpn } - val bpnL = poolUpdatedEntries.filter { it.businessPartnerType == BusinessPartnerType.LEGAL_ENTITY } - .map { it.bpn } - val bpnS = - poolUpdatedEntries.filter { it.businessPartnerType == BusinessPartnerType.SITE }.map { it.bpn } - - val gateOutputEntries = businessPartnerRepository.findByStageAndBpnLInOrBpnSInOrBpnAIn(StageType.Output, bpnL, bpnS, bpnA) - - val businessPartnerGenericDtoList = gateOutputEntries.map { bp -> - orchestratorMappings.toOrchestratorDto(bp) - } - - val tasks = createGoldenRecordTasks(TaskMode.UpdateFromPool, businessPartnerGenericDtoList) - - val pendingRequests = gateOutputEntries.zip(tasks) - .map { (partner, task) -> - SharingStateService.PendingRequest( - partner.externalId, - task.taskId - ) - } - sharingStateService.setPending(pendingRequests, null) - - if (poolUpdatedEntries.isNotEmpty()) { - syncRecordService.setSynchronizationStart(SyncTypeDb.POOL_TO_GATE_OUTPUT) - syncRecordService.setSynchronizationSuccess(SyncTypeDb.POOL_TO_GATE_OUTPUT, poolUpdatedEntries.last().timestamp) - } - - logger.info { "Created ${tasks.size} new golden record tasks from pool updates" } - } - private fun createGoldenRecordTasks(mode: TaskMode, orchestratorBusinessPartnersDto: List): List { if (orchestratorBusinessPartnersDto.isEmpty()) return emptyList() diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/GoldenRecordUpdateService.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/GoldenRecordUpdateService.kt new file mode 100644 index 000000000..0404d62eb --- /dev/null +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/GoldenRecordUpdateService.kt @@ -0,0 +1,306 @@ +/******************************************************************************* + * 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.gate.service + +import com.nimbusds.oauth2.sdk.id.Identifier +import jakarta.persistence.Column +import mu.KotlinLogging +import org.eclipse.tractusx.bpdm.common.dto.BusinessPartnerType +import org.eclipse.tractusx.bpdm.common.dto.IBaseStateDto +import org.eclipse.tractusx.bpdm.common.dto.PaginationRequest +import org.eclipse.tractusx.bpdm.common.model.BusinessStateType +import org.eclipse.tractusx.bpdm.common.model.StageType +import org.eclipse.tractusx.bpdm.gate.api.model.ChangelogType +import org.eclipse.tractusx.bpdm.gate.config.GoldenRecordTaskConfigProperties +import org.eclipse.tractusx.bpdm.gate.entity.* +import org.eclipse.tractusx.bpdm.gate.entity.generic.* +import org.eclipse.tractusx.bpdm.gate.repository.ChangelogRepository +import org.eclipse.tractusx.bpdm.gate.repository.generic.BusinessPartnerRepository +import org.eclipse.tractusx.bpdm.gate.util.BusinessPartnerComparisonUtil +import org.eclipse.tractusx.bpdm.gate.util.BusinessPartnerCopyUtil +import org.eclipse.tractusx.bpdm.pool.api.client.PoolApiClient +import org.eclipse.tractusx.bpdm.pool.api.model.* +import org.eclipse.tractusx.bpdm.pool.api.model.request.AddressSearchRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.ChangelogSearchRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.LegalEntitySearchRequest +import org.eclipse.tractusx.bpdm.pool.api.model.request.SiteSearchRequest +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import java.time.LocalDateTime + +@Service +class GoldenRecordUpdateService( + private val poolClient: PoolApiClient, + private val syncRecordService: SyncRecordService, + private val taskConfigProperties: GoldenRecordTaskConfigProperties, + private val businessPartnerRepository: BusinessPartnerRepository, + private val changelogRepository: ChangelogRepository, + private val copyUtil: BusinessPartnerCopyUtil, + private val compareUtil: BusinessPartnerComparisonUtil +) { + + private val logger = KotlinLogging.logger { } + + @Transactional + fun updateOutputOnGoldenRecordChange(){ + logger.info { "Update Business Partner Output based on Golden Record Updates from the Pool..." } + + val syncRecord = syncRecordService.setSynchronizationStart(SyncTypeDb.POOL_TO_GATE_OUTPUT) + + val changelogSearchRequest = ChangelogSearchRequest(timestampAfter = syncRecord.fromTime) + val pageRequest = PaginationRequest(0, taskConfigProperties.creation.fromPool.batchSize) + val poolChangelogEntries = poolClient.changelogs.getChangelogEntries(changelogSearchRequest, pageRequest) + + val changelogByType = poolChangelogEntries.content.groupBy { it.businessPartnerType } + val changedBpnAs = changelogByType[BusinessPartnerType.ADDRESS]?.map { it.bpn } ?: emptyList() + val changedBpnSs = changelogByType[BusinessPartnerType.SITE]?.map { it.bpn } ?: emptyList() + val changedBpnLs = changelogByType[BusinessPartnerType.LEGAL_ENTITY]?.map { it.bpn } ?: emptyList() + + logger.debug { "Found ${changedBpnLs.size} BPNL, ${changedBpnSs.size} BPNS and ${changedBpnAs.size} BPNA entries." } + + updateLegalEntities(changedBpnLs) + updateSites(changedBpnSs) + updateAddresses(changedBpnAs) + + syncRecordService.setSynchronizationSuccess(SyncTypeDb.POOL_TO_GATE_OUTPUT) + } + + private fun updateLegalEntities(changedBpnLs: Collection){ + val businessPartnersToUpdate = businessPartnerRepository.findByStageAndBpnLIn(StageType.Output, changedBpnLs) + + logger.debug { "Found ${businessPartnersToUpdate.size} business partners with matching BPNL to update." } + + val bpnLsToQuery = businessPartnersToUpdate.mapNotNull { it.bpnL } + + val searchRequest = LegalEntitySearchRequest(bpnLs = bpnLsToQuery) + val legalEntities = if(searchRequest.bpnLs.isNotEmpty()) + poolClient.legalEntities.getLegalEntities(searchRequest, PaginationRequest(size = searchRequest.bpnLs.size)).content + else + emptyList() + + + val legalEntitiesByBpn = legalEntities.associateBy { it.legalEntity.bpnl } + + val updatedPartners = businessPartnersToUpdate.mapNotNull { partner -> + legalEntitiesByBpn[partner.bpnL]?.legalEntity?.let { legalEntity -> partner.apply { update(partner, legalEntity) } } + } + + logger.debug { "Updating ${updatedPartners.size} business partners from legal entities" } + + val changedPartners = filterChanged(updatedPartners) + + businessPartnerRepository.saveAll(changedPartners) + + val changelogs = changedPartners.map { ChangelogEntryDb(it.externalId, it.associatedOwnerBpnl, ChangelogType.UPDATE, StageType.Output) } + changelogRepository.saveAll(changelogs) + + logger.debug { "Actual values changed of ${changedPartners.size} business partners from legal entities" } + } + + private fun updateSites(changedSiteBpns: Collection){ + val businessPartnersToUpdate = businessPartnerRepository.findByStageAndBpnSIn(StageType.Output, changedSiteBpns) + + logger.debug { "Found ${businessPartnersToUpdate.size} business partners with matching BPNS to update." } + + val siteBpnsToQuery = businessPartnersToUpdate.mapNotNull { it.bpnS } + + val searchRequest = SiteSearchRequest(siteBpns = siteBpnsToQuery) + val sites = if(searchRequest.siteBpns.isNotEmpty()) + poolClient.sites.getSites(searchRequest, PaginationRequest(size = searchRequest.siteBpns.size)).content + else + emptyList() + + val sitesByBpn = sites.associateBy { it.site.bpns } + + + val updatedPartners = businessPartnersToUpdate.mapNotNull { partner -> + sitesByBpn[partner.bpnS]?.site?.let { site -> partner.apply { update(partner, site) } } + } + + logger.debug { "Updating ${updatedPartners.size} business partners from sites" } + + + val changedPartners = filterChanged(updatedPartners) + + businessPartnerRepository.saveAll(changedPartners) + + val changelogs = changedPartners.map { ChangelogEntryDb(it.externalId, it.associatedOwnerBpnl, ChangelogType.UPDATE, StageType.Output) } + changelogRepository.saveAll(changelogs) + + logger.debug { "Actual values changed of ${changedPartners.size} business partners from sites" } + } + + private fun updateAddresses(changedAddressBpns: Collection){ + val businessPartnersToUpdate = businessPartnerRepository.findByStageAndBpnAIn(StageType.Output, changedAddressBpns) + + logger.debug { "Found ${businessPartnersToUpdate.size} business partners with matching BPNA to update." } + + val addressBpnsToQuery = businessPartnersToUpdate.mapNotNull { it.bpnA } + + val searchRequest = AddressSearchRequest(addressBpns = addressBpnsToQuery) + val addresses = if(searchRequest.addressBpns.isNotEmpty()) + poolClient.addresses.getAddresses(searchRequest, PaginationRequest(size = searchRequest.addressBpns.size)).content + else + emptyList() + + val addressesByBpn = addresses.associateBy { it.bpna } + + val updatedPartners = businessPartnersToUpdate.mapNotNull { partner -> + addressesByBpn[partner.bpnA]?.let { address -> partner.apply { update(partner, address) } } + } + + logger.debug { "Updating ${updatedPartners.size} business partners from logistic addresses" } + + val changedPartners = filterChanged(updatedPartners) + + businessPartnerRepository.saveAll(changedPartners) + + val changelogs = changedPartners.map { ChangelogEntryDb(it.externalId, it.associatedOwnerBpnl, ChangelogType.UPDATE, StageType.Output) } + changelogRepository.saveAll(changelogs) + + logger.debug { "Actual values changed of ${changedPartners.size} business partners from logistic addresses" } + } + + private fun update(businessPartner: BusinessPartnerDb, legalEntity: LegalEntityVerboseDto){ + updateIdentifiers(businessPartner.identifiers, legalEntity.identifiers.map(::toEntity), BusinessPartnerType.LEGAL_ENTITY) + updateStates(businessPartner.states, legalEntity.states, BusinessPartnerType.LEGAL_ENTITY) + businessPartner.legalName = legalEntity.legalName + businessPartner.legalForm = legalEntity.legalForm + businessPartner.legalEntityConfidence?.let { update(it, legalEntity.confidenceCriteria) } + } + + private fun update(businessPartner: BusinessPartnerDb, site: SiteVerboseDto){ + updateStates(businessPartner.states, site.states, BusinessPartnerType.SITE) + businessPartner.siteName = site.name + businessPartner.siteConfidence?.let { update(it, site.confidenceCriteria) } + } + + private fun update(businessPartner: BusinessPartnerDb, address: LogisticAddressVerboseDto){ + updateIdentifiers(businessPartner.identifiers, address.identifiers.map(::toEntity), BusinessPartnerType.ADDRESS) + updateStates(businessPartner.states, address.states, BusinessPartnerType.ADDRESS) + businessPartner.addressName = address.name + businessPartner.postalAddress.physicalPostalAddress = address.physicalPostalAddress.toEntity() + businessPartner.postalAddress.alternativePostalAddress = address.alternativePostalAddress?.toEntity() + businessPartner.addressConfidence?.let { update(it, address.confidenceCriteria) } + } + + private fun update(entity: ConfidenceCriteriaDb, poolDto: ConfidenceCriteriaDto){ + entity.sharedByOwner = poolDto.sharedByOwner + entity.checkedByExternalDataSource = poolDto.checkedByExternalDataSource + entity.numberOfBusinessPartners = poolDto.numberOfSharingMembers + entity.lastConfidenceCheckAt = poolDto.lastConfidenceCheckAt + entity.nextConfidenceCheckAt = poolDto.nextConfidenceCheckAt + entity.confidenceLevel = poolDto.confidenceLevel + } + + private fun updateIdentifiers(entities: MutableCollection, updatedIdentifiers: Collection, businessPartnerType: BusinessPartnerType){ + entities.removeIf{ it.businessPartnerType == businessPartnerType } + entities.addAll(updatedIdentifiers) + } + + private fun updateStates(entities: MutableCollection, poolDtos: Collection, businessPartnerType: BusinessPartnerType){ + entities.removeIf{ it.businessPartnerTyp == businessPartnerType } + entities.addAll(poolDtos.map{ toEntity(it, businessPartnerType) }) + } + + private fun toEntity(poolDto: LegalEntityIdentifierVerboseDto) = + IdentifierDb( + poolDto.type, + poolDto.value, + poolDto.issuingBody, + BusinessPartnerType.LEGAL_ENTITY + ) + + private fun toEntity(poolDto: AddressIdentifierVerboseDto) = + IdentifierDb( + type = poolDto.type, + value = poolDto.value, + issuingBody = null, + businessPartnerType = BusinessPartnerType.ADDRESS + ) + + private fun toEntity(poolDto: IBaseStateDto, businessPartnerType: BusinessPartnerType) = + StateDb( + validFrom = poolDto.validFrom, + validTo = poolDto.validTo, + type = poolDto.type!!, + businessPartnerTyp = businessPartnerType + ) + + private fun PhysicalPostalAddressVerboseDto.toEntity() = + PhysicalPostalAddressDb( + geographicCoordinates = geographicCoordinates?.let { GeographicCoordinateDb(it.latitude, it.longitude, it.altitude) }, + country = country, + administrativeAreaLevel1 = administrativeAreaLevel1, + administrativeAreaLevel2 = administrativeAreaLevel2, + administrativeAreaLevel3 = administrativeAreaLevel3, + postalCode = postalCode, + city = city, + district = district, + street = street?.toEntity(), + companyPostalCode = companyPostalCode, + industrialZone = industrialZone, + building = building, + floor = floor, + door = door + ) + + private fun StreetDto.toEntity() = + StreetDb( + name, + houseNumber, + houseNumberSupplement, + milestone, + direction, + namePrefix, + additionalNamePrefix, + nameSuffix, + additionalNameSuffix + ) + + private fun AlternativePostalAddressVerboseDto.toEntity() = + AlternativePostalAddressDb( + geographicCoordinates = geographicCoordinates?.let { GeographicCoordinateDb(it.latitude, it.longitude, it.altitude) }, + country = country, + administrativeAreaLevel1 = administrativeAreaLevel1, + postalCode = postalCode, + city = city, + deliveryServiceType = deliveryServiceType, + deliveryServiceQualifier = deliveryServiceQualifier, + deliveryServiceNumber = deliveryServiceNumber + ) + + private fun emptyBusinessPartner(externalId: String) = + BusinessPartnerDb( + externalId = externalId, + stage = StageType.Output, + legalEntityConfidence = null, + siteConfidence = null, + addressConfidence = null, + postalAddress = PostalAddressDb() + ) + + private fun filterChanged(partners: Collection): Collection{ + return partners.associateWith { partner -> emptyBusinessPartner(partner.externalId).apply { copyUtil.copyValues( partner, this) } } + .filter { (partner, copy) -> compareUtil.hasChanges(partner, copy) } + .keys + } + +} \ No newline at end of file diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/OrchestratorMappings.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/OrchestratorMappings.kt index 19b4f7f83..92715e098 100644 --- a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/OrchestratorMappings.kt +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/service/OrchestratorMappings.kt @@ -51,7 +51,7 @@ class OrchestratorMappings( nameParts = emptyList(), uncategorized = UncategorizedProperties( nameParts = entity.nameParts, - identifiers = entity.identifiers.map { Identifier(it.value, it.type, it.issuingBody) }, + identifiers = entity.identifiers.filter { it.businessPartnerType == BusinessPartnerType.GENERIC }.map { Identifier(it.value, it.type, it.issuingBody) }, states = entity.states.filter { it.businessPartnerTyp == BusinessPartnerType.GENERIC }.map { toState(it) }, address = postalAddress.takeIf { entity.postalAddress.addressType == null } ), @@ -61,7 +61,7 @@ class OrchestratorMappings( legalName = entity.legalName, legalForm = entity.legalForm, legalShortName = entity.shortName, - identifiers = emptyList(), + identifiers = entity.identifiers.filter { it.businessPartnerType == BusinessPartnerType.LEGAL_ENTITY }.map { Identifier(it.value, it.type, it.issuingBody) }, states = entity.states.filter { it.businessPartnerTyp == BusinessPartnerType.LEGAL_ENTITY }.map { toState(it) }, confidenceCriteria = toConfidenceCriteria(entity.legalEntityConfidence), isCatenaXMemberData = null, @@ -84,7 +84,7 @@ class OrchestratorMappings( return PostalAddress( bpnReference = toBpnReference(entity.bpnA), addressName = entity.addressName, - identifiers = emptyList(), + identifiers = entity.identifiers.filter { it.businessPartnerType == BusinessPartnerType.ADDRESS }.map { Identifier(it.value, it.type, it.issuingBody) }, states = entity.states.filter { it.businessPartnerTyp == BusinessPartnerType.ADDRESS }.map { toState(it) }, confidenceCriteria = toConfidenceCriteria(entity.addressConfidence), physicalAddress = entity.postalAddress.physicalPostalAddress?.let { @@ -210,10 +210,10 @@ class OrchestratorMappings( externalId = externalId, nameParts = uncategorized.nameParts.toMutableList(), shortName = legalEntity.legalShortName, - identifiers = uncategorized.identifiers - .plus(legalEntity.identifiers) - .plus(postalAddress.identifiers) - .mapNotNull { toIdentifier(it) }.toSortedSet(), + identifiers = uncategorized.identifiers.mapNotNull { toIdentifier(it, BusinessPartnerType.GENERIC) } + .plus(legalEntity.identifiers.mapNotNull { toIdentifier(it, BusinessPartnerType.LEGAL_ENTITY) }) + .plus(postalAddress.identifiers.mapNotNull { toIdentifier(it, BusinessPartnerType.ADDRESS) }) + .toSortedSet(), legalName = legalEntity.legalName, siteName = site?.siteName, addressName = postalAddress.addressName, @@ -233,19 +233,19 @@ class OrchestratorMappings( bpnS = site?.bpnReference?.referenceValue, bpnA = postalAddress.bpnReference.referenceValue!!, stage = StageType.Output, - legalEntityConfidence = legalEntity.confidenceCriteria?.let { toConfidenceCriteria(it) }, - siteConfidence = site?.confidenceCriteria?.let { toConfidenceCriteria(it) }, - addressConfidence = postalAddress.confidenceCriteria?.let { toConfidenceCriteria(it) }, + legalEntityConfidence = toConfidenceCriteria(legalEntity.confidenceCriteria), + siteConfidence = site?.let { toConfidenceCriteria(it.confidenceCriteria) }, + addressConfidence = toConfidenceCriteria(postalAddress.confidenceCriteria), associatedOwnerBpnl = associatedOwnerBpnl ) } } - private fun toIdentifier(dto: Identifier) = + private fun toIdentifier(dto: Identifier, businessPartnerType: BusinessPartnerType) = dto.type?.let { type -> dto.value?.let { value -> - IdentifierDb(type = type, value = value, issuingBody = dto.issuingBody) + IdentifierDb(type = type, value = value, issuingBody = dto.issuingBody, businessPartnerType = businessPartnerType) } } diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/util/BusinessPartnerComparisonUtil.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/util/BusinessPartnerComparisonUtil.kt new file mode 100644 index 000000000..699ef1fef --- /dev/null +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/util/BusinessPartnerComparisonUtil.kt @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.gate.util + +import org.eclipse.tractusx.bpdm.gate.entity.generic.BusinessPartnerDb +import org.eclipse.tractusx.bpdm.gate.entity.generic.PostalAddressDb +import org.springframework.stereotype.Component + +@Component +class BusinessPartnerComparisonUtil { + + fun hasChanges(entity: BusinessPartnerDb, persistedBP: BusinessPartnerDb): Boolean { + + return entity.nameParts != persistedBP.nameParts || + entity.roles != persistedBP.roles || + entity.shortName != persistedBP.shortName || + entity.legalName != persistedBP.legalName || + entity.siteName != persistedBP.siteName || + entity.addressName != persistedBP.addressName || + entity.legalForm != persistedBP.legalForm || + entity.isOwnCompanyData != persistedBP.isOwnCompanyData || + entity.bpnL != persistedBP.bpnL || + entity.bpnS != persistedBP.bpnS || + entity.bpnA != persistedBP.bpnA || + entity.stage != persistedBP.stage || + entity.parentId != persistedBP.parentId || + entity.parentType != persistedBP.parentType || + entity.identifiers != persistedBP.identifiers || + entity.states != persistedBP.states || + entity.classifications != persistedBP.classifications || + postalAddressHasChanges(entity.postalAddress, persistedBP.postalAddress) + } + + private fun postalAddressHasChanges(entityPostalAddress: PostalAddressDb, persistedPostalAddress: PostalAddressDb): Boolean { + return (entityPostalAddress.addressType != persistedPostalAddress.addressType) || + (entityPostalAddress.alternativePostalAddress != persistedPostalAddress.alternativePostalAddress) || + (entityPostalAddress.physicalPostalAddress != persistedPostalAddress.physicalPostalAddress) + } +} \ No newline at end of file diff --git a/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/util/BusinessPartnerCopyUtil.kt b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/util/BusinessPartnerCopyUtil.kt new file mode 100644 index 000000000..542eb1d2b --- /dev/null +++ b/bpdm-gate/src/main/kotlin/org/eclipse/tractusx/bpdm/gate/util/BusinessPartnerCopyUtil.kt @@ -0,0 +1,87 @@ +/******************************************************************************* + * 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.gate.util + +import org.eclipse.tractusx.bpdm.common.util.copyAndSync +import org.eclipse.tractusx.bpdm.common.util.replace +import org.eclipse.tractusx.bpdm.gate.entity.generic.* +import org.springframework.stereotype.Component + +@Component +class BusinessPartnerCopyUtil { + + fun copyValues(fromPartner: BusinessPartnerDb, toPartner: BusinessPartnerDb): BusinessPartnerDb { + return toPartner.apply { + stage = fromPartner.stage + shortName = fromPartner.shortName + legalName = fromPartner.legalName + siteName = fromPartner.siteName + addressName = fromPartner.addressName + legalForm = fromPartner.legalForm + isOwnCompanyData = fromPartner.isOwnCompanyData + bpnL = fromPartner.bpnL + bpnS = fromPartner.bpnS + bpnA = fromPartner.bpnA + parentId = fromPartner.parentId + parentType = fromPartner.parentType + legalEntityConfidence = fromPartner.legalEntityConfidence + siteConfidence = fromPartner.siteConfidence + addressConfidence = fromPartner.addressConfidence + + nameParts.replace(fromPartner.nameParts) + roles.replace(fromPartner.roles) + + states.copyAndSync(fromPartner.states, ::copyValues) + classifications.copyAndSync(fromPartner.classifications, ::copyValues) + identifiers.copyAndSync(fromPartner.identifiers, ::copyValues) + + copyValues(fromPartner.postalAddress, postalAddress) + } + } + + private fun copyValues(fromState: StateDb, toState: StateDb) = + toState.apply { + validFrom = fromState.validFrom + validTo = fromState.validTo + type = fromState.type + } + + private fun copyValues(fromClassification: ClassificationDb, toClassification: ClassificationDb) = + toClassification.apply { + value = fromClassification.value + type = fromClassification.type + code = fromClassification.code + } + + private fun copyValues(fromIdentifier: IdentifierDb, toIdentifier: IdentifierDb) = + toIdentifier.apply { + type = fromIdentifier.type + value = fromIdentifier.value + issuingBody = fromIdentifier.issuingBody + } + + private fun copyValues(fromPostalAddress: PostalAddressDb, toPostalAddress: PostalAddressDb) = + toPostalAddress.apply { + addressType = fromPostalAddress.addressType + physicalPostalAddress = fromPostalAddress.physicalPostalAddress + alternativePostalAddress = fromPostalAddress.alternativePostalAddress + } + +} \ No newline at end of file diff --git a/bpdm-gate/src/main/resources/application.yml b/bpdm-gate/src/main/resources/application.yml index 0320f4ec9..df8dc8b86 100644 --- a/bpdm-gate/src/main/resources/application.yml +++ b/bpdm-gate/src/main/resources/application.yml @@ -53,7 +53,7 @@ bpdm: # Up to how many golden record tasks can be created when checking batchSize: 100 # When and how often the Gate checks for golden record updates from the Pool - cron: '-' + cron: '*/30 * * * * *' check: batchSize: 100 cron: '*/30 * * * * *' diff --git a/bpdm-gate/src/main/resources/db/migration/V6_0_0_5__add_LSA_identifiers.sql b/bpdm-gate/src/main/resources/db/migration/V6_0_0_5__add_LSA_identifiers.sql new file mode 100644 index 000000000..e79694073 --- /dev/null +++ b/bpdm-gate/src/main/resources/db/migration/V6_0_0_5__add_LSA_identifiers.sql @@ -0,0 +1,2 @@ +ALTER TABLE business_partners_identifiers +ADD COLUMN business_partner_type VARCHAR(255) NOT NULL DEFAULT 'GENERIC'; \ No newline at end of file diff --git a/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/controller/BusinessPartnerControllerAndSharingControllerIT.kt b/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/controller/BusinessPartnerControllerAndSharingControllerIT.kt index 1002df1f0..50dac0727 100644 --- a/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/controller/BusinessPartnerControllerAndSharingControllerIT.kt +++ b/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/controller/BusinessPartnerControllerAndSharingControllerIT.kt @@ -268,48 +268,6 @@ class BusinessPartnerControllerAndSharingControllerIT @Autowired constructor( } - @Test - fun `insert one business partners and request cleaning task for bpn update`() { - - this.mockAndAssertUtils.mockPoolApiGetChangeLogs(poolWireMockServer) - this.mockAndAssertUtils.mockOrchestratorApiCleanedResponseSizeOne(gateWireMockServer) - - val outputBusinessPartners = listOf( - BusinessPartnerVerboseValues.bpOutputDtoCleaned - ) - val upsertRequests = listOf( - BusinessPartnerNonVerboseValues.bpInputRequestCleaned - ) - upsertBusinessPartnersAndShare(upsertRequests) - - val externalId4 = BusinessPartnerNonVerboseValues.bpInputRequestCleaned.externalId - - goldenRecordTaskService.resolvePendingTasks() - - goldenRecordTaskService.createTasksForGoldenRecordUpdates() - - val upsertSharingStatesRequests = listOf( - SharingStateDto( - externalId = externalId4, - sharingStateType = SharingStateType.Pending, - sharingErrorCode = null, - sharingErrorMessage = null, - sharingProcessStarted = null, - taskId = "0" - ) - ) - val externalIds = listOf(externalId4) - val upsertSharingStateResponses = this.mockAndAssertUtils.readSharingStates(BusinessPartnerType.GENERIC, externalIds) - - //Assert that Cleaned Golden Record is persisted in the Output correctly - val searchResponsePage = gateClient.businessParters.getBusinessPartnersOutput(listOf(externalId4)) - this.mockAndAssertUtils.assertUpsertOutputResponsesMatchRequests(searchResponsePage.content, outputBusinessPartners) - - //Assert that sharing state are created - assertHelpers.assertRecursively(upsertSharingStateResponses).ignoringFieldsMatchingRegexes(".*${SharingStateDto::sharingProcessStarted.name}") - .isEqualTo(upsertSharingStatesRequests) - } - fun upsertBusinessPartnersAndShare(partners: List) { gateClient.businessParters.upsertBusinessPartnersInput(partners) gateClient.sharingState.postSharingStateReady(PostSharingStateReadyRequest(partners.map { it.externalId })) diff --git a/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/controller/BusinessPartnerControllerIT.kt b/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/controller/BusinessPartnerControllerIT.kt index 1d64a6d48..28a962d07 100644 --- a/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/controller/BusinessPartnerControllerIT.kt +++ b/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/controller/BusinessPartnerControllerIT.kt @@ -405,48 +405,6 @@ class BusinessPartnerControllerIT @Autowired constructor( } - @Test - fun `insert one business partners and request cleaning task for bpn update`() { - - this.mockAndAssertUtils.mockPoolApiGetChangeLogs(poolWireMockServer) - this.mockAndAssertUtils.mockOrchestratorApiCleanedResponseSizeOne(gateWireMockServer) - - val outputBusinessPartners = listOf( - BusinessPartnerVerboseValues.bpOutputDtoCleaned - ) - val upsertRequests = listOf( - BusinessPartnerNonVerboseValues.bpInputRequestCleaned - ) - upsertBusinessPartnersAndShare(upsertRequests) - - val externalId4 = BusinessPartnerNonVerboseValues.bpInputRequestCleaned.externalId - - goldenRecordTaskService.resolvePendingTasks() - - goldenRecordTaskService.createTasksForGoldenRecordUpdates() - - val upsertSharingStatesRequests = listOf( - SharingStateDto( - externalId = externalId4, - sharingStateType = SharingStateType.Pending, - sharingErrorCode = null, - sharingErrorMessage = null, - sharingProcessStarted = null, - taskId = "0" - ) - ) - val externalIds = listOf(externalId4) - val upsertSharingStateResponses = this.mockAndAssertUtils.readSharingStates(BusinessPartnerType.GENERIC, externalIds) - - //Assert that Cleaned Golden Record is persisted in the Output correctly - val searchResponsePage = gateClient.businessParters.getBusinessPartnersOutput(listOf(externalId4)) - this.mockAndAssertUtils.assertUpsertOutputResponsesMatchRequests(searchResponsePage.content, outputBusinessPartners) - - //Assert that sharing state are created - assertHelpers.assertRecursively(upsertSharingStateResponses).ignoringFieldsMatchingRegexes(".*${SharingStateDto::sharingProcessStarted.name}") - .isEqualTo(upsertSharingStatesRequests) - } - private fun upsertBusinessPartnersAndShare(partners: List) { gateClient.businessParters.upsertBusinessPartnersInput(partners) goldenRecordTaskService.createTasksForReadyBusinessPartners() diff --git a/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/BusinessPartnerIT.kt b/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/BusinessPartnerIT.kt index 17c980a05..29fae19a7 100644 --- a/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/BusinessPartnerIT.kt +++ b/bpdm-gate/src/test/kotlin/org/eclipse/tractusx/bpdm/gate/entity/generic/BusinessPartnerIT.kt @@ -239,7 +239,8 @@ internal class BusinessPartnerIT @Autowired constructor( return IdentifierDb( value = "1234567890", type = "Passport", - issuingBody = "Government of XYZ" + issuingBody = "Government of XYZ", + businessPartnerType = BusinessPartnerType.GENERIC ) } diff --git a/bpdm-gate/src/test/resources/application-test.yml b/bpdm-gate/src/test/resources/application-test.yml index 8f2784d3d..ae02898b0 100644 --- a/bpdm-gate/src/test/resources/application-test.yml +++ b/bpdm-gate/src/test/resources/application-test.yml @@ -24,5 +24,7 @@ bpdm: creation: fromSharingMember: cron: '-' + fromPool: + cron: '_' check: cron: '-' \ No newline at end of file