From 44bed78d19ca957ff1c7a7da7ac6f58268685e21 Mon Sep 17 00:00:00 2001 From: Jaro Hartmann Date: Tue, 30 Jan 2024 14:32:47 +0100 Subject: [PATCH] feat(irs-api):[#344] Add test case for recursive IRS flow --- .../irs/IrsWireMockIntegrationTest.java | 235 ++++++++---------- .../tractusx/irs/WireMockTestConfig.java | 127 ++++++++-- .../testing/wiremock/DtrWiremockConfig.java | 13 + .../SubmodelFacadeWiremockConfig.java | 9 +- 4 files changed, 236 insertions(+), 148 deletions(-) diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java index 0aa067bb31..1b93697317 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java @@ -20,54 +20,46 @@ package org.eclipse.tractusx.irs; import static com.github.tomakehurst.wiremock.client.WireMock.containing; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; -import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.tractusx.irs.WireMockTestConfig.createEndpointDataReference; -import static org.eclipse.tractusx.irs.bpdm.BpdmWireMockConfig.bpdmResponse; -import static org.eclipse.tractusx.irs.semanticshub.SemanticHubWireMockConfig.batchSchemaResponse200; -import static org.eclipse.tractusx.irs.semanticshub.SemanticHubWireMockConfig.singleLevelBomAsBuiltSchemaResponse200; +import static org.eclipse.tractusx.irs.WireMockTestConfig.randomUUID; +import static org.eclipse.tractusx.irs.WireMockTestConfig.successfulDataRequests; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.DISCOVERY_FINDER_PATH; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.DISCOVERY_FINDER_URL; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.EDC_DISCOVERY_PATH; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.TEST_BPN; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.postDiscoveryFinder200; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.postDiscoveryFinder404; -import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.postEdcDiscovery200; import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.postEdcDiscoveryEmpty200; -import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.DATAPLANE_PUBLIC_PATH; +import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.DATAPLANE_PUBLIC_URL; import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.LOOKUP_SHELLS_TEMPLATE; import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.PUBLIC_LOOKUP_SHELLS_PATH; import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.PUBLIC_SHELL_DESCRIPTORS_PATH; import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.SHELL_DESCRIPTORS_TEMPLATE; import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.getLookupShells200; import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.getShellDescriptor200; -import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.lookupShellsResponse; +import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.submodelDescriptor; import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_CATALOG; import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_NEGOTIATE; import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_STATE; import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_TRANSFER; -import static org.eclipse.tractusx.irs.testing.wiremock.WireMockConfig.responseWithStatus; -import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.List; +import java.util.Objects; import com.github.tomakehurst.wiremock.junit5.WireMockTest; -import org.apache.commons.codec.binary.Base64; import org.awaitility.Awaitility; import org.eclipse.tractusx.irs.bpdm.BpdmWireMockConfig; import org.eclipse.tractusx.irs.component.JobHandle; import org.eclipse.tractusx.irs.component.Jobs; -import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.RegisterJob; -import org.eclipse.tractusx.irs.component.enums.Direction; import org.eclipse.tractusx.irs.component.enums.JobState; +import org.eclipse.tractusx.irs.data.StringMapper; import org.eclipse.tractusx.irs.edc.client.EndpointDataReferenceStorage; import org.eclipse.tractusx.irs.semanticshub.AspectModels; import org.eclipse.tractusx.irs.semanticshub.SemanticHubWireMockConfig; @@ -75,15 +67,17 @@ import org.eclipse.tractusx.irs.services.SemanticHubService; import org.eclipse.tractusx.irs.services.validation.SchemaNotFoundException; import org.eclipse.tractusx.irs.testing.containers.MinioContainer; +import org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig; import org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig; import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cache.CacheManager; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.DynamicPropertyRegistry; @@ -94,7 +88,6 @@ @WireMockTest(httpPort = 8085) @Testcontainers @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WireMockTestConfig.class) -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) @ContextConfiguration(initializers = IrsWireMockIntegrationTest.MinioConfigInitializer.class) @ActiveProfiles("integrationtest") class IrsWireMockIntegrationTest { @@ -111,11 +104,19 @@ class IrsWireMockIntegrationTest { private SemanticHubService semanticHubService; @Autowired private EndpointDataReferenceStorage endpointDataReferenceStorage; + @Autowired + private CacheManager cacheManager; @BeforeAll static void startContainer() { minioContainer.start(); - successfulSemanticModelRequest(); + WireMockTestConfig.successfulSemanticModelRequest(); + } + + @AfterEach + void tearDown() { + cacheManager.getCacheNames() + .forEach(cacheName -> Objects.requireNonNull(cacheManager.getCache(cacheName)).clear()); } @AfterAll @@ -146,7 +147,7 @@ static void configureProperties(DynamicPropertyRegistry registry) { @Test void shouldStartApplicationAndCollectSemanticModels() throws SchemaNotFoundException { // Arrange - successfulSemanticModelRequest(); + WireMockTestConfig.successfulSemanticModelRequest(); // Act final AspectModels allAspectModels = semanticHubService.getAllAspectModels(); @@ -156,22 +157,23 @@ void shouldStartApplicationAndCollectSemanticModels() throws SchemaNotFoundExcep } @Test - void shouldStartJob() { + void shouldStopJobAfterDepthIsReached() { // Arrange - final String globalAssetId = "globalAssetId"; + final String globalAssetIdLevel1 = "globalAssetId"; + final String globalAssetIdLevel2 = "urn:uuid:6d505432-8b31-4966-9514-4b753372683f"; - successfulSemanticModelRequest(); - successfulSemanticHubRequests(); - successfulDiscovery(); - successfulRegistryNegotiation(); - successfulDtrRequest(globalAssetId); - successfulAssetNegotiation(); + WireMockTestConfig.successfulSemanticModelRequest(); + WireMockTestConfig.successfulSemanticHubRequests(); + WireMockTestConfig.successfulDiscovery(); - successfulDataRequests(); + successfulRegistryAndDataRequest(globalAssetIdLevel1, "Cathode", TEST_BPN, "integrationtesting/batch-1.json", + "integrationtesting/singleLevelBomAsBuilt-1.json"); + successfulRegistryAndDataRequest(globalAssetIdLevel2, "Polyamid", TEST_BPN, "integrationtesting/batch-2.json", + "integrationtesting/singleLevelBomAsBuilt-2.json"); - successfulBpdmRequests(); + WireMockTestConfig.successfulBpdmRequests(); - final RegisterJob request = jobRequest(globalAssetId, TEST_BPN); + final RegisterJob request = WireMockTestConfig.jobRequest(globalAssetIdLevel1, TEST_BPN, 1); // Act final JobHandle jobHandle = irsService.registerItemJob(request); @@ -181,8 +183,8 @@ void shouldStartJob() { Jobs jobForJobId = irsService.getJobForJobId(jobHandle.getId(), true); // Assert - verifyDiscoveryCalls(1); - verifyNegotiationCalls(3); + WireMockTestConfig.verifyDiscoveryCalls(1); + WireMockTestConfig.verifyNegotiationCalls(3); assertThat(jobForJobId.getJob().getState()).isEqualTo(JobState.COMPLETED); assertThat(jobForJobId.getShells()).hasSize(2); @@ -193,10 +195,10 @@ void shouldStartJob() { @Test void shouldCreateTombstoneWhenDiscoveryServiceNotAvailable() { // Arrange - successfulSemanticModelRequest(); + WireMockTestConfig.successfulSemanticModelRequest(); stubFor(postDiscoveryFinder404()); final String globalAssetId = "globalAssetId"; - final RegisterJob request = jobRequest(globalAssetId, TEST_BPN); + final RegisterJob request = WireMockTestConfig.jobRequest(globalAssetId, TEST_BPN, 1); // Act final JobHandle jobHandle = irsService.registerItemJob(request); @@ -218,11 +220,12 @@ void shouldCreateTombstoneWhenDiscoveryServiceNotAvailable() { @Test void shouldCreateTombstoneWhenEdcDiscoveryIsEmpty() { // Arrange - successfulSemanticModelRequest(); + WireMockTestConfig.successfulSemanticModelRequest(); stubFor(postDiscoveryFinder200()); stubFor(postEdcDiscoveryEmpty200()); final String globalAssetId = "globalAssetId"; - final RegisterJob request = jobRequest(globalAssetId, TEST_BPN); + final RegisterJob request = WireMockTestConfig.jobRequest(globalAssetId, TEST_BPN, 1); + // Act final JobHandle jobHandle = irsService.registerItemJob(request); @@ -231,8 +234,7 @@ void shouldCreateTombstoneWhenEdcDiscoveryIsEmpty() { waitForCompletion(jobHandle); final Jobs jobForJobId = irsService.getJobForJobId(jobHandle.getId(), true); - verify(1, postRequestedFor(urlPathEqualTo(DISCOVERY_FINDER_PATH))); - verify(1, postRequestedFor(urlPathEqualTo(EDC_DISCOVERY_PATH))); + WireMockTestConfig.verifyDiscoveryCalls(1); assertThat(jobForJobId.getJob().getState()).isEqualTo(JobState.COMPLETED); assertThat(jobForJobId.getShells()).isEmpty(); @@ -240,108 +242,91 @@ void shouldCreateTombstoneWhenEdcDiscoveryIsEmpty() { assertThat(jobForJobId.getTombstones()).hasSize(1); } - private static void successfulSemanticModelRequest() { - stubFor(get(urlPathEqualTo("/models")).willReturn( - responseWithStatus(200).withBodyFile("semantichub/all-models-page-IT.json"))); - } + @Test + void shouldStartRecursiveProcesses() { + // Arrange + final String globalAssetIdLevel1 = "urn:uuid:334cce52-1f52-4bc9-9dd1-410bbe497bbc"; + final String globalAssetIdLevel2 = "urn:uuid:7e4541ea-bb0f-464c-8cb3-021abccbfaf5"; + final String globalAssetIdLevel3 = "urn:uuid:a314ad6b-77ea-417e-ae2d-193b3e249e99"; - private static RegisterJob jobRequest(final String globalAssetId, final String bpn) { - return RegisterJob.builder() - .key(PartChainIdentificationKey.builder().bpn(bpn).globalAssetId(globalAssetId).build()) - .depth(1) - .aspects(List.of("Batch", "SingleLevelBomAsBuilt")) - .collectAspects(true) - .lookupBPNs(true) - .direction(Direction.DOWNWARD) - .build(); - } + WireMockTestConfig.successfulSemanticModelRequest(); + WireMockTestConfig.successfulSemanticHubRequests(); + WireMockTestConfig.successfulDiscovery(); - private void waitForCompletion(final JobHandle jobHandle) { - Awaitility.await() - .timeout(Duration.ofSeconds(35)) - .pollInterval(Duration.ofSeconds(1)) - .until(() -> irsService.getJobForJobId(jobHandle.getId(), false) - .getJob() - .getState() - .equals(JobState.COMPLETED)); - } + successfulRegistryAndDataRequest(globalAssetIdLevel1, "Cathode", TEST_BPN, "integrationtesting/batch-1.json", + "integrationtesting/singleLevelBomAsBuilt-1.json"); + successfulRegistryAndDataRequest(globalAssetIdLevel2, "Polyamid", TEST_BPN, "integrationtesting/batch-2.json", + "integrationtesting/singleLevelBomAsBuilt-2.json"); + successfulRegistryAndDataRequest(globalAssetIdLevel3, "GenericChemical", TEST_BPN, + "integrationtesting/batch-3.json", "integrationtesting/singleLevelBomAsBuilt-3.json"); - private void successfulRegistryNegotiation() { - final String negotiationId = "1bbaec6e-c316-4e1e-8258-c07a648cc43c"; - final String transferProcessId = "1b21e963-0bc5-422a-b30d-fd3511861d88"; - final String edcAssetId = "registry-asset"; - final String contractAgreementId = SubmodelFacadeWiremockConfig.prepareNegotiation(negotiationId, - transferProcessId, - "7681f966-36ea-4542-b5ea-0d0db81967de:registry-asset:a6144a2e-c1b1-4ec6-96e1-a221da134e4f", edcAssetId); - endpointDataReferenceStorage.put(contractAgreementId, createEndpointDataReference(contractAgreementId)); - } + WireMockTestConfig.successfulBpdmRequests(); - private void successfulAssetNegotiation() { - final String negotiationId = "1bbaec6e-c316-4e1e-8258-c07a648cc43c"; - final String transferProcessId = "1b21e963-0bc5-422a-b30d-fd3511861d88"; - final String edcAssetId = "urn:uuid:f8196d6a-1664-4531-bdee-f15dbb1daf26"; - final String contractAgreementId = SubmodelFacadeWiremockConfig.prepareNegotiation(negotiationId, - transferProcessId, - "7681f966-36ea-4542-b5ea-0d0db81967de:urn:uuid:f8196d6a-1664-4531-bdee-f15dbb1daf26:a6144a2e-c1b1-4ec6-96e1-a221da134e4f", - edcAssetId); - endpointDataReferenceStorage.put(contractAgreementId, createEndpointDataReference(contractAgreementId)); - } + final RegisterJob request = WireMockTestConfig.jobRequest(globalAssetIdLevel1, TEST_BPN, 4); - private static void successfulDiscovery() { - stubFor(postDiscoveryFinder200()); - stubFor(postEdcDiscovery200()); - } - - private static String encodedId(final String secondDTR) { - return Base64.encodeBase64String(secondDTR.getBytes(StandardCharsets.UTF_8)); - } + // Act + final JobHandle jobHandle = irsService.registerItemJob(request); - private static void verifyDiscoveryCalls(final int times) { - verify(times, postRequestedFor(urlPathEqualTo(DISCOVERY_FINDER_PATH))); - verify(times, postRequestedFor(urlPathEqualTo(EDC_DISCOVERY_PATH))); - } + // Assert + assertThat(jobHandle.getId()).isNotNull(); + waitForCompletion(jobHandle); + final Jobs jobForJobId = irsService.getJobForJobId(jobHandle.getId(), false); + System.out.println(StringMapper.mapToString(jobForJobId)); - private static void verifyNegotiationCalls(final int times) { - verify(times, postRequestedFor(urlPathEqualTo(PATH_NEGOTIATE))); - verify(times, postRequestedFor(urlPathEqualTo(PATH_CATALOG))); - verify(times * 2, getRequestedFor(urlPathMatching(PATH_NEGOTIATE + "/.*"))); - verify(times, getRequestedFor(urlPathMatching(PATH_NEGOTIATE + "/.*" + PATH_STATE))); - verify(times, postRequestedFor(urlPathEqualTo(PATH_TRANSFER))); - verify(times * 2, getRequestedFor(urlPathMatching(PATH_TRANSFER + "/.*"))); - verify(times, getRequestedFor(urlPathMatching(PATH_TRANSFER + "/.*" + PATH_STATE))); - } + assertThat(jobForJobId.getJob().getState()).isEqualTo(JobState.COMPLETED); + assertThat(jobForJobId.getShells()).hasSize(3); + assertThat(jobForJobId.getRelationships()).hasSize(2); + assertThat(jobForJobId.getTombstones()).isEmpty(); + assertThat(jobForJobId.getSubmodels()).hasSize(6); - private static void successfulBpdmRequests() { - stubFor(get(urlPathMatching("/legal-entities/.*")).willReturn( - responseWithStatus(200).withBody(bpdmResponse(TEST_BPN, "Company Name")))); + WireMockTestConfig.verifyDiscoveryCalls(1); + WireMockTestConfig.verifyNegotiationCalls(6); } - private static void successfulDataRequests() { - stubFor(get( - urlPathMatching(DATAPLANE_PUBLIC_PATH + "/urn:uuid:f53db6ef-7a58-4326-9169-0ae198b85dbf")).willReturn( - responseWithStatus(200).withBodyFile("integrationtesting/batch-1.json"))); - stubFor(get( - urlPathMatching(DATAPLANE_PUBLIC_PATH + "/urn:uuid:0e413809-966b-4107-aae5-aeb28bcdaadf")).willReturn( - responseWithStatus(200).withBodyFile("integrationtesting/singleLevelBomAsBuilt-1.json"))); + private void successfulRegistryAndDataRequest(final String globalAssetId, final String idShort, final String bpn, + final String batchFileName, final String sbomFileName) { + + final String edcAssetId = WireMockTestConfig.randomUUIDwithPrefix(); + final String batchId = WireMockTestConfig.randomUUIDwithPrefix(); + final String batch = submodelDescriptor(DATAPLANE_PUBLIC_URL, edcAssetId, + DiscoveryServiceWiremockConfig.CONTROLPLANE_PUBLIC_URL, "Batch", batchId, + "urn:samm:io.catenax.batch:2.0.0#Batch"); + successfulDataRequests(batchId, batchFileName); + + final String sbomId = WireMockTestConfig.randomUUIDwithPrefix(); + final String singleLevelBomAsBuilt = submodelDescriptor(DATAPLANE_PUBLIC_URL, edcAssetId, + DiscoveryServiceWiremockConfig.CONTROLPLANE_PUBLIC_URL, "SingleLevelBomAsBuilt", sbomId, + "urn:bamm:io.catenax.single_level_bom_as_built:2.0.0#SingleLevelBomAsBuilt"); + final List submodelDescriptors = List.of(batch, singleLevelBomAsBuilt); + successfulDataRequests(sbomId, sbomFileName); + successfulNegotiation(edcAssetId); + + final String shellId = WireMockTestConfig.randomUUIDwithPrefix(); + final String registryEdcAssetId = "registry-asset"; + successfulNegotiation(registryEdcAssetId); + stubFor(getLookupShells200(PUBLIC_LOOKUP_SHELLS_PATH, List.of(shellId)).withQueryParam("assetIds", + containing(globalAssetId))); + stubFor(getShellDescriptor200(PUBLIC_SHELL_DESCRIPTORS_PATH + WireMockTestConfig.encodedId(shellId), bpn, + submodelDescriptors, globalAssetId, shellId, idShort)); } - private static void successfulSemanticHubRequests() { - stubFor(batchSchemaResponse200()); - stubFor(singleLevelBomAsBuiltSchemaResponse200()); + private void successfulNegotiation(final String edcAssetId) { + final String negotiationId = randomUUID(); + final String transferProcessId = randomUUID(); + final String contractAgreementId = "%s:%s:%s".formatted(randomUUID(), edcAssetId, randomUUID()); + SubmodelFacadeWiremockConfig.prepareNegotiation(negotiationId, transferProcessId, contractAgreementId, + edcAssetId); + endpointDataReferenceStorage.put(contractAgreementId, createEndpointDataReference(contractAgreementId)); } - private static void successfulDtrRequest(final String startId) { - stubFor(getLookupShells200(PUBLIC_LOOKUP_SHELLS_PATH).withQueryParam("assetIds", containing(startId))); - stubFor(getShellDescriptor200( - PUBLIC_SHELL_DESCRIPTORS_PATH + encodedId("urn:uuid:21f7ebea-fa8a-410c-a656-bd9082e67dcf"))); - - final String secondDTR = "urn:uuid:6d505432-8b31-4966-9514-4b753372683f"; - stubFor(get(urlPathEqualTo(PUBLIC_LOOKUP_SHELLS_PATH)).withQueryParam("assetIds", - containing("urn:uuid:7e4541ea-bb0f-464c-8cb3-021abccbfaf5")) - .willReturn(responseWithStatus(200).withBody( - lookupShellsResponse(List.of(secondDTR))))); - - stubFor(getShellDescriptor200(PUBLIC_SHELL_DESCRIPTORS_PATH + encodedId(secondDTR))); + private void waitForCompletion(final JobHandle jobHandle) { + Awaitility.await() + .timeout(Duration.ofSeconds(35)) + .pollInterval(Duration.ofSeconds(1)) + .until(() -> irsService.getJobForJobId(jobHandle.getId(), false) + .getJob() + .getState() + .equals(JobState.COMPLETED)); } public static class MinioConfigInitializer diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/WireMockTestConfig.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/WireMockTestConfig.java index 24968aee88..2db79977e6 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/WireMockTestConfig.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/WireMockTestConfig.java @@ -19,24 +19,49 @@ ********************************************************************************/ package org.eclipse.tractusx.irs; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; +import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static org.eclipse.tractusx.irs.bpdm.BpdmWireMockConfig.bpdmResponse; import static org.eclipse.tractusx.irs.configuration.RestTemplateConfig.BPDM_REST_TEMPLATE; import static org.eclipse.tractusx.irs.configuration.RestTemplateConfig.DISCOVERY_REST_TEMPLATE; import static org.eclipse.tractusx.irs.configuration.RestTemplateConfig.DTR_REST_TEMPLATE; import static org.eclipse.tractusx.irs.configuration.RestTemplateConfig.EDC_REST_TEMPLATE; import static org.eclipse.tractusx.irs.configuration.RestTemplateConfig.NO_ERROR_REST_TEMPLATE; import static org.eclipse.tractusx.irs.configuration.RestTemplateConfig.SEMHUB_REST_TEMPLATE; +import static org.eclipse.tractusx.irs.semanticshub.SemanticHubWireMockConfig.batchSchemaResponse200; +import static org.eclipse.tractusx.irs.semanticshub.SemanticHubWireMockConfig.singleLevelBomAsBuiltSchemaResponse200; +import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.DISCOVERY_FINDER_PATH; +import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.EDC_DISCOVERY_PATH; +import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.TEST_BPN; +import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.postDiscoveryFinder200; +import static org.eclipse.tractusx.irs.testing.wiremock.DiscoveryServiceWiremockConfig.postEdcDiscovery200; +import static org.eclipse.tractusx.irs.testing.wiremock.DtrWiremockConfig.DATAPLANE_PUBLIC_PATH; import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.DATAPLANE_HOST; +import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_CATALOG; import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_DATAPLANE_PUBLIC; +import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_NEGOTIATE; +import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_STATE; +import static org.eclipse.tractusx.irs.testing.wiremock.SubmodelFacadeWiremockConfig.PATH_TRANSFER; +import static org.eclipse.tractusx.irs.testing.wiremock.WireMockConfig.responseWithStatus; import static org.eclipse.tractusx.irs.testing.wiremock.WireMockConfig.restTemplateProxy; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; import java.util.Map; +import java.util.UUID; import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.edc.policy.model.PolicyRegistrationTypes; import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; +import org.eclipse.tractusx.irs.component.RegisterJob; +import org.eclipse.tractusx.irs.component.enums.Direction; import org.eclipse.tractusx.irs.data.StringMapper; import org.eclipse.tractusx.irs.edc.client.configuration.JsonLdConfiguration; import org.eclipse.tractusx.irs.edc.client.model.EDRAuthCode; @@ -54,25 +79,6 @@ public class WireMockTestConfig { public static final int HTTP_PORT = 8085; private static final String PROXY_SERVER_HOST = "127.0.0.1"; - public static EndpointDataReference createEndpointDataReference(final String contractAgreementId) { - final EDRAuthCode edrAuthCode = EDRAuthCode.builder() - .cid(contractAgreementId) - .dad("test") - .exp(9999999999L) - .build(); - final String b64EncodedAuthCode = Base64.getUrlEncoder() - .encodeToString(StringMapper.mapToString(edrAuthCode) - .getBytes(StandardCharsets.UTF_8)); - final String jwtToken = "eyJhbGciOiJSUzI1NiJ9." + b64EncodedAuthCode + ".test"; - return EndpointDataReference.Builder.newInstance() - .authKey("testkey") - .authCode(jwtToken) - .properties( - Map.of(JsonLdConfiguration.NAMESPACE_EDC_CID, contractAgreementId)) - .endpoint(DATAPLANE_HOST + PATH_DATAPLANE_PUBLIC) - .build(); - } - @Primary @Profile("integrationtest") @Bean(DTR_REST_TEMPLATE) @@ -124,4 +130,87 @@ RestTemplate bpdmRestTemplate() { RestTemplate semanticHubRestTemplate() { return restTemplateProxy(PROXY_SERVER_HOST, HTTP_PORT); } + + public static EndpointDataReference createEndpointDataReference(final String contractAgreementId) { + final EDRAuthCode edrAuthCode = EDRAuthCode.builder() + .cid(contractAgreementId) + .dad("test") + .exp(9999999999L) + .build(); + final String b64EncodedAuthCode = Base64.getUrlEncoder() + .encodeToString(StringMapper.mapToString(edrAuthCode) + .getBytes(StandardCharsets.UTF_8)); + final String jwtToken = "eyJhbGciOiJSUzI1NiJ9." + b64EncodedAuthCode + ".test"; + return EndpointDataReference.Builder.newInstance() + .authKey("testkey") + .authCode(jwtToken) + .properties( + Map.of(JsonLdConfiguration.NAMESPACE_EDC_CID, contractAgreementId)) + .endpoint(DATAPLANE_HOST + PATH_DATAPLANE_PUBLIC) + .build(); + } + + static void successfulSemanticModelRequest() { + stubFor(get(urlPathEqualTo("/models")).willReturn( + responseWithStatus(200).withBodyFile("semantichub/all-models-page-IT.json"))); + } + + static RegisterJob jobRequest(final String globalAssetId, final String bpn, final int depth) { + return RegisterJob.builder() + .key(PartChainIdentificationKey.builder().bpn(bpn).globalAssetId(globalAssetId).build()) + .depth(depth) + .aspects(List.of("Batch", "SingleLevelBomAsBuilt")) + .collectAspects(true) + .lookupBPNs(true) + .direction(Direction.DOWNWARD) + .build(); + } + + static void successfulDiscovery() { + stubFor(postDiscoveryFinder200()); + stubFor(postEdcDiscovery200()); + } + + static String encodedId(final String shellId) { + return org.apache.commons.codec.binary.Base64.encodeBase64String(shellId.getBytes(StandardCharsets.UTF_8)); + } + + static void verifyDiscoveryCalls(final int times) { + verify(times, postRequestedFor(urlPathEqualTo(DISCOVERY_FINDER_PATH))); + verify(times, postRequestedFor(urlPathEqualTo(EDC_DISCOVERY_PATH))); + } + + static void verifyNegotiationCalls(final int times) { + verify(times, postRequestedFor(urlPathEqualTo(PATH_NEGOTIATE))); + verify(times, postRequestedFor(urlPathEqualTo(PATH_CATALOG))); + verify(times * 2, getRequestedFor(urlPathMatching(PATH_NEGOTIATE + "/.*"))); + verify(times, getRequestedFor(urlPathMatching(PATH_NEGOTIATE + "/.*" + PATH_STATE))); + verify(times, postRequestedFor(urlPathEqualTo(PATH_TRANSFER))); + verify(times * 2, getRequestedFor(urlPathMatching(PATH_TRANSFER + "/.*"))); + verify(times, getRequestedFor(urlPathMatching(PATH_TRANSFER + "/.*" + PATH_STATE))); + } + + static void successfulBpdmRequests() { + stubFor(get(urlPathMatching("/legal-entities/.*")).willReturn( + responseWithStatus(200).withBody(bpdmResponse(TEST_BPN, "Company Name")))); + } + + static void successfulDataRequests(final String assetId, final String fileName) { + stubFor(get(urlPathMatching(DATAPLANE_PUBLIC_PATH + "/" + assetId)).willReturn( + responseWithStatus(200).withBodyFile(fileName))); + } + + static void successfulSemanticHubRequests() { + stubFor(batchSchemaResponse200()); + stubFor(singleLevelBomAsBuiltSchemaResponse200()); + } + + static String randomUUIDwithPrefix() { + final String uuidPrefix = "urn:uuid:"; + return uuidPrefix + randomUUID(); + } + + static String randomUUID() { + return UUID.randomUUID().toString(); + } } diff --git a/irs-testing/src/main/java/org/eclipse/tractusx/irs/testing/wiremock/DtrWiremockConfig.java b/irs-testing/src/main/java/org/eclipse/tractusx/irs/testing/wiremock/DtrWiremockConfig.java index 17332ce160..30367044e2 100644 --- a/irs-testing/src/main/java/org/eclipse/tractusx/irs/testing/wiremock/DtrWiremockConfig.java +++ b/irs-testing/src/main/java/org/eclipse/tractusx/irs/testing/wiremock/DtrWiremockConfig.java @@ -74,6 +74,14 @@ public static MappingBuilder getShellDescriptor200(final String urlRegex) { "EngineeringPlastics", "urn:uuid:9ce43b21-75e3-4cea-b13e-9a34f4f6822a", specificAssetIds))); } + @SuppressWarnings("PMD.UseObjectForClearerAPI") // used only for testing + public static MappingBuilder getShellDescriptor200(final String urlRegex, final String bpn, final List submodelDescriptors, + final String globalAssetId, final String shellId, final String idShort) { + final List specificAssetIds = List.of(specificAssetId("manufacturerId", bpn)); + return get(urlPathMatching(urlRegex)).willReturn(responseWithStatus(STATUS_CODE_OK).withBody( + assetAdministrationShellResponse(submodelDescriptors, globalAssetId, idShort, shellId, specificAssetIds))); + } + public static String assetAdministrationShellResponse(final List submodelDescriptors, final String globalAssetId, final String idShort, final String shellId, final List specificAssetIds) { @@ -169,6 +177,11 @@ public static MappingBuilder getLookupShells200(final String lookupShellsPath) { lookupShellsResponse(List.of("urn:uuid:21f7ebea-fa8a-410c-a656-bd9082e67dcf")))); } + public static MappingBuilder getLookupShells200(final String lookupShellsPath, final List shellIds) { + return get(urlPathEqualTo(lookupShellsPath)).willReturn(responseWithStatus(STATUS_CODE_OK).withBody( + lookupShellsResponse(shellIds))); + } + public static MappingBuilder getLookupShells200Empty() { return get(urlPathMatching(LOOKUP_SHELLS_PATH + ".*")).willReturn( responseWithStatus(STATUS_CODE_OK).withBody(lookupShellsResponse(List.of()))); diff --git a/irs-testing/src/main/java/org/eclipse/tractusx/irs/testing/wiremock/SubmodelFacadeWiremockConfig.java b/irs-testing/src/main/java/org/eclipse/tractusx/irs/testing/wiremock/SubmodelFacadeWiremockConfig.java index 3269322ab1..361423cf05 100644 --- a/irs-testing/src/main/java/org/eclipse/tractusx/irs/testing/wiremock/SubmodelFacadeWiremockConfig.java +++ b/irs-testing/src/main/java/org/eclipse/tractusx/irs/testing/wiremock/SubmodelFacadeWiremockConfig.java @@ -54,13 +54,15 @@ private SubmodelFacadeWiremockConfig() { } public static String prepareNegotiation() { - return prepareNegotiation("1bbaec6e-c316-4e1e-8258-c07a648cc43c", "1b21e963-0bc5-422a-b30d-fd3511861d88", - "7681f966-36ea-4542-b5ea-0d0db81967de:5a7ab616-989f-46ae-bdf2-32027b9f6ee6-31b614f5-ec14-4ed2-a509-e7b7780083e7:a6144a2e-c1b1-4ec6-96e1-a221da134e4f", + final String contractAgreementId = "7681f966-36ea-4542-b5ea-0d0db81967de:5a7ab616-989f-46ae-bdf2-32027b9f6ee6-31b614f5-ec14-4ed2-a509-e7b7780083e7:a6144a2e-c1b1-4ec6-96e1-a221da134e4f"; + prepareNegotiation("1bbaec6e-c316-4e1e-8258-c07a648cc43c", "1b21e963-0bc5-422a-b30d-fd3511861d88", + contractAgreementId, "5a7ab616-989f-46ae-bdf2-32027b9f6ee6-31b614f5-ec14-4ed2-a509-e7b7780083e7"); + return contractAgreementId; } @SuppressWarnings("PMD.UseObjectForClearerAPI") // used only for testing - public static String prepareNegotiation(final String negotiationId, final String transferProcessId, + public static void prepareNegotiation(final String negotiationId, final String transferProcessId, final String contractAgreementId, final String edcAssetId) { stubFor(post(urlPathEqualTo(PATH_CATALOG)).willReturn(WireMockConfig.responseWithStatus(STATUS_CODE_OK) .withBody(getCatalogResponse(edcAssetId, @@ -93,7 +95,6 @@ public static String prepareNegotiation(final String negotiationId, final String .withBody( getTransferConfirmedResponse(transferProcessId, transferProcessState, edcAssetId, contractAgreementId)))); - return contractAgreementId; } private static String startTransferProcessResponse(final String transferProcessId) {