From e9c6b25013ceabcd673ab6d660eb27b737f6b996 Mon Sep 17 00:00:00 2001 From: "fabio.d.mota" Date: Mon, 9 Oct 2023 17:10:25 +0100 Subject: [PATCH 1/5] feat(Cleaning Service): Add logic for cleaning data --- .../bpdm/cleaning/config/ClientsConfig.kt | 103 ++++++++++++++ .../config/OrchestratorConfigProperties.kt | 30 ++++ .../cleaning/service/CleaningServiceDummy.kt | 133 ++++++++++++++++++ .../bpdm/cleaning/service/ResponseMappings.kt | 96 +++++++++++++ .../src/main/resources/application.properties | 2 + 5 files changed, 364 insertions(+) create mode 100644 bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/config/ClientsConfig.kt create mode 100644 bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/config/OrchestratorConfigProperties.kt create mode 100644 bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt create mode 100644 bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/ResponseMappings.kt diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/config/ClientsConfig.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/config/ClientsConfig.kt new file mode 100644 index 000000000..33c849960 --- /dev/null +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/config/ClientsConfig.kt @@ -0,0 +1,103 @@ +/******************************************************************************* + * 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.cleaning.config + + +import org.eclipse.tractusx.orchestrator.api.client.OrchestrationApiClient +import org.eclipse.tractusx.orchestrator.api.client.OrchestrationApiClientImpl +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.http.HttpHeaders +import org.springframework.http.MediaType +import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder +import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository +import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction +import org.springframework.web.reactive.function.client.WebClient +import java.util.function.Consumer + + +@Configuration +class ClientsConfig { + + + @Bean + @ConditionalOnProperty( + value = ["bpdm.orchestrator.security-enabled"], + havingValue = "false", + matchIfMissing = true + ) + fun orchestratorClientNoAuth(poolConfigProperties: OrchestratorConfigProperties): OrchestrationApiClient { + val url = poolConfigProperties.baseUrl + return OrchestrationApiClientImpl { webClientBuilder(url).build() } + } + + + @Bean + @ConditionalOnProperty( + value = ["bpdm.orchestrator.security-enabled"], + havingValue = "true" + ) + fun orchestratorClientWithAuth( + poolConfigProperties: OrchestratorConfigProperties, + clientRegistrationRepository: ClientRegistrationRepository, + authorizedClientService: OAuth2AuthorizedClientService + ): OrchestrationApiClient { + val url = poolConfigProperties.baseUrl + val clientRegistrationId = poolConfigProperties.oauth2ClientRegistration + ?: throw IllegalArgumentException("bpdm.orchestrator.oauth2-client-registration is required if bpdm.orchestrator.security-enabled is set") + return OrchestrationApiClientImpl { + webClientBuilder(url) + .apply(oauth2Configuration(clientRegistrationRepository, authorizedClientService, clientRegistrationId)) + .build() + } + } + + + private fun webClientBuilder(url: String) = + WebClient.builder() + .baseUrl(url) + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + + private fun oauth2Configuration( + clientRegistrationRepository: ClientRegistrationRepository, + authorizedClientService: OAuth2AuthorizedClientService, + clientRegistrationId: String + ): Consumer { + val authorizedClientManager = authorizedClientManager(clientRegistrationRepository, authorizedClientService) + val oauth = ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager) + oauth.setDefaultClientRegistrationId(clientRegistrationId) + return oauth.oauth2Configuration() + } + + private fun authorizedClientManager( + clientRegistrationRepository: ClientRegistrationRepository, + authorizedClientService: OAuth2AuthorizedClientService + ): OAuth2AuthorizedClientManager { + val authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder().clientCredentials().build() + val authorizedClientManager = AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientService) + authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider) + return authorizedClientManager + } + +} \ No newline at end of file diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/config/OrchestratorConfigProperties.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/config/OrchestratorConfigProperties.kt new file mode 100644 index 000000000..ba5bd6a53 --- /dev/null +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/config/OrchestratorConfigProperties.kt @@ -0,0 +1,30 @@ +/******************************************************************************* + * 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.cleaning.config + +import org.springframework.boot.context.properties.ConfigurationProperties + + +@ConfigurationProperties(prefix = "bpdm.orchestrator") +data class OrchestratorConfigProperties( + val baseUrl: String = "http://localhost:8085/", + val securityEnabled: Boolean = false, + val oauth2ClientRegistration: String? +) diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt new file mode 100644 index 000000000..1cf041912 --- /dev/null +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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.cleaning.service + +import mu.KotlinLogging +import org.eclipse.tractusx.bpdm.common.dto.AddressType + + +import org.eclipse.tractusx.orchestrator.api.client.OrchestrationApiClient +import org.eclipse.tractusx.orchestrator.api.model.* +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Service +import java.util.* + +@Service +class CleaningServiceDummy( + private val orchestrationApiClient: OrchestrationApiClient, + + ) { + + private val logger = KotlinLogging.logger { } + + @Scheduled(fixedRate = 60000) // Adjust the rate as needed + fun pollForCleaningTasks() { + try { + logger.info { "Starting polling for cleaning tasks from Orchestrator..." } + + // Step 1: Fetch and reserve the next cleaning request + val cleaningRequest = orchestrationApiClient.goldenRecordTasks + .reserveTasksForStep(TaskStepReservationRequest(amount = 10, TaskStep.Clean)) + + val cleaningTasks = cleaningRequest.reservedTasks + + if (cleaningTasks.isNotEmpty()) { + logger.info { "${cleaningTasks.size} tasks found for cleaning. Proceeding with cleaning..." } + + val cleaningResults = cleaningTasks.mapNotNull { reservedTask -> + // Step 2: Generate dummy cleaning results + processCleaningTask(reservedTask) + } + + // Step 3: Send the cleaning result back to the Orchestrator + orchestrationApiClient.goldenRecordTasks.resolveStepResults(TaskStepResultRequest(cleaningResults)) + logger.info { "Cleaning tasks processing completed for this iteration." } + } + } catch (e: Exception) { + logger.error(e) { "Error while processing cleaning task" } + } + } + + private fun processCleaningTask(reservedTask: TaskStepReservationEntryDto): TaskStepResultEntryDto { + val businessPartner = reservedTask.businessPartner + val addressPartner = createAddressRepresentation(businessPartner.generic) + + val legalAddressBpnReference = when (businessPartner.generic.postalAddress.addressType) { + AddressType.LegalAddress, AddressType.LegalAndSiteMainAddress -> addressPartner.bpnAReference + else -> generateNewBpnReference() + } + + val legalAddress = addressPartner.copy(bpnAReference = legalAddressBpnReference) + val legalEntityDto = createLegalEntityRepresentation(businessPartner.generic, legalAddress) + + val siteDto = when { + shouldCreateSite(businessPartner.generic) -> { + val siteAddressReference = when (businessPartner.generic.postalAddress.addressType) { + AddressType.SiteMainAddress, AddressType.LegalAndSiteMainAddress -> addressPartner.bpnAReference + else -> generateNewBpnReference() + } + val siteMainAddress = addressPartner.copy(bpnAReference = siteAddressReference) + createSiteRepresentation(businessPartner.generic, siteMainAddress) + } + + else -> null + } + + return TaskStepResultEntryDto(reservedTask.taskId, BusinessPartnerFullDto(businessPartner.generic, legalEntityDto, siteDto, addressPartner)) + } + + fun createLegalEntityRepresentation(genericPartner: BusinessPartnerGenericDto, legalAddress: LogisticAddressDto): LegalEntityDto { + val legalName = genericPartner.nameParts.joinToString(" ") + val bpnReferenceDto = validateBpn(genericPartner.bpnL) + return genericPartner.toLegalEntityDto(bpnReferenceDto, legalName, legalAddress) + + } + + fun createAddressRepresentation(genericPartner: BusinessPartnerGenericDto): LogisticAddressDto { + val legalName = genericPartner.nameParts.joinToString(" ") + val bpnReferenceDto = validateBpn(genericPartner.bpnA) + return genericPartner.postalAddress.toLogisticAddressDto(bpnReferenceDto, legalName) + } + + fun createSiteRepresentation(genericPartner: BusinessPartnerGenericDto, siteAddressReference: LogisticAddressDto): SiteDto { + val legalName = genericPartner.nameParts.joinToString(" ") + val bpnReferenceDto = validateBpn(genericPartner.bpnS) + return genericPartner.toSiteDto(bpnReferenceDto, legalName, siteAddressReference) + } + + fun validateBpn(bpn: String?): BpnReferenceDto { + return if (bpn != null) { + BpnReferenceDto(bpn, BpnReferenceType.Bpn) + } else { + // Generate a new UUID and create a BpnReferenceDto object if bpnL/bpnS/bpnA is null + generateNewBpnReference() + } + } + + private fun generateNewBpnReference() = BpnReferenceDto(UUID.randomUUID().toString(), BpnReferenceType.BpnRequestIdentifier) + + fun shouldCreateSite(genericPartner: BusinessPartnerGenericDto): Boolean { + return genericPartner.postalAddress.addressType == AddressType.SiteMainAddress || + genericPartner.postalAddress.addressType == AddressType.LegalAndSiteMainAddress || + genericPartner.bpnS != null + } + + +} diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/ResponseMappings.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/ResponseMappings.kt new file mode 100644 index 000000000..0b2de02a7 --- /dev/null +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/ResponseMappings.kt @@ -0,0 +1,96 @@ +/******************************************************************************* + * 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.cleaning.service + + +import org.eclipse.tractusx.bpdm.common.dto.BusinessPartnerIdentifierDto +import org.eclipse.tractusx.bpdm.common.dto.BusinessPartnerStateDto +import org.eclipse.tractusx.bpdm.common.dto.ClassificationDto +import org.eclipse.tractusx.orchestrator.api.model.* + + +fun BusinessPartnerGenericDto.toLegalEntityDto(bpnReferenceDto: BpnReferenceDto, legalName: String, legalAddress: LogisticAddressDto): LegalEntityDto { + + + return LegalEntityDto( + bpnLReference = bpnReferenceDto, + hasChanged = true, + legalName = legalName, + legalShortName = shortName, + identifiers = identifiers.map { it.toLegalEntityIdentifierDto() }, + legalForm = legalForm, + states = states.map { it.toLegalEntityState() }, + classifications = classifications.map { it.toBusinessPartnerClassificationDto() }, + legalAddress = legalAddress + + ) +} + +fun ClassificationDto.toBusinessPartnerClassificationDto(): BusinessPartnerClassificationDto { + + return BusinessPartnerClassificationDto(code = code, type = type, value = value) +} + +fun BusinessPartnerIdentifierDto.toLegalEntityIdentifierDto(): LegalEntityIdentifierDto { + + return LegalEntityIdentifierDto(value = value, type = type, issuingBody = issuingBody) +} + +fun BusinessPartnerStateDto.toLegalEntityState(): LegalEntityState { + + return LegalEntityState(description, validFrom, validTo, type) +} + +fun BusinessPartnerStateDto.toSiteState(): SiteStateDto { + + return SiteStateDto(description, validFrom, validTo, type) +} + +fun PostalAddressDto.toLogisticAddressDto(bpnReferenceDto: BpnReferenceDto, name: String): + LogisticAddressDto { + + return LogisticAddressDto( + bpnAReference = bpnReferenceDto, + hasChanged = true, + name = name, + states = emptyList(), + identifiers = emptyList(), + physicalPostalAddress = physicalPostalAddress, + alternativePostalAddress = alternativePostalAddress + ) +} + +fun BusinessPartnerGenericDto.toSiteDto(bpnReferenceDto: BpnReferenceDto, legalName: String, siteAddressReference: LogisticAddressDto): SiteDto { + + + return SiteDto( + bpnSReference = bpnReferenceDto, + hasChanged = true, + name = legalName, + states = states.map { it.toSiteState() }, + mainAddress = siteAddressReference + + ) +} + + + + + diff --git a/bpdm-cleaning-service-dummy/src/main/resources/application.properties b/bpdm-cleaning-service-dummy/src/main/resources/application.properties index 9a18363d8..a9814906c 100644 --- a/bpdm-cleaning-service-dummy/src/main/resources/application.properties +++ b/bpdm-cleaning-service-dummy/src/main/resources/application.properties @@ -39,4 +39,6 @@ springdoc.swagger-ui.csrf.enabled=true management.endpoint.health.probes.enabled=true management.health.livenessState.enabled=true management.health.readinessState.enabled=true +#Connection to Orchestrator +bpdm.orchestrator.base-url=http://localhost:8080/api/catena From dd7a3db87ebefab9aced58bc27d2e3b7c69c9c69 Mon Sep 17 00:00:00 2001 From: "fabio.d.mota" Date: Wed, 11 Oct 2023 21:34:14 +0100 Subject: [PATCH 2/5] feat(Cleaning Service): Add unit test --- bpdm-cleaning-service-dummy/pom.xml | 16 ++ .../cleaning/service/CleaningServiceDummy.kt | 2 +- .../service/CleaningServiceDummyTest.kt | 122 +++++++++++++++ .../bpdm/cleaning/testdata/CommonValues.kt | 139 ++++++++++++++++++ 4 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt create mode 100644 bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt diff --git a/bpdm-cleaning-service-dummy/pom.xml b/bpdm-cleaning-service-dummy/pom.xml index b79f8592e..f8c5b56d3 100644 --- a/bpdm-cleaning-service-dummy/pom.xml +++ b/bpdm-cleaning-service-dummy/pom.xml @@ -123,6 +123,22 @@ + + com.github.tomakehurst + wiremock-jre8-standalone + test + + + com.ninja-squad + springmockk + test + + + org.assertj + assertj-core + test + + org.assertj assertj-core diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt index 1cf041912..c0923c98d 100644 --- a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt @@ -65,7 +65,7 @@ class CleaningServiceDummy( } } - private fun processCleaningTask(reservedTask: TaskStepReservationEntryDto): TaskStepResultEntryDto { + fun processCleaningTask(reservedTask: TaskStepReservationEntryDto): TaskStepResultEntryDto { val businessPartner = reservedTask.businessPartner val addressPartner = createAddressRepresentation(businessPartner.generic) diff --git a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt new file mode 100644 index 000000000..bfb9bd160 --- /dev/null +++ b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt @@ -0,0 +1,122 @@ +/******************************************************************************* + * 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.cleaning.service + +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnA +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnLAndBpnAAndLegalAddressType +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithEmptyBpnA +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithEmptyBpnAndSiteMainAddressType +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithEmptyBpnLAndAdditionalAddressType +import org.eclipse.tractusx.bpdm.common.dto.* +import org.eclipse.tractusx.orchestrator.api.model.* +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ActiveProfiles +import java.time.Instant +import java.util.* + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +class CleaningServiceDummyTest @Autowired constructor( + val cleaningServiceDummy: CleaningServiceDummy, +) { + + + @Test + fun `test processCleaningTask with BpnA present and additional address type`() { + val taskStepReservationEntryDto = createSampleTaskStepReservationResponse(businessPartnerWithBpnA).reservedTasks[0] + + val result = cleaningServiceDummy.processCleaningTask(taskStepReservationEntryDto) + + val expectedBpnA = taskStepReservationEntryDto.businessPartner.generic.bpnA + + val resultedAddress = result.businessPartner?.address + + val resultedLegalEntity = result.businessPartner?.legalEntity + + assertEquals(expectedBpnA, resultedAddress?.bpnAReference?.referenceValue) + + assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) + } + + @Test + fun `test processCleaningTask with empty BpnA and additional address type`() { + val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithEmptyBpnA).reservedTasks[0] + + val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + + val resultedAddress = result.businessPartner?.address + + val resultedLegalEntity = result.businessPartner?.legalEntity + + assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedAddress?.bpnAReference?.referenceType) + + assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) + } + + @Test + fun `test processCleaningTask with BpnL and BpnA present and legal address type`() { + val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithBpnLAndBpnAAndLegalAddressType).reservedTasks[0] + + val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + + val expectedBpnA = taskStepReservationResponse.businessPartner.generic.bpnA + } + + @Test + fun `test processCleaningTask with empty BpnL and additional address type`() { + val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithEmptyBpnLAndAdditionalAddressType).reservedTasks[0] + + val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + + val expectedBpnA = taskStepReservationResponse.businessPartner.generic.bpnA + + + } + + @Test + fun `test processCleaningTask with BpnS and BpnA present and legal and site main address type`() { + val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType).reservedTasks[0] + + val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + + val expectedBpnA = taskStepReservationResponse.businessPartner.generic.bpnA + } + + @Test + fun `test processCleaningTask with empty Bpn and site main address type`() { + val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithEmptyBpnAndSiteMainAddressType).reservedTasks[0] + + val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + + val expectedBpnA = taskStepReservationResponse.businessPartner.generic.bpnA + } + + // Helper method to create a sample TaskStepReservationResponse + private fun createSampleTaskStepReservationResponse(businessPartnerGenericDto: BusinessPartnerGenericDto): TaskStepReservationResponse { + val fullDto = BusinessPartnerFullDto(businessPartnerGenericDto) + return TaskStepReservationResponse(listOf(TaskStepReservationEntryDto(UUID.randomUUID().toString(), fullDto)), Instant.MIN) + } + + +} diff --git a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt new file mode 100644 index 000000000..526acdc09 --- /dev/null +++ b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt @@ -0,0 +1,139 @@ +/******************************************************************************* + * 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.cleaning.testdata + +import com.neovisionaries.i18n.CountryCode +import org.eclipse.tractusx.bpdm.common.dto.* +import org.eclipse.tractusx.bpdm.common.model.BusinessStateType +import org.eclipse.tractusx.bpdm.common.model.ClassificationType +import org.eclipse.tractusx.orchestrator.api.model.BusinessPartnerGenericDto +import org.eclipse.tractusx.orchestrator.api.model.PhysicalPostalAddressDto +import org.eclipse.tractusx.orchestrator.api.model.PostalAddressDto +import org.eclipse.tractusx.orchestrator.api.model.StreetDto +import java.time.LocalDateTime + +/** + * Contains simple test values used to create more complex test values such as DTOs + */ +object CommonValues { + + val nameParts = listOf("Part1", "Part2") + const val shortName = "ShortName" + val identifiers = listOf( + BusinessPartnerIdentifierDto( + type = "Type1", + value = "Value1", + issuingBody = "IssuingBody1" + ) + ) + const val legalForm = "LegalForm" + val states = listOf( + BusinessPartnerStateDto( + validFrom = LocalDateTime.now(), + validTo = LocalDateTime.now().plusDays(10), + type = BusinessStateType.ACTIVE, + description = "ActiveState" + ) + ) + val classifications = listOf( + ClassificationDto( + type = ClassificationType.NACE, + code = "Code1", + value = "Value1" + ) + ) + val roles = listOf(BusinessPartnerRole.SUPPLIER, BusinessPartnerRole.CUSTOMER) + val physicalPostalAddress = PhysicalPostalAddressDto( + geographicCoordinates = GeoCoordinateDto(longitude = 12.34f, latitude = 56.78f), + country = CountryCode.PT, + administrativeAreaLevel1 = "AdminArea1", + administrativeAreaLevel2 = "AdminArea2", + administrativeAreaLevel3 = "AdminArea3", + postalCode = "PostalCode", + city = "City", + district = "District", + street = StreetDto("StreetName"), + companyPostalCode = "CompanyPostalCode", + industrialZone = "IndustrialZone", + building = "Building", + floor = "Floor", + door = "Door" + ) + + val postalAddressForLegalAndSite = PostalAddressDto( + addressType = AddressType.LegalAndSiteMainAddress, + physicalPostalAddress = physicalPostalAddress + ) + val postalAddressForLegal = PostalAddressDto( + addressType = AddressType.LegalAddress, + physicalPostalAddress = physicalPostalAddress + ) + val postalAddressForSite = PostalAddressDto( + addressType = AddressType.SiteMainAddress, + physicalPostalAddress = physicalPostalAddress + ) + val postalAddressForAdditional = PostalAddressDto( + addressType = AddressType.AdditionalAddress, + physicalPostalAddress = physicalPostalAddress + ) + + val businessPartnerWithEmptyBpns = BusinessPartnerGenericDto( + nameParts = nameParts, + shortName = shortName, + identifiers = identifiers, + legalForm = legalForm, + states = states, + classifications = classifications, + roles = roles, + ownerBpnL = "ownerBpnL2" + ) + + + val businessPartnerWithBpnA = businessPartnerWithEmptyBpns.copy( + postalAddress = postalAddressForAdditional, + bpnA = "FixedBPNA" + ) + + val businessPartnerWithEmptyBpnA = businessPartnerWithEmptyBpns.copy( + postalAddress = postalAddressForAdditional + ) + + val businessPartnerWithBpnLAndBpnAAndLegalAddressType = businessPartnerWithEmptyBpns.copy( + postalAddress = postalAddressForLegal, + bpnA = "FixedBPNA", + bpnL = "FixedBPNL" + ) + + val businessPartnerWithEmptyBpnLAndAdditionalAddressType = businessPartnerWithEmptyBpns.copy( + postalAddress = postalAddressForAdditional, + ) + + val businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType = businessPartnerWithEmptyBpns.copy( + postalAddress = postalAddressForLegalAndSite, + bpnA = "FixedBPNA", + bpnS = "FixedBPNS" + ) + + val businessPartnerWithEmptyBpnAndSiteMainAddressType = businessPartnerWithEmptyBpns.copy( + postalAddress = postalAddressForSite + ) + + +} \ No newline at end of file From 3bc7778c46f500d2680e7c104e8f3bde1cdd9c50 Mon Sep 17 00:00:00 2001 From: "fabio.d.mota" Date: Fri, 13 Oct 2023 12:32:31 +0100 Subject: [PATCH 3/5] feat(Cleaning Service): Fix comments to PR and add unit test for possibility's --- .../tractusx/bpdm/cleaning/Application.kt | 2 + .../cleaning/service/CleaningServiceDummy.kt | 65 ++++++++------ ...s.kt => GenericBusinessPartnerMappings.kt} | 0 .../src/main/resources/application.properties | 4 +- .../service/CleaningServiceDummyTest.kt | 89 ++++++++++++++++--- .../bpdm/cleaning/testdata/CommonValues.kt | 3 - 6 files changed, 120 insertions(+), 43 deletions(-) rename bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/{ResponseMappings.kt => GenericBusinessPartnerMappings.kt} (100%) diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/Application.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/Application.kt index 30730dfd5..0c84b7bf8 100644 --- a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/Application.kt +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/Application.kt @@ -23,9 +23,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration import org.springframework.boot.context.properties.ConfigurationPropertiesScan import org.springframework.boot.runApplication +import org.springframework.scheduling.annotation.EnableScheduling @SpringBootApplication(exclude=[DataSourceAutoConfiguration::class]) @ConfigurationPropertiesScan +@EnableScheduling class Application fun main(args: Array) { diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt index c0923c98d..d4e83b298 100644 --- a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt @@ -19,10 +19,9 @@ package org.eclipse.tractusx.bpdm.cleaning.service + import mu.KotlinLogging import org.eclipse.tractusx.bpdm.common.dto.AddressType - - import org.eclipse.tractusx.orchestrator.api.client.OrchestrationApiClient import org.eclipse.tractusx.orchestrator.api.model.* import org.springframework.scheduling.annotation.Scheduled @@ -37,7 +36,8 @@ class CleaningServiceDummy( private val logger = KotlinLogging.logger { } - @Scheduled(fixedRate = 60000) // Adjust the rate as needed + + @Scheduled(cron = "\${cleaningService.pollingCron:-}", zone = "UTC") fun pollForCleaningTasks() { try { logger.info { "Starting polling for cleaning tasks from Orchestrator..." } @@ -48,8 +48,9 @@ class CleaningServiceDummy( val cleaningTasks = cleaningRequest.reservedTasks + logger.info { "${cleaningTasks.size} tasks found for cleaning. Proceeding with cleaning..." } + if (cleaningTasks.isNotEmpty()) { - logger.info { "${cleaningTasks.size} tasks found for cleaning. Proceeding with cleaning..." } val cleaningResults = cleaningTasks.mapNotNull { reservedTask -> // Step 2: Generate dummy cleaning results @@ -67,52 +68,64 @@ class CleaningServiceDummy( fun processCleaningTask(reservedTask: TaskStepReservationEntryDto): TaskStepResultEntryDto { val businessPartner = reservedTask.businessPartner + val addressPartner = createAddressRepresentation(businessPartner.generic) - val legalAddressBpnReference = when (businessPartner.generic.postalAddress.addressType) { - AddressType.LegalAddress, AddressType.LegalAndSiteMainAddress -> addressPartner.bpnAReference - else -> generateNewBpnReference() - } + val addressType = businessPartner.generic.postalAddress.addressType - val legalAddress = addressPartner.copy(bpnAReference = legalAddressBpnReference) - val legalEntityDto = createLegalEntityRepresentation(businessPartner.generic, legalAddress) + val legalEntityDto = createLegalEntityRepresentation(addressPartner, addressType!!, businessPartner.generic) - val siteDto = when { - shouldCreateSite(businessPartner.generic) -> { - val siteAddressReference = when (businessPartner.generic.postalAddress.addressType) { - AddressType.SiteMainAddress, AddressType.LegalAndSiteMainAddress -> addressPartner.bpnAReference - else -> generateNewBpnReference() - } - val siteMainAddress = addressPartner.copy(bpnAReference = siteAddressReference) - createSiteRepresentation(businessPartner.generic, siteMainAddress) - } + val siteDto = createSiteDtoIfNeeded(businessPartner.generic, addressPartner) - else -> null + return TaskStepResultEntryDto(reservedTask.taskId, BusinessPartnerFullDto(businessPartner.generic, legalEntityDto, siteDto, addressPartner)) + } + + fun createSiteDtoIfNeeded(businessPartner: BusinessPartnerGenericDto, addressPartner: LogisticAddressDto): SiteDto? { + if (!shouldCreateSite(businessPartner)) return null + + val siteAddressReference = when (businessPartner.postalAddress.addressType) { + AddressType.SiteMainAddress, AddressType.LegalAndSiteMainAddress -> addressPartner.bpnAReference + else -> generateNewBpnReference() } - return TaskStepResultEntryDto(reservedTask.taskId, BusinessPartnerFullDto(businessPartner.generic, legalEntityDto, siteDto, addressPartner)) + val siteMainAddress = addressPartner.copy(bpnAReference = siteAddressReference) + return createSiteRepresentation(businessPartner, siteMainAddress) } - fun createLegalEntityRepresentation(genericPartner: BusinessPartnerGenericDto, legalAddress: LogisticAddressDto): LegalEntityDto { + fun createLegalEntityRepresentation( + addressPartner: LogisticAddressDto, + addressType: AddressType, + genericPartner: BusinessPartnerGenericDto + ): LegalEntityDto { + val legalAddressBpnReference = if (addressType == AddressType.LegalAddress || addressType == AddressType.LegalAndSiteMainAddress) { + addressPartner.bpnAReference + } else { + generateNewBpnReference() + } + + val legalAddress = addressPartner.copy(bpnAReference = legalAddressBpnReference) + val legalName = genericPartner.nameParts.joinToString(" ") - val bpnReferenceDto = validateBpn(genericPartner.bpnL) + + val bpnReferenceDto = createBpnReference(genericPartner.bpnL) + return genericPartner.toLegalEntityDto(bpnReferenceDto, legalName, legalAddress) } fun createAddressRepresentation(genericPartner: BusinessPartnerGenericDto): LogisticAddressDto { val legalName = genericPartner.nameParts.joinToString(" ") - val bpnReferenceDto = validateBpn(genericPartner.bpnA) + val bpnReferenceDto = createBpnReference(genericPartner.bpnA) return genericPartner.postalAddress.toLogisticAddressDto(bpnReferenceDto, legalName) } fun createSiteRepresentation(genericPartner: BusinessPartnerGenericDto, siteAddressReference: LogisticAddressDto): SiteDto { val legalName = genericPartner.nameParts.joinToString(" ") - val bpnReferenceDto = validateBpn(genericPartner.bpnS) + val bpnReferenceDto = createBpnReference(genericPartner.bpnS) return genericPartner.toSiteDto(bpnReferenceDto, legalName, siteAddressReference) } - fun validateBpn(bpn: String?): BpnReferenceDto { + fun createBpnReference(bpn: String?): BpnReferenceDto { return if (bpn != null) { BpnReferenceDto(bpn, BpnReferenceType.Bpn) } else { diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/ResponseMappings.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/GenericBusinessPartnerMappings.kt similarity index 100% rename from bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/ResponseMappings.kt rename to bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/GenericBusinessPartnerMappings.kt diff --git a/bpdm-cleaning-service-dummy/src/main/resources/application.properties b/bpdm-cleaning-service-dummy/src/main/resources/application.properties index a9814906c..9022d8710 100644 --- a/bpdm-cleaning-service-dummy/src/main/resources/application.properties +++ b/bpdm-cleaning-service-dummy/src/main/resources/application.properties @@ -41,4 +41,6 @@ management.health.livenessState.enabled=true management.health.readinessState.enabled=true #Connection to Orchestrator bpdm.orchestrator.base-url=http://localhost:8080/api/catena - +## +#Cleaning Service Configurations +cleaningService.pollingCron=- diff --git a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt index bfb9bd160..fc24026d8 100644 --- a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt +++ b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt @@ -22,12 +22,13 @@ package org.eclipse.tractusx.bpdm.cleaning.service import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnA import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnLAndBpnAAndLegalAddressType import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType -import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithEmptyBpnA + import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithEmptyBpnAndSiteMainAddressType import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithEmptyBpnLAndAdditionalAddressType import org.eclipse.tractusx.bpdm.common.dto.* import org.eclipse.tractusx.orchestrator.api.model.* import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotEquals import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -54,6 +55,9 @@ class CleaningServiceDummyTest @Autowired constructor( val resultedLegalEntity = result.businessPartner?.legalEntity + // legalEntity should be Generated with new bpnL and legalAddress bpnA + // addressPartner should use passed bpnA, and it will be different from legalAddress since type is additional address type + assertEquals(expectedBpnA, resultedAddress?.bpnAReference?.referenceValue) assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) @@ -61,46 +65,84 @@ class CleaningServiceDummyTest @Autowired constructor( @Test fun `test processCleaningTask with empty BpnA and additional address type`() { - val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithEmptyBpnA).reservedTasks[0] + val taskStepReservationEntryDto = createSampleTaskStepReservationResponse(businessPartnerWithEmptyBpnLAndAdditionalAddressType).reservedTasks[0] - val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + val result = cleaningServiceDummy.processCleaningTask(taskStepReservationEntryDto) val resultedAddress = result.businessPartner?.address val resultedLegalEntity = result.businessPartner?.legalEntity + // legalEntity should be Generated with new bpnL and legalAddress bpnA + // addressPartner should be Generated bpnA, and it will be different from legalAddress since type is additional address type + assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedAddress?.bpnAReference?.referenceType) assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) + + assertNotEquals(resultedAddress?.bpnAReference?.referenceValue, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) } @Test fun `test processCleaningTask with BpnL and BpnA present and legal address type`() { - val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithBpnLAndBpnAAndLegalAddressType).reservedTasks[0] + val taskStepReservationEntryDto = createSampleTaskStepReservationResponse(businessPartnerWithBpnLAndBpnAAndLegalAddressType).reservedTasks[0] - val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + val result = cleaningServiceDummy.processCleaningTask(taskStepReservationEntryDto) - val expectedBpnA = taskStepReservationResponse.businessPartner.generic.bpnA - } + val expectedBpnA = taskStepReservationEntryDto.businessPartner.generic.bpnA - @Test - fun `test processCleaningTask with empty BpnL and additional address type`() { - val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithEmptyBpnLAndAdditionalAddressType).reservedTasks[0] + val expectedBpnL = taskStepReservationEntryDto.businessPartner.generic.bpnL - val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + val resultedAddress = result.businessPartner?.address - val expectedBpnA = taskStepReservationResponse.businessPartner.generic.bpnA + val resultedLegalEntity = result.businessPartner?.legalEntity + // legalEntity should use passed bpnL and legalAddress should use passed bpnA since address type is LegalAddressType + // addressPartner should use passed bpnA, and it will be the same from legalAddress since type is LegalAddressType + assertEquals(expectedBpnA, resultedAddress?.bpnAReference?.referenceValue) + assertEquals(expectedBpnL, resultedLegalEntity?.bpnLReference?.referenceValue) + assertEquals(expectedBpnA, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) } + @Test fun `test processCleaningTask with BpnS and BpnA present and legal and site main address type`() { val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType).reservedTasks[0] val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) + val resultedAddress = result.businessPartner?.address + + val resultedLegalEntity = result.businessPartner?.legalEntity + + val resultedSite = result.businessPartner?.site + val expectedBpnA = taskStepReservationResponse.businessPartner.generic.bpnA + + val expectedBpnS = taskStepReservationResponse.businessPartner.generic.bpnS + + + // legalEntity should Generate new bpnL and legalAddress should use passed bpnA since address type is LegalAndSiteMainAddress + // addressPartner should use passed bpnA, and it will be the same from legalAddress since type is LegalAndSiteMainAddress + // Site should use passed bpnS, and it will be the same MainAddress as legalAddress and addressPartner since address type is LegalAndSiteMainAddress + + + assertEquals(expectedBpnA, resultedAddress?.bpnAReference?.referenceValue) + + assertEquals(expectedBpnA, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) + + assertEquals(expectedBpnA, resultedSite?.mainAddress?.bpnAReference?.referenceValue) + + assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) + + assertEquals(resultedAddress?.bpnAReference?.referenceValue, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) + + assertEquals(resultedAddress?.bpnAReference?.referenceValue, resultedSite?.mainAddress?.bpnAReference?.referenceValue) + + assertEquals(expectedBpnS, resultedSite?.bpnSReference?.referenceValue) + + } @Test @@ -109,7 +151,28 @@ class CleaningServiceDummyTest @Autowired constructor( val result = cleaningServiceDummy.processCleaningTask(taskStepReservationResponse) - val expectedBpnA = taskStepReservationResponse.businessPartner.generic.bpnA + val resultedAddress = result.businessPartner?.address + + val resultedLegalEntity = result.businessPartner?.legalEntity + + val resultedSite = result.businessPartner?.site + + + // legalEntity should Generate new bpnL and legalAddress should Generate new bpnA since address type is SiteMainAddress + // addressPartner should Generate new bpnA, and it will be different from legalAddress since type is SiteMainAddress + // Site should Generate new bpnS, and it will be the same MainAddress as addressPartner since address type is SiteMainAddress + + + assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) + + assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedAddress?.bpnAReference?.referenceType) + + assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedSite?.bpnSReference?.referenceType) + + assertNotEquals(resultedAddress?.bpnAReference?.referenceValue, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) + + assertEquals(resultedSite?.mainAddress?.bpnAReference?.referenceValue, resultedAddress?.bpnAReference?.referenceValue) + } // Helper method to create a sample TaskStepReservationResponse diff --git a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt index 526acdc09..44d632166 100644 --- a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt +++ b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt @@ -111,9 +111,6 @@ object CommonValues { bpnA = "FixedBPNA" ) - val businessPartnerWithEmptyBpnA = businessPartnerWithEmptyBpns.copy( - postalAddress = postalAddressForAdditional - ) val businessPartnerWithBpnLAndBpnAAndLegalAddressType = businessPartnerWithEmptyBpns.copy( postalAddress = postalAddressForLegal, From 50de80feb4ce57f477c334628e9daa14d3925575 Mon Sep 17 00:00:00 2001 From: "fabio.d.mota" Date: Tue, 17 Oct 2023 22:17:16 +0100 Subject: [PATCH 4/5] feat(Cleaning Service): Change Logic on Address Creation --- .../cleaning/service/CleaningServiceDummy.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt index d4e83b298..b31e59e01 100644 --- a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt @@ -77,7 +77,21 @@ class CleaningServiceDummy( val siteDto = createSiteDtoIfNeeded(businessPartner.generic, addressPartner) - return TaskStepResultEntryDto(reservedTask.taskId, BusinessPartnerFullDto(businessPartner.generic, legalEntityDto, siteDto, addressPartner)) + val addressDto = shouldCreateAddress(addressType, addressPartner) + + return TaskStepResultEntryDto(reservedTask.taskId, BusinessPartnerFullDto(businessPartner.generic, legalEntityDto, siteDto, addressDto)) + } + + private fun shouldCreateAddress( + addressType: AddressType?, + addressPartner: LogisticAddressDto + ): LogisticAddressDto? { + val addressDto = if (addressType == AddressType.AdditionalAddress) { + addressPartner + } else { + null + } + return addressDto } fun createSiteDtoIfNeeded(businessPartner: BusinessPartnerGenericDto, addressPartner: LogisticAddressDto): SiteDto? { From 96bc9a784a7d54bd906d75b75d3ba1424d1566ea Mon Sep 17 00:00:00 2001 From: "fabio.d.mota" Date: Tue, 17 Oct 2023 22:17:55 +0100 Subject: [PATCH 5/5] feat(Cleaning Service): Add unit testing for variations and rest api calls --- .../cleaning/service/CleaningServiceDummy.kt | 33 ++--- .../service/GenericBusinessPartnerMappings.kt | 14 +- .../src/main/resources/application.properties | 2 +- .../service/CleaningServiceApiCallsTest.kt | 139 ++++++++++++++++++ .../service/CleaningServiceDummyTest.kt | 103 ++++++++++--- .../bpdm/cleaning/testdata/CommonValues.kt | 37 ++++- 6 files changed, 282 insertions(+), 46 deletions(-) create mode 100644 bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceApiCallsTest.kt diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt index b31e59e01..0d367d59a 100644 --- a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummy.kt @@ -44,7 +44,7 @@ class CleaningServiceDummy( // Step 1: Fetch and reserve the next cleaning request val cleaningRequest = orchestrationApiClient.goldenRecordTasks - .reserveTasksForStep(TaskStepReservationRequest(amount = 10, TaskStep.Clean)) + .reserveTasksForStep(TaskStepReservationRequest(amount = 10, TaskStep.CleanAndSync)) val cleaningTasks = cleaningRequest.reservedTasks @@ -52,7 +52,7 @@ class CleaningServiceDummy( if (cleaningTasks.isNotEmpty()) { - val cleaningResults = cleaningTasks.mapNotNull { reservedTask -> + val cleaningResults = cleaningTasks.map { reservedTask -> // Step 2: Generate dummy cleaning results processCleaningTask(reservedTask) } @@ -67,23 +67,23 @@ class CleaningServiceDummy( } fun processCleaningTask(reservedTask: TaskStepReservationEntryDto): TaskStepResultEntryDto { - val businessPartner = reservedTask.businessPartner + val genericBusinessPartner = reservedTask.businessPartner.generic - val addressPartner = createAddressRepresentation(businessPartner.generic) + val addressPartner = createAddressRepresentation(genericBusinessPartner) - val addressType = businessPartner.generic.postalAddress.addressType + val addressType = genericBusinessPartner.postalAddress.addressType ?: AddressType.AdditionalAddress - val legalEntityDto = createLegalEntityRepresentation(addressPartner, addressType!!, businessPartner.generic) + val legalEntityDto = createLegalEntityRepresentation(addressPartner, addressType, genericBusinessPartner) - val siteDto = createSiteDtoIfNeeded(businessPartner.generic, addressPartner) + val siteDto = createSiteDtoIfNeeded(genericBusinessPartner, addressPartner) val addressDto = shouldCreateAddress(addressType, addressPartner) - return TaskStepResultEntryDto(reservedTask.taskId, BusinessPartnerFullDto(businessPartner.generic, legalEntityDto, siteDto, addressDto)) + return TaskStepResultEntryDto(reservedTask.taskId, BusinessPartnerFullDto(genericBusinessPartner, legalEntityDto, siteDto, addressDto)) } private fun shouldCreateAddress( - addressType: AddressType?, + addressType: AddressType, addressPartner: LogisticAddressDto ): LogisticAddressDto? { val addressDto = if (addressType == AddressType.AdditionalAddress) { @@ -99,7 +99,7 @@ class CleaningServiceDummy( val siteAddressReference = when (businessPartner.postalAddress.addressType) { AddressType.SiteMainAddress, AddressType.LegalAndSiteMainAddress -> addressPartner.bpnAReference - else -> generateNewBpnReference() + else -> generateNewBpnRequestIdentifier() } val siteMainAddress = addressPartner.copy(bpnAReference = siteAddressReference) @@ -114,23 +114,20 @@ class CleaningServiceDummy( val legalAddressBpnReference = if (addressType == AddressType.LegalAddress || addressType == AddressType.LegalAndSiteMainAddress) { addressPartner.bpnAReference } else { - generateNewBpnReference() + generateNewBpnRequestIdentifier() } val legalAddress = addressPartner.copy(bpnAReference = legalAddressBpnReference) - val legalName = genericPartner.nameParts.joinToString(" ") - val bpnReferenceDto = createBpnReference(genericPartner.bpnL) - return genericPartner.toLegalEntityDto(bpnReferenceDto, legalName, legalAddress) + return genericPartner.toLegalEntityDto(bpnReferenceDto, legalAddress) } fun createAddressRepresentation(genericPartner: BusinessPartnerGenericDto): LogisticAddressDto { - val legalName = genericPartner.nameParts.joinToString(" ") val bpnReferenceDto = createBpnReference(genericPartner.bpnA) - return genericPartner.postalAddress.toLogisticAddressDto(bpnReferenceDto, legalName) + return genericPartner.toLogisticAddressDto(bpnReferenceDto) } fun createSiteRepresentation(genericPartner: BusinessPartnerGenericDto, siteAddressReference: LogisticAddressDto): SiteDto { @@ -144,11 +141,11 @@ class CleaningServiceDummy( BpnReferenceDto(bpn, BpnReferenceType.Bpn) } else { // Generate a new UUID and create a BpnReferenceDto object if bpnL/bpnS/bpnA is null - generateNewBpnReference() + generateNewBpnRequestIdentifier() } } - private fun generateNewBpnReference() = BpnReferenceDto(UUID.randomUUID().toString(), BpnReferenceType.BpnRequestIdentifier) + private fun generateNewBpnRequestIdentifier() = BpnReferenceDto(UUID.randomUUID().toString(), BpnReferenceType.BpnRequestIdentifier) fun shouldCreateSite(genericPartner: BusinessPartnerGenericDto): Boolean { return genericPartner.postalAddress.addressType == AddressType.SiteMainAddress || diff --git a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/GenericBusinessPartnerMappings.kt b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/GenericBusinessPartnerMappings.kt index 0b2de02a7..1cc1fef71 100644 --- a/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/GenericBusinessPartnerMappings.kt +++ b/bpdm-cleaning-service-dummy/src/main/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/GenericBusinessPartnerMappings.kt @@ -26,13 +26,12 @@ import org.eclipse.tractusx.bpdm.common.dto.ClassificationDto import org.eclipse.tractusx.orchestrator.api.model.* -fun BusinessPartnerGenericDto.toLegalEntityDto(bpnReferenceDto: BpnReferenceDto, legalName: String, legalAddress: LogisticAddressDto): LegalEntityDto { - +fun BusinessPartnerGenericDto.toLegalEntityDto(bpnReferenceDto: BpnReferenceDto, legalAddress: LogisticAddressDto): LegalEntityDto { return LegalEntityDto( bpnLReference = bpnReferenceDto, hasChanged = true, - legalName = legalName, + legalName = nameParts.joinToString(" "), legalShortName = shortName, identifiers = identifiers.map { it.toLegalEntityIdentifierDto() }, legalForm = legalForm, @@ -63,17 +62,16 @@ fun BusinessPartnerStateDto.toSiteState(): SiteStateDto { return SiteStateDto(description, validFrom, validTo, type) } -fun PostalAddressDto.toLogisticAddressDto(bpnReferenceDto: BpnReferenceDto, name: String): +fun BusinessPartnerGenericDto.toLogisticAddressDto(bpnReferenceDto: BpnReferenceDto): LogisticAddressDto { - return LogisticAddressDto( bpnAReference = bpnReferenceDto, hasChanged = true, - name = name, + name = nameParts.joinToString(" "), states = emptyList(), identifiers = emptyList(), - physicalPostalAddress = physicalPostalAddress, - alternativePostalAddress = alternativePostalAddress + physicalPostalAddress = postalAddress.physicalPostalAddress, + alternativePostalAddress = postalAddress.alternativePostalAddress ) } diff --git a/bpdm-cleaning-service-dummy/src/main/resources/application.properties b/bpdm-cleaning-service-dummy/src/main/resources/application.properties index 9022d8710..74107e09c 100644 --- a/bpdm-cleaning-service-dummy/src/main/resources/application.properties +++ b/bpdm-cleaning-service-dummy/src/main/resources/application.properties @@ -40,7 +40,7 @@ management.endpoint.health.probes.enabled=true management.health.livenessState.enabled=true management.health.readinessState.enabled=true #Connection to Orchestrator -bpdm.orchestrator.base-url=http://localhost:8080/api/catena +bpdm.orchestrator.base-url=http://localhost:8085/ ## #Cleaning Service Configurations cleaningService.pollingCron=- diff --git a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceApiCallsTest.kt b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceApiCallsTest.kt new file mode 100644 index 000000000..3b72b28db --- /dev/null +++ b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceApiCallsTest.kt @@ -0,0 +1,139 @@ +/******************************************************************************* + * 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.cleaning.service + + +import com.fasterxml.jackson.databind.ObjectMapper +import com.github.tomakehurst.wiremock.client.WireMock.* +import com.github.tomakehurst.wiremock.core.WireMockConfiguration +import com.github.tomakehurst.wiremock.junit5.WireMockExtension +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnA +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.fixedTaskId + +import org.eclipse.tractusx.bpdm.common.dto.* +import org.eclipse.tractusx.orchestrator.api.client.OrchestrationApiClient +import org.eclipse.tractusx.orchestrator.api.model.* +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.RegisterExtension +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.context.SpringBootTest +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.DynamicPropertyRegistry +import org.springframework.test.context.DynamicPropertySource +import java.time.Instant +import java.util.* + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("test") +class CleaningServiceApiCallsTest @Autowired constructor( + val cleaningServiceDummy: CleaningServiceDummy, + val jacksonObjectMapper: ObjectMapper, + val orchestrationApiClient: OrchestrationApiClient +) { + + companion object { + const val ORCHESTRATOR_RESERVE_TASKS_URL = "/api/golden-record-tasks/step-reservations" + const val ORCHESTRATOR_RESOLVE_TASKS_URL = "/api/golden-record-tasks/step-results" + + @JvmField + @RegisterExtension + val orchestratorMockApi: WireMockExtension = WireMockExtension.newInstance() + .options(WireMockConfiguration.wireMockConfig().dynamicPort()) + .build() + + @JvmStatic + @DynamicPropertySource + fun properties(registry: DynamicPropertyRegistry) { + registry.add("bpdm.orchestrator.base-url") { orchestratorMockApi.baseUrl() } + + } + } + + @BeforeEach + fun beforeEach() { + orchestratorMockApi.resetAll() + this.mockOrchestratorResolveApi() + this.mockOrchestratorReserveApi() + } + + + @Test + fun `pollForCleaningTasks should reserve and resolve tasks from orchestrator`() { + + // Call the method under test + cleaningServiceDummy.pollForCleaningTasks() + + // Verify that the reserve API was called once (using WireMock) + orchestratorMockApi.verify(postRequestedFor(urlEqualTo(ORCHESTRATOR_RESERVE_TASKS_URL)).withRequestBody(matchingJsonPath("$.amount", equalTo("10")))) + + // Verify that the resolve API was called once (using WireMock) + orchestratorMockApi.verify(postRequestedFor(urlEqualTo(ORCHESTRATOR_RESOLVE_TASKS_URL))) + } + + @Test + fun `reserveTasksForStep should return expected response`() { + + + val expectedResponse = jacksonObjectMapper.writeValueAsString(createSampleTaskStepReservationResponse(businessPartnerWithBpnA)) + + + val result = orchestrationApiClient.goldenRecordTasks.reserveTasksForStep( + TaskStepReservationRequest(amount = 10, TaskStep.Clean) + ) + + // Assert the expected result + val expectedResult = jacksonObjectMapper.readValue(expectedResponse, result::class.java) // Convert the expected JSON response to your DTO + assertEquals(expectedResult, result) + + orchestrationApiClient.goldenRecordTasks.resolveStepResults( + TaskStepResultRequest(emptyList()) + ) + + } + + + fun mockOrchestratorReserveApi() { + + // Orchestrator reserve + orchestratorMockApi.stubFor( + post(urlPathEqualTo(ORCHESTRATOR_RESERVE_TASKS_URL)) + .willReturn( + okJson(jacksonObjectMapper.writeValueAsString(createSampleTaskStepReservationResponse(businessPartnerWithBpnA))) + ) + ) + } + + fun mockOrchestratorResolveApi() { + // Orchestrator resolve + orchestratorMockApi.stubFor( + post(urlPathEqualTo(ORCHESTRATOR_RESOLVE_TASKS_URL)) + .willReturn(aResponse().withStatus(200)) + ) + } + + // Helper method to create a sample TaskStepReservationResponse + private fun createSampleTaskStepReservationResponse(businessPartnerGenericDto: BusinessPartnerGenericDto): TaskStepReservationResponse { + val fullDto = BusinessPartnerFullDto(businessPartnerGenericDto) + return TaskStepReservationResponse(listOf(TaskStepReservationEntryDto(fixedTaskId, fullDto)), Instant.MIN) + } + +} \ No newline at end of file diff --git a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt index fc24026d8..8769212aa 100644 --- a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt +++ b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/service/CleaningServiceDummyTest.kt @@ -19,16 +19,20 @@ package org.eclipse.tractusx.bpdm.cleaning.service +import com.github.tomakehurst.wiremock.client.WireMock.* +import org.assertj.core.api.Assertions +import org.assertj.core.api.RecursiveComparisonAssert import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnA import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnLAndBpnAAndLegalAddressType import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType - import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithEmptyBpnAndSiteMainAddressType import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.businessPartnerWithEmptyBpnLAndAdditionalAddressType +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.expectedLegalEntityDto +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.expectedLogisticAddressDto +import org.eclipse.tractusx.bpdm.cleaning.testdata.CommonValues.expectedSiteDto import org.eclipse.tractusx.bpdm.common.dto.* import org.eclipse.tractusx.orchestrator.api.model.* -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -39,7 +43,7 @@ import java.util.* @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") class CleaningServiceDummyTest @Autowired constructor( - val cleaningServiceDummy: CleaningServiceDummy, + val cleaningServiceDummy: CleaningServiceDummy ) { @@ -61,6 +65,17 @@ class CleaningServiceDummyTest @Autowired constructor( assertEquals(expectedBpnA, resultedAddress?.bpnAReference?.referenceValue) assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) + + val expectedAddress = expectedLogisticAddressDto.copy(bpnAReference = BpnReferenceDto(expectedBpnA.toString(), BpnReferenceType.Bpn)) + + val expectedLegalEntity = expectedLegalEntityDto.copy(legalAddress = expectedLogisticAddressDto) + + assertRecursively(resultedAddress).isEqualTo(expectedAddress) + + // ignoring bpnLReference and bpnAReference since they are generated + assertRecursively(resultedLegalEntity).ignoringFields("bpnLReference", "legalAddress.bpnAReference").isEqualTo(expectedLegalEntity) + + } @Test @@ -81,6 +96,16 @@ class CleaningServiceDummyTest @Autowired constructor( assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) assertNotEquals(resultedAddress?.bpnAReference?.referenceValue, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) + + val expectedAddress = expectedLogisticAddressDto.copy() + + val expectedLegalEntity = expectedLegalEntityDto.copy(legalAddress = expectedLogisticAddressDto) + + // bpnAReference since they are generated + assertRecursively(resultedAddress).ignoringFields("bpnAReference").isEqualTo(expectedAddress) + + // ignoring bpnLReference and bpnAReference since they are generated + assertRecursively(resultedLegalEntity).ignoringFields("bpnAReference", "bpnLReference", "legalAddress.bpnAReference").isEqualTo(expectedLegalEntity) } @Test @@ -98,14 +123,25 @@ class CleaningServiceDummyTest @Autowired constructor( val resultedLegalEntity = result.businessPartner?.legalEntity // legalEntity should use passed bpnL and legalAddress should use passed bpnA since address type is LegalAddressType - // addressPartner should use passed bpnA, and it will be the same from legalAddress since type is LegalAddressType + // addressPartner should use null, since it does not create when type is LegalAddressType - assertEquals(expectedBpnA, resultedAddress?.bpnAReference?.referenceValue) + assertNull(resultedAddress?.bpnAReference?.referenceValue) assertEquals(expectedBpnL, resultedLegalEntity?.bpnLReference?.referenceValue) assertEquals(expectedBpnA, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) - } + val expectedLegalEntity = expectedLegalEntityDto.copy( + legalAddress = expectedLogisticAddressDto.copy( + bpnAReference = BpnReferenceDto( + expectedBpnA.toString(), + BpnReferenceType.Bpn + ) + ), bpnLReference = BpnReferenceDto(expectedBpnL.toString(), BpnReferenceType.Bpn) + ) + + assertRecursively(resultedLegalEntity).isEqualTo(expectedLegalEntity) + } + @Test fun `test processCleaningTask with BpnS and BpnA present and legal and site main address type`() { val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithBpnSAndBpnAAndLegalAndSiteMainAddressType).reservedTasks[0] @@ -124,11 +160,11 @@ class CleaningServiceDummyTest @Autowired constructor( // legalEntity should Generate new bpnL and legalAddress should use passed bpnA since address type is LegalAndSiteMainAddress - // addressPartner should use passed bpnA, and it will be the same from legalAddress since type is LegalAndSiteMainAddress + // addressPartner should use null, since it does not create when type is LegalAndSiteMainAddress // Site should use passed bpnS, and it will be the same MainAddress as legalAddress and addressPartner since address type is LegalAndSiteMainAddress - assertEquals(expectedBpnA, resultedAddress?.bpnAReference?.referenceValue) + assertNull(resultedAddress?.bpnAReference?.referenceValue) assertEquals(expectedBpnA, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) @@ -136,15 +172,31 @@ class CleaningServiceDummyTest @Autowired constructor( assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) - assertEquals(resultedAddress?.bpnAReference?.referenceValue, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) + assertEquals(expectedBpnS, resultedSite?.bpnSReference?.referenceValue) - assertEquals(resultedAddress?.bpnAReference?.referenceValue, resultedSite?.mainAddress?.bpnAReference?.referenceValue) - assertEquals(expectedBpnS, resultedSite?.bpnSReference?.referenceValue) + val expectedLegalEntity = expectedLegalEntityDto.copy( + legalAddress = expectedLogisticAddressDto.copy( + bpnAReference = BpnReferenceDto( + expectedBpnA.toString(), + BpnReferenceType.Bpn + ) + ) + ) + val expectedSite = expectedSiteDto.copy( + mainAddress = expectedLogisticAddressDto.copy(bpnAReference = BpnReferenceDto(expectedBpnA.toString(), BpnReferenceType.Bpn)), + bpnSReference = BpnReferenceDto(expectedBpnS.toString(), BpnReferenceType.Bpn) + ) + + + // ignoring bpnLReference since they are generated + assertRecursively(resultedLegalEntity).ignoringFields("bpnLReference").isEqualTo(expectedLegalEntity) + + assertRecursively(resultedSite).isEqualTo(expectedSite) - } + } @Test fun `test processCleaningTask with empty Bpn and site main address type`() { val taskStepReservationResponse = createSampleTaskStepReservationResponse(businessPartnerWithEmptyBpnAndSiteMainAddressType).reservedTasks[0] @@ -159,19 +211,29 @@ class CleaningServiceDummyTest @Autowired constructor( // legalEntity should Generate new bpnL and legalAddress should Generate new bpnA since address type is SiteMainAddress - // addressPartner should Generate new bpnA, and it will be different from legalAddress since type is SiteMainAddress - // Site should Generate new bpnS, and it will be the same MainAddress as addressPartner since address type is SiteMainAddress + // addressPartner should use null, since it does not create when type is SiteMainAddress + // Site should Generate new bpnS assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedLegalEntity?.bpnLReference?.referenceType) - assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedAddress?.bpnAReference?.referenceType) + assertNull(resultedAddress?.bpnAReference?.referenceType) assertEquals(BpnReferenceType.BpnRequestIdentifier, resultedSite?.bpnSReference?.referenceType) assertNotEquals(resultedAddress?.bpnAReference?.referenceValue, resultedLegalEntity?.legalAddress?.bpnAReference?.referenceValue) + assertNotEquals(resultedAddress?.bpnAReference?.referenceValue, resultedSite?.mainAddress?.bpnAReference?.referenceValue) + + val expectedLegalEntity = expectedLegalEntityDto.copy(legalAddress = expectedLogisticAddressDto.copy()) + + val expectedSite = expectedSiteDto.copy(mainAddress = expectedLogisticAddressDto.copy()) - assertEquals(resultedSite?.mainAddress?.bpnAReference?.referenceValue, resultedAddress?.bpnAReference?.referenceValue) + + // ignoring bpnLReference and legalAddress.bpnAReference since they are generated + assertRecursively(resultedLegalEntity).ignoringFields("bpnLReference", "legalAddress.bpnAReference").isEqualTo(expectedLegalEntity) + + // ignoring bpnSReference and mainAddress.bpnAReference since they are generated + assertRecursively(resultedSite).ignoringFields("bpnSReference", "mainAddress.bpnAReference").isEqualTo(expectedSite) } @@ -181,5 +243,12 @@ class CleaningServiceDummyTest @Autowired constructor( return TaskStepReservationResponse(listOf(TaskStepReservationEntryDto(UUID.randomUUID().toString(), fullDto)), Instant.MIN) } + fun assertRecursively(actual: T): RecursiveComparisonAssert<*> { + return Assertions.assertThat(actual) + .usingRecursiveComparison() + .ignoringCollectionOrder() + .ignoringAllOverriddenEquals() + .ignoringFieldsOfTypes(Instant::class.java) + } } diff --git a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt index 44d632166..3cb5b8f1c 100644 --- a/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt +++ b/bpdm-cleaning-service-dummy/src/test/kotlin/org/eclipse/tractusx/bpdm/cleaning/testdata/CommonValues.kt @@ -20,12 +20,18 @@ package org.eclipse.tractusx.bpdm.cleaning.testdata import com.neovisionaries.i18n.CountryCode +import org.eclipse.tractusx.bpdm.cleaning.service.toBusinessPartnerClassificationDto +import org.eclipse.tractusx.bpdm.cleaning.service.toLegalEntityIdentifierDto +import org.eclipse.tractusx.bpdm.cleaning.service.toLegalEntityState +import org.eclipse.tractusx.bpdm.cleaning.service.toSiteState import org.eclipse.tractusx.bpdm.common.dto.* import org.eclipse.tractusx.bpdm.common.model.BusinessStateType import org.eclipse.tractusx.bpdm.common.model.ClassificationType -import org.eclipse.tractusx.orchestrator.api.model.BusinessPartnerGenericDto +import org.eclipse.tractusx.orchestrator.api.model.* +import org.eclipse.tractusx.orchestrator.api.model.LegalEntityDto +import org.eclipse.tractusx.orchestrator.api.model.LogisticAddressDto import org.eclipse.tractusx.orchestrator.api.model.PhysicalPostalAddressDto -import org.eclipse.tractusx.orchestrator.api.model.PostalAddressDto +import org.eclipse.tractusx.orchestrator.api.model.SiteDto import org.eclipse.tractusx.orchestrator.api.model.StreetDto import java.time.LocalDateTime @@ -34,6 +40,8 @@ import java.time.LocalDateTime */ object CommonValues { + val fixedTaskId = "taskid-123123" + val nameParts = listOf("Part1", "Part2") const val shortName = "ShortName" val identifiers = listOf( @@ -132,5 +140,30 @@ object CommonValues { postalAddress = postalAddressForSite ) + val expectedLegalEntityDto = LegalEntityDto( + hasChanged = true, + legalName = nameParts.joinToString(" "), + legalShortName = shortName, + identifiers = identifiers.map { it.toLegalEntityIdentifierDto() }, + legalForm = legalForm, + states = states.map { it.toLegalEntityState() }, + classifications = classifications.map { it.toBusinessPartnerClassificationDto() } + ) + + val expectedSiteDto = SiteDto( + hasChanged = true, + name = nameParts.joinToString(" "), + states = states.map { it.toSiteState() }, + ) + + val expectedLogisticAddressDto = LogisticAddressDto( + + hasChanged = true, + name = nameParts.joinToString(" "), + states = emptyList(), + identifiers = emptyList(), + physicalPostalAddress = physicalPostalAddress + ) + } \ No newline at end of file