diff --git a/CHANGELOG.md b/CHANGELOG.md index b659a7b6db..8f15efd20b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Fixed +- BPN is now passed on correctly while traversing the item graph +- Tombstone is created if no BPN is available for a child item ## [3.2.1] - 2023-07-19 ### Fixed diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASRecursiveJobHandler.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASRecursiveJobHandler.java index c997a7aac4..d79b069e0a 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASRecursiveJobHandler.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASRecursiveJobHandler.java @@ -25,6 +25,7 @@ import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.connector.job.MultiTransferJob; import org.eclipse.tractusx.irs.connector.job.RecursiveJobHandler; @@ -44,7 +45,9 @@ public AASRecursiveJobHandler(final TreeRecursiveLogic logic) { public Stream initiate(final MultiTransferJob job) { log.info("Initiating request for job {}", job.getJobIdString()); final var partId = job.getGlobalAssetId(); - final var dataRequest = ItemDataRequest.rootNode(partId); + final var bpn = job.getJobParameter().getBpn(); + final var dataRequest = ItemDataRequest.rootNode( + PartChainIdentificationKey.builder().globalAssetId(partId).bpn(bpn).build()); return Stream.of(dataRequest); } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcess.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcess.java index 109a4704ba..f64d245675 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcess.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcess.java @@ -29,6 +29,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.ToString; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.connector.job.TransferProcess; /** @@ -40,12 +41,12 @@ @ToString public class AASTransferProcess implements TransferProcess { - private final List idsToProcess = new ArrayList<>(); + private final List idsToProcess = new ArrayList<>(); @SuppressWarnings("PMD.ShortVariable") private String id; private Integer depth; - public void addIdsToProcess(final List childIds) { + public void addIdsToProcess(final List childIds) { idsToProcess.addAll(childIds); } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcessManager.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcessManager.java index e394066f32..4d41531843 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcessManager.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcessManager.java @@ -34,6 +34,7 @@ import org.eclipse.tractusx.irs.common.persistence.BlobPersistence; import org.eclipse.tractusx.irs.common.persistence.BlobPersistenceException; import org.eclipse.tractusx.irs.component.JobParameter; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.connector.job.ResponseStatus; import org.eclipse.tractusx.irs.connector.job.TransferInitiateResponse; import org.eclipse.tractusx.irs.connector.job.TransferProcessManager; @@ -80,7 +81,7 @@ private Runnable getRunnable(final ItemDataRequest dataRequest, return () -> { final AASTransferProcess aasTransferProcess = new AASTransferProcess(processId, dataRequest.getDepth()); - final String itemId = dataRequest.getItemId(); + final PartChainIdentificationKey itemId = dataRequest.getItemId(); log.info("Starting processing Digital Twin Registry with itemId {}", itemId); final ItemContainer itemContainer = abstractDelegate.process(ItemContainer.builder(), jobData, diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/ItemDataRequest.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/ItemDataRequest.java index c55dedbfe8..9c20123fe5 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/ItemDataRequest.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/ItemDataRequest.java @@ -23,6 +23,7 @@ package org.eclipse.tractusx.irs.aaswrapper.job; import lombok.Value; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.connector.job.DataRequest; /** @@ -31,14 +32,14 @@ @Value public class ItemDataRequest implements DataRequest { - private final String itemId; + private final PartChainIdentificationKey itemId; private final Integer depth; - public static ItemDataRequest rootNode(final String itemId) { + public static ItemDataRequest rootNode(final PartChainIdentificationKey itemId) { return new ItemDataRequest(itemId, 0); } - public static ItemDataRequest nextDepthNode(final String itemId, final Integer currentDepth) { + public static ItemDataRequest nextDepthNode(final PartChainIdentificationKey itemId, final Integer currentDepth) { return new ItemDataRequest(itemId, currentDepth + 1); } } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java index 201b504304..6d62200fd4 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/AbstractDelegate.java @@ -35,6 +35,7 @@ import org.eclipse.tractusx.irs.aaswrapper.job.AASTransferProcess; import org.eclipse.tractusx.irs.aaswrapper.job.ItemContainer; import org.eclipse.tractusx.irs.component.JobParameter; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.assetadministrationshell.Endpoint; import org.eclipse.tractusx.irs.edc.client.EdcSubmodelFacade; import org.eclipse.tractusx.irs.edc.client.ItemNotFoundInCatalogException; @@ -62,7 +63,7 @@ public abstract class AbstractDelegate { * and Tombstones (if requests fail). */ public abstract ItemContainer process(ItemContainer.ItemContainerBuilder itemContainerBuilder, JobParameter jobData, - AASTransferProcess aasTransferProcess, String itemId); + AASTransferProcess aasTransferProcess, PartChainIdentificationKey itemId); /** * Delegates processing to next step if exists or returns filled {@link ItemContainer} @@ -75,7 +76,8 @@ public abstract ItemContainer process(ItemContainer.ItemContainerBuilder itemCon * @return item container with filled data */ protected ItemContainer next(final ItemContainer.ItemContainerBuilder itemContainerBuilder, - final JobParameter jobData, final AASTransferProcess aasTransferProcess, final String itemId) { + final JobParameter jobData, final AASTransferProcess aasTransferProcess, + final PartChainIdentificationKey itemId) { if (this.nextStep != null) { return this.nextStep.process(itemContainerBuilder, jobData, aasTransferProcess, itemId); } @@ -91,7 +93,11 @@ protected String requestSubmodelAsString(final EdcSubmodelFacade submodelFacade, for (final String connectorEndpoint : connectorEndpoints) { addSubmodelToList(submodelFacade, endpoint, submodelPayload, connectorEndpoint); } - return submodelPayload.stream().findFirst().orElseThrow(); + return submodelPayload.stream() + .findFirst() + .orElseThrow(() -> new EdcClientException(String.format( + "Called %s connectorEndpoints but did not get any submodels. Connectors: '%s'", + connectorEndpoints.size(), String.join(", ", connectorEndpoints)))); } private void addSubmodelToList(final EdcSubmodelFacade submodelFacade, final Endpoint endpoint, diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/BpdmDelegate.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/BpdmDelegate.java index 0e084faadd..dfe391c949 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/BpdmDelegate.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/BpdmDelegate.java @@ -31,6 +31,7 @@ import org.eclipse.tractusx.irs.bpdm.BpdmFacade; import org.eclipse.tractusx.irs.component.Bpn; import org.eclipse.tractusx.irs.component.JobParameter; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.Tombstone; import org.eclipse.tractusx.irs.component.enums.ProcessStep; import org.springframework.web.client.RestClientException; @@ -53,7 +54,7 @@ public BpdmDelegate(final AbstractDelegate nextStep, final BpdmFacade bpdmFacade @Override public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContainerBuilder, - final JobParameter jobData, final AASTransferProcess aasTransferProcess, final String itemId) { + final JobParameter jobData, final AASTransferProcess aasTransferProcess, final PartChainIdentificationKey itemId) { if (jobData.isLookupBPNs()) { log.debug("BPN Lookup enabled, collecting BPN information"); @@ -65,12 +66,12 @@ public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContai try { itemContainerBuilder.build() .getBpns() - .forEach(bpn -> lookupBPN(itemContainerBuilder, itemId, bpn, + .forEach(bpn -> lookupBPN(itemContainerBuilder, itemId.getGlobalAssetId(), bpn, requestMetric)); } catch (final RestClientException e) { log.info("Business Partner endpoint could not be retrieved for Item: {}. Creating Tombstone.", itemId); requestMetric.incrementFailed(); - itemContainerBuilder.tombstone(Tombstone.from(itemId, null, e, retryCount, ProcessStep.BPDM_REQUEST)); + itemContainerBuilder.tombstone(Tombstone.from(itemId.getGlobalAssetId(), null, e, retryCount, ProcessStep.BPDM_REQUEST)); } } else { log.debug("BPN lookup disabled, no BPN information will be collected."); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/DigitalTwinDelegate.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/DigitalTwinDelegate.java index 1f07fa6b03..d7ecd56cc5 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/DigitalTwinDelegate.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/DigitalTwinDelegate.java @@ -28,6 +28,7 @@ import org.eclipse.tractusx.irs.aaswrapper.job.AASTransferProcess; import org.eclipse.tractusx.irs.aaswrapper.job.ItemContainer; import org.eclipse.tractusx.irs.component.JobParameter; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.Tombstone; import org.eclipse.tractusx.irs.component.enums.ProcessStep; import org.eclipse.tractusx.irs.registryclient.DigitalTwinRegistryKey; @@ -52,15 +53,15 @@ public DigitalTwinDelegate(final AbstractDelegate nextStep, @Override public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContainerBuilder, final JobParameter jobData, - final AASTransferProcess aasTransferProcess, final String itemId) { + final AASTransferProcess aasTransferProcess, final PartChainIdentificationKey itemId) { try { itemContainerBuilder.shell(digitalTwinRegistryService.fetchShells( - List.of(new DigitalTwinRegistryKey(itemId, jobData.getBpn())) + List.of(new DigitalTwinRegistryKey(itemId.getGlobalAssetId(), itemId.getBpn())) ).stream().findFirst().orElseThrow()); } catch (final RestClientException | RegistryServiceException e) { log.info("Shell Endpoint could not be retrieved for Item: {}. Creating Tombstone.", itemId); - itemContainerBuilder.tombstone(Tombstone.from(itemId, null, e, retryCount, ProcessStep.DIGITAL_TWIN_REQUEST)); + itemContainerBuilder.tombstone(Tombstone.from(itemId.getGlobalAssetId(), null, e, retryCount, ProcessStep.DIGITAL_TWIN_REQUEST)); } if (expectedDepthOfTreeIsNotReached(jobData.getDepth(), aasTransferProcess.getDepth())) { diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegate.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegate.java index 1de59262ed..64593084a7 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegate.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegate.java @@ -25,12 +25,12 @@ import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.irs.aaswrapper.job.AASTransferProcess; import org.eclipse.tractusx.irs.aaswrapper.job.ItemContainer; import org.eclipse.tractusx.irs.component.Bpn; -import org.eclipse.tractusx.irs.component.GlobalAssetIdentification; import org.eclipse.tractusx.irs.component.JobParameter; -import org.eclipse.tractusx.irs.component.LinkedItem; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.Relationship; import org.eclipse.tractusx.irs.component.Tombstone; import org.eclipse.tractusx.irs.component.assetadministrationshell.Endpoint; @@ -66,7 +66,8 @@ public RelationshipDelegate(final AbstractDelegate nextStep, final EdcSubmodelFa @Override public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContainerBuilder, - final JobParameter jobData, final AASTransferProcess aasTransferProcess, final String itemId) { + final JobParameter jobData, final AASTransferProcess aasTransferProcess, + final PartChainIdentificationKey itemId) { final RelationshipAspect relationshipAspect = RelationshipAspect.from(jobData.getBomLifecycle(), jobData.getDirection()); @@ -76,24 +77,34 @@ public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContai .findFirst() .ifPresent(shell -> shell.findRelationshipEndpointAddresses( AspectType.fromValue(relationshipAspect.getName())) - .forEach(endpoint -> processEndpoint(endpoint, jobData, - relationshipAspect, aasTransferProcess, - itemContainerBuilder, itemId))); + .forEach(endpoint -> processEndpoint(endpoint, relationshipAspect, + aasTransferProcess, itemContainerBuilder, itemId))); return next(itemContainerBuilder, jobData, aasTransferProcess, itemId); } - private void processEndpoint(final Endpoint endpoint, final JobParameter jobData, - final RelationshipAspect relationshipAspect, final AASTransferProcess aasTransferProcess, - final ItemContainer.ItemContainerBuilder itemContainerBuilder, final String itemId) { + private void processEndpoint(final Endpoint endpoint, final RelationshipAspect relationshipAspect, + final AASTransferProcess aasTransferProcess, final ItemContainer.ItemContainerBuilder itemContainerBuilder, + final PartChainIdentificationKey itemId) { + + if (StringUtils.isBlank(itemId.getBpn())) { + log.warn("Could not process item with id {} because no BPN was provided. Creating Tombstone.", + itemId.getGlobalAssetId()); + itemContainerBuilder.tombstone( + Tombstone.from(itemId.getGlobalAssetId(), endpoint.getProtocolInformation().getHref(), + "Can't get relationship without a BPN", retryCount, ProcessStep.SUBMODEL_REQUEST)); + return; + } + try { final String submodelRawPayload = requestSubmodelAsString(submodelFacade, connectorEndpointsService, - endpoint, jobData.getBpn()); + endpoint, itemId.getBpn()); final var relationships = jsonUtil.fromString(submodelRawPayload, relationshipAspect.getSubmodelClazz()) .asRelationships(); - final List idsToProcess = getIdsToProcess(relationships, relationshipAspect.getDirection()); + final List idsToProcess = getIdsToProcess(relationships, + relationshipAspect.getDirection()); log.info("Processing Relationships with {} items", idsToProcess.size()); @@ -104,13 +115,13 @@ private void processEndpoint(final Endpoint endpoint, final JobParameter jobData log.info("Submodel Endpoint could not be retrieved for Endpoint: {}. Creating Tombstone.", endpoint.getProtocolInformation().getHref()); itemContainerBuilder.tombstone( - Tombstone.from(itemId, endpoint.getProtocolInformation().getHref(), e, retryCount, - ProcessStep.SUBMODEL_REQUEST)); + Tombstone.from(itemId.getGlobalAssetId(), endpoint.getProtocolInformation().getHref(), e, + retryCount, ProcessStep.SUBMODEL_REQUEST)); } catch (final JsonParseException e) { log.info("Submodel payload did not match the expected AspectType. Creating Tombstone."); itemContainerBuilder.tombstone( - Tombstone.from(itemId, endpoint.getProtocolInformation().getHref(), e, retryCount, - ProcessStep.SUBMODEL_REQUEST)); + Tombstone.from(itemId.getGlobalAssetId(), endpoint.getProtocolInformation().getHref(), e, + retryCount, ProcessStep.SUBMODEL_REQUEST)); } } @@ -118,25 +129,32 @@ private static List getBpnsFrom(final List relationships) { return relationships.stream().map(Relationship::getBpn).map(Bpn::withManufacturerId).toList(); } - private List getIdsToProcess(final List relationships, final Direction direction) { + private List getIdsToProcess(final List relationships, + final Direction direction) { return switch (direction) { case DOWNWARD -> getChildIds(relationships); case UPWARD -> getParentIds(relationships); }; } - private List getParentIds(final List relationships) { + private List getParentIds(final List relationships) { return relationships.stream() - .map(Relationship::getCatenaXId) - .map(GlobalAssetIdentification::getGlobalAssetId) + .map(relationship -> PartChainIdentificationKey.builder() + .globalAssetId(relationship.getCatenaXId() + .getGlobalAssetId()) + .bpn(relationship.getBpn()) + .build()) .toList(); } - private List getChildIds(final List relationships) { + private List getChildIds(final List relationships) { return relationships.stream() - .map(Relationship::getLinkedItem) - .map(LinkedItem::getChildCatenaXId) - .map(GlobalAssetIdentification::getGlobalAssetId) + .map(relationship -> PartChainIdentificationKey.builder() + .globalAssetId(relationship.getLinkedItem() + .getChildCatenaXId() + .getGlobalAssetId()) + .bpn(relationship.getBpn()) + .build()) .toList(); } } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegate.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegate.java index 52fa9432c7..701cc79f0e 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegate.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegate.java @@ -28,9 +28,11 @@ import io.github.resilience4j.retry.RetryRegistry; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.irs.aaswrapper.job.AASTransferProcess; import org.eclipse.tractusx.irs.aaswrapper.job.ItemContainer; import org.eclipse.tractusx.irs.component.JobParameter; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.Submodel; import org.eclipse.tractusx.irs.component.Tombstone; import org.eclipse.tractusx.irs.component.assetadministrationshell.SubmodelDescriptor; @@ -75,7 +77,8 @@ public SubmodelDelegate(final EdcSubmodelFacade submodelFacade, final SemanticsH @Override public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContainerBuilder, - final JobParameter jobData, final AASTransferProcess aasTransferProcess, final String itemId) { + final JobParameter jobData, final AASTransferProcess aasTransferProcess, + final PartChainIdentificationKey itemId) { itemContainerBuilder.build().getShells().stream().findFirst().ifPresent(shell -> { final List aasSubmodelDescriptors = shell.getSubmodelDescriptors(); @@ -87,7 +90,8 @@ public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContai if (jobData.isCollectAspects()) { log.info("Collecting Submodels."); filteredSubmodelDescriptorsByAspectType.forEach(submodelDescriptor -> itemContainerBuilder.submodels( - getSubmodels(submodelDescriptor, itemContainerBuilder, itemId, jobData.getBpn()))); + getSubmodels(submodelDescriptor, itemContainerBuilder, itemId.getGlobalAssetId(), + itemId.getBpn()))); } log.debug("Unfiltered SubmodelDescriptor: {}", aasSubmodelDescriptors); log.debug("Filtered SubmodelDescriptor: {}", filteredSubmodelDescriptorsByAspectType); @@ -103,6 +107,14 @@ private List getSubmodels(final SubmodelDescriptor submodelDescriptor, final ItemContainer.ItemContainerBuilder itemContainerBuilder, final String itemId, final String bpn) { final List submodels = new ArrayList<>(); submodelDescriptor.getEndpoints().forEach(endpoint -> { + + if (StringUtils.isBlank(bpn)) { + log.warn("Could not process item with id {} because no BPN was provided. Creating Tombstone.", itemId); + itemContainerBuilder.tombstone(Tombstone.from(itemId, endpoint.getProtocolInformation().getHref(), + "Can't get submodel without a BPN", retryCount, ProcessStep.SUBMODEL_REQUEST)); + return; + } + try { final String jsonSchema = semanticsHubFacade.getModelJsonSchema(submodelDescriptor.getAspectType()); final String submodelRawPayload = requestSubmodelAsString(submodelFacade, connectorEndpointsService, diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/RegistryConfiguration.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/RegistryConfiguration.java index 3450d34f26..4c51d7a8cf 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/RegistryConfiguration.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/configuration/RegistryConfiguration.java @@ -22,8 +22,6 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.configuration; -import java.util.HashMap; - import org.eclipse.tractusx.irs.edc.client.EdcSubmodelFacade; import org.eclipse.tractusx.irs.edc.client.exceptions.EdcClientException; import org.eclipse.tractusx.irs.registryclient.central.CentralDigitalTwinRegistryService; @@ -35,7 +33,6 @@ import org.eclipse.tractusx.irs.registryclient.decentral.EndpointDataForConnectorsService; import org.eclipse.tractusx.irs.registryclient.discovery.ConnectorEndpointsService; import org.eclipse.tractusx.irs.registryclient.discovery.DiscoveryFinderClientImpl; -import org.eclipse.tractusx.irs.registryclient.discovery.LocalDataDiscovery; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -82,27 +79,10 @@ public DecentralDigitalTwinRegistryService decentralDigitalTwinRegistryService( } @Bean - @Profile({ "!local && !stubtest" }) public ConnectorEndpointsService connectorEndpointsService( @Qualifier(RestTemplateConfig.DTR_REST_TEMPLATE) final RestTemplate dtrRestTemplate, @Value("${digitalTwinRegistry.discoveryFinderUrl:}") final String finderUrl) { return new ConnectorEndpointsService(new DiscoveryFinderClientImpl(finderUrl, dtrRestTemplate)); } - @Bean - @Profile({ "local", - "stubtest" - }) - public LocalDataDiscovery discoveryFinderClient() { - return new LocalDataDiscovery(new HashMap<>()); - } - - @Bean - @Profile({ "local", - "stubtest" - }) - public ConnectorEndpointsService localDiscoveryConnector(final LocalDataDiscovery discoveryFinderClient) { - return new ConnectorEndpointsService(discoveryFinderClient); - } - } diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java index 4565e96941..3c81db74c0 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java @@ -23,6 +23,8 @@ package org.eclipse.tractusx.irs; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; import static org.springframework.security.oauth2.jwt.JwtClaimNames.SUB; import java.time.Instant; @@ -37,7 +39,8 @@ import org.eclipse.tractusx.irs.component.RegisterJob; import org.eclipse.tractusx.irs.component.enums.JobState; import org.eclipse.tractusx.irs.controllers.IrsController; -import org.eclipse.tractusx.irs.registryclient.discovery.LocalDataDiscovery; +import org.eclipse.tractusx.irs.data.StringMapper; +import org.eclipse.tractusx.irs.registryclient.discovery.ConnectorEndpointsService; import org.eclipse.tractusx.irs.testing.containers.MinioContainer; import org.eclipse.tractusx.irs.util.TestMother; import org.jetbrains.annotations.NotNull; @@ -47,6 +50,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -75,8 +79,6 @@ class IrsFunctionalTest { new MinioContainer.CredentialsProvider(ACCESS_KEY, SECRET_KEY)).withReuse(true); @Autowired private IrsController controller; - @Autowired - private LocalDataDiscovery discovery; @BeforeAll static void startContainer() { @@ -88,10 +90,14 @@ static void stopContainer() { minioContainer.stop(); } + @MockBean + private ConnectorEndpointsService connectorEndpointsService; + @Test void shouldStartJobAndRetrieveResult() { final RegisterJob registerJob = TestMother.registerJobWithoutDepth(); - discovery.registerMapping(registerJob.getKey().getBpn(), "singleLevelBomAsBuilt"); + when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn( + List.of("http://localhost/discovery")); thereIsJwtAuthentication(); @@ -121,7 +127,8 @@ void shouldStartJobAndRetrieveResult() { @Test void shouldFillSummaryWithoutBPNLookup() { final RegisterJob registerJob = TestMother.registerJobWithoutDepth(); - discovery.registerMapping(registerJob.getKey().getBpn(), "singleLevelBomAsBuilt"); + when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn( + List.of("http://localhost/discovery")); thereIsJwtAuthentication(); @@ -147,7 +154,8 @@ void shouldFillSummaryWithoutBPNLookup() { @Test void shouldFillSummaryWithBPNLookup() { final RegisterJob registerJob = TestMother.registerJobWithLookupBPNs(); - discovery.registerMapping(registerJob.getKey().getBpn(), "singleLevelBomAsBuilt"); + when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn( + List.of("http://localhost/discovery")); thereIsJwtAuthentication(); final JobHandle jobHandle = controller.registerJobForGlobalAssetId(registerJob); @@ -174,7 +182,7 @@ private void thereIsJwtAuthentication() { List.of(new SimpleGrantedAuthority("view_irs"))); jwtAuthenticationToken.setAuthenticated(true); SecurityContext securityContext = Mockito.mock(SecurityContext.class); - Mockito.when(securityContext.getAuthentication()).thenReturn(jwtAuthenticationToken); + when(securityContext.getAuthentication()).thenReturn(jwtAuthenticationToken); SecurityContextHolder.setContext(securityContext); } diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcessManagerTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcessManagerTest.java index 40cc2730d9..9d37068b8b 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcessManagerTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/AASTransferProcessManagerTest.java @@ -22,8 +22,8 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.aaswrapper.job; -import static org.eclipse.tractusx.irs.util.TestMother.jobParameter; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.tractusx.irs.util.TestMother.jobParameter; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -34,6 +34,7 @@ import org.eclipse.tractusx.irs.InMemoryBlobStore; import org.eclipse.tractusx.irs.aaswrapper.job.delegate.DigitalTwinDelegate; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.connector.job.ResponseStatus; import org.eclipse.tractusx.irs.connector.job.TransferInitiateResponse; import org.eclipse.tractusx.irs.util.TestMother; @@ -49,12 +50,14 @@ class AASTransferProcessManagerTest { DigitalTwinDelegate digitalTwinProcessor = mock(DigitalTwinDelegate.class); ExecutorService pool = mock(ExecutorService.class); - final AASTransferProcessManager manager = new AASTransferProcessManager(digitalTwinProcessor, pool, new InMemoryBlobStore()); + final AASTransferProcessManager manager = new AASTransferProcessManager(digitalTwinProcessor, pool, + new InMemoryBlobStore()); @Test void shouldExecuteThreadForProcessing() { // given - final ItemDataRequest itemDataRequest = ItemDataRequest.rootNode(UUID.randomUUID().toString()); + final ItemDataRequest itemDataRequest = ItemDataRequest.rootNode( + PartChainIdentificationKey.builder().globalAssetId(UUID.randomUUID().toString()).bpn("bpn123").build()); // when manager.initiateRequest(itemDataRequest, s -> { @@ -68,7 +71,8 @@ void shouldExecuteThreadForProcessing() { @Test void shouldInitiateProcessingAndReturnOkStatus() { // given - final ItemDataRequest itemDataRequest = ItemDataRequest.rootNode(UUID.randomUUID().toString()); + final ItemDataRequest itemDataRequest = ItemDataRequest.rootNode( + PartChainIdentificationKey.builder().globalAssetId(UUID.randomUUID().toString()).bpn("bpn123").build()); // when final TransferInitiateResponse initiateResponse = manager.initiateRequest(itemDataRequest, s -> { diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/BpdmDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/BpdmDelegateTest.java index f67672f97c..9e6fe30d47 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/BpdmDelegateTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/BpdmDelegateTest.java @@ -36,6 +36,7 @@ import org.eclipse.tractusx.irs.aaswrapper.job.ItemContainer; import org.eclipse.tractusx.irs.bpdm.BpdmFacade; import org.eclipse.tractusx.irs.component.Bpn; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.enums.ProcessStep; import org.junit.jupiter.api.Test; import org.springframework.web.client.RestClientException; @@ -53,7 +54,7 @@ void shouldFillItemContainerWithBpn() { // when final ItemContainer result = bpdmDelegate.process(itemContainer, jobParameterCollectBpns(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); @@ -61,6 +62,10 @@ void shouldFillItemContainerWithBpn() { assertThat(result.getBpns().stream().findFirst().get().getManufacturerName()).isEqualTo("Tier A"); } + private static PartChainIdentificationKey createKey() { + return PartChainIdentificationKey.builder().globalAssetId("itemId").build(); + } + @Test void shouldCreateTombstoneForNotValidBpn() { // given @@ -69,7 +74,7 @@ void shouldCreateTombstoneForNotValidBpn() { // when final ItemContainer result = bpdmDelegate.process(itemContainer, jobParameterCollectBpns(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); @@ -88,7 +93,7 @@ void shouldCatchRestClientExceptionAndPutTombstone() { // when final ItemContainer result = bpdmDelegate.process(itemContainerWithShell, jobParameterCollectBpns(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); @@ -106,7 +111,7 @@ void shouldCreateTombstoneForMissingBpnForGivenManufacturerId() { // when final ItemContainer result = bpdmDelegate.process(itemContainer, jobParameterCollectBpns(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); @@ -125,7 +130,7 @@ void shouldNotResolveBPNsWithoutFlag() { // when final ItemContainer result = bpdmDelegate.process(itemContainer, jobParameter(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); @@ -141,7 +146,7 @@ void shouldResolveBPNsWhenFlagIsTrue() { // when final ItemContainer result = bpdmDelegate.process(itemContainer, jobParameterCollectBpns(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); @@ -159,7 +164,7 @@ void shouldIncrementFailedMetricWhenFacadeResultIsEmpty() { // when final ItemContainer result = bpdmDelegate.process(itemContainer, jobParameterCollectBpns(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); @@ -177,7 +182,7 @@ void shouldIncrementFailedMetricWhenExceptionIsThrown() { // when final ItemContainer result = bpdmDelegate.process(itemContainer, jobParameterCollectBpns(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/DigitalTwinDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/DigitalTwinDelegateTest.java index 7e3df757a2..1808ba8aa8 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/DigitalTwinDelegateTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/DigitalTwinDelegateTest.java @@ -22,10 +22,10 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.aaswrapper.job.delegate; +import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.tractusx.irs.util.TestMother.jobParameter; import static org.eclipse.tractusx.irs.util.TestMother.shellDescriptor; import static org.eclipse.tractusx.irs.util.TestMother.submodelDescriptorWithoutEndpoint; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -35,6 +35,7 @@ import io.github.resilience4j.retry.RetryRegistry; import org.eclipse.tractusx.irs.aaswrapper.job.AASTransferProcess; import org.eclipse.tractusx.irs.aaswrapper.job.ItemContainer; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.enums.ProcessStep; import org.eclipse.tractusx.irs.registryclient.DigitalTwinRegistryService; import org.eclipse.tractusx.irs.registryclient.exceptions.RegistryServiceException; @@ -49,18 +50,22 @@ class DigitalTwinDelegateTest { @Test void shouldFillItemContainerWithShell() throws RegistryServiceException { // given - when(digitalTwinRegistryService.fetchShells(any())).thenReturn(List.of(shellDescriptor( - List.of(submodelDescriptorWithoutEndpoint("any"))))); + when(digitalTwinRegistryService.fetchShells(any())).thenReturn( + List.of(shellDescriptor(List.of(submodelDescriptorWithoutEndpoint("any"))))); // when final ItemContainer result = digitalTwinDelegate.process(ItemContainer.builder(), jobParameter(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); assertThat(result.getShells()).isNotEmpty(); } + private static PartChainIdentificationKey createKey() { + return PartChainIdentificationKey.builder().globalAssetId("itemId").build(); + } + @Test void shouldCatchRestClientExceptionAndPutTombstone() throws RegistryServiceException { // given @@ -69,7 +74,7 @@ void shouldCatchRestClientExceptionAndPutTombstone() throws RegistryServiceExcep // when final ItemContainer result = digitalTwinDelegate.process(ItemContainer.builder(), jobParameter(), - new AASTransferProcess("id", 0), "itemId"); + new AASTransferProcess("id", 0), createKey()); // then assertThat(result).isNotNull(); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java index 41d9d3629c..f82884c95b 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/RelationshipDelegateTest.java @@ -39,6 +39,7 @@ import org.eclipse.tractusx.irs.aaswrapper.job.AASTransferProcess; import org.eclipse.tractusx.irs.aaswrapper.job.ItemContainer; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.enums.ProcessStep; import org.eclipse.tractusx.irs.edc.client.EdcSubmodelFacade; import org.eclipse.tractusx.irs.edc.client.exceptions.EdcClientException; @@ -73,7 +74,7 @@ void shouldFillItemContainerWithRelationshipAndAddChildIdsToProcess() // when final ItemContainer result = relationshipDelegate.process(itemContainerWithShell, jobParameter(), - aasTransferProcess, "itemId"); + aasTransferProcess, createKey()); // then assertThat(result).isNotNull(); @@ -81,6 +82,25 @@ void shouldFillItemContainerWithRelationshipAndAddChildIdsToProcess() assertThat(aasTransferProcess.getIdsToProcess()).isNotEmpty(); } + @Test + void shouldPutTombstoneForMissingBpn() throws EdcClientException { + final ItemContainer.ItemContainerBuilder itemContainerWithShell = ItemContainer.builder() + .shell(shellDescriptor( + List.of(submodelDescriptor( + singleLevelBomAsBuiltAspectName, + "address")))); + // when + final ItemContainer result = relationshipDelegate.process(itemContainerWithShell, jobParameter(), + new AASTransferProcess(), PartChainIdentificationKey.builder().globalAssetId("testId").build()); + + // then + assertThat(result).isNotNull(); + assertThat(result.getTombstones()).hasSize(1); + assertThat(result.getTombstones().get(0).getCatenaXId()).isEqualTo("testId"); + assertThat(result.getTombstones().get(0).getProcessingError().getProcessStep()).isEqualTo( + ProcessStep.SUBMODEL_REQUEST); + } + @Test void shouldCatchRestClientExceptionAndPutTombstone() throws EdcClientException { // given @@ -96,7 +116,7 @@ void shouldCatchRestClientExceptionAndPutTombstone() throws EdcClientException { // when final ItemContainer result = relationshipDelegate.process(itemContainerWithShell, jobParameter(), - new AASTransferProcess(), "itemId"); + new AASTransferProcess(), createKey()); // then assertThat(result).isNotNull(); @@ -120,7 +140,7 @@ void shouldCatchJsonParseExceptionAndPutTombstone() throws EdcClientException { // when final ItemContainer result = relationshipDelegate.process(itemContainerWithShell, jobParameter(), - new AASTransferProcess(), "itemId"); + new AASTransferProcess(), createKey()); // then assertThat(result).isNotNull(); @@ -130,4 +150,8 @@ void shouldCatchJsonParseExceptionAndPutTombstone() throws EdcClientException { ProcessStep.SUBMODEL_REQUEST); } + private static PartChainIdentificationKey createKey() { + return PartChainIdentificationKey.builder().globalAssetId("itemId").bpn("bpn123").build(); + } + } diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java index 5a3521c002..b76095b098 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/aaswrapper/job/delegate/SubmodelDelegateTest.java @@ -35,6 +35,7 @@ import org.eclipse.tractusx.irs.aaswrapper.job.AASTransferProcess; import org.eclipse.tractusx.irs.aaswrapper.job.ItemContainer; +import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.enums.ProcessStep; import org.eclipse.tractusx.irs.data.JsonParseException; import org.eclipse.tractusx.irs.edc.client.EdcSubmodelFacade; @@ -74,13 +75,17 @@ void shouldFilterSubmodelDescriptorsByAspectTypeFilter() { // when final ItemContainer result = submodelDelegate.process(itemContainerShellWithTwoSubmodels, jobParameterFilter(), - new AASTransferProcess(), "itemId"); + new AASTransferProcess(), createKey()); // then assertThat(result).isNotNull(); assertThat(result.getShells().get(0).getSubmodelDescriptors()).isEmpty(); } + private static PartChainIdentificationKey createKey() { + return PartChainIdentificationKey.builder().globalAssetId("itemId").bpn("bpn123").build(); + } + @Test void shouldCatchJsonParseExceptionAndPutTombstone() throws SchemaNotFoundException { // given @@ -97,7 +102,7 @@ void shouldCatchJsonParseExceptionAndPutTombstone() throws SchemaNotFoundExcepti when(semanticsHubFacade.getModelJsonSchema(any())).thenThrow( new JsonParseException(new Exception("Payload did not match expected submodel"))); final ItemContainer result = submodelDelegate.process(itemContainerShellWithTwoSubmodels, - jobParameterCollectAspects(), new AASTransferProcess(), "itemId"); + jobParameterCollectAspects(), new AASTransferProcess(), createKey()); // then assertThat(result).isNotNull(); @@ -107,6 +112,29 @@ void shouldCatchJsonParseExceptionAndPutTombstone() throws SchemaNotFoundExcepti ProcessStep.SCHEMA_VALIDATION); } + + @Test + void shouldPutTombstoneForMissingBpn() { + final ItemContainer.ItemContainerBuilder itemContainerShellWithTwoSubmodels = ItemContainer.builder() + .shell(shellDescriptor( + List.of(submodelDescriptor( + "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart", + "testSerialPartEndpoint"), + submodelDescriptor( + "urn:bamm:com.catenax.single_level_bom_as_built:1.0.0#SingleLevelBomAsBuilt", + "testSingleLevelBomAsBuiltEndpoint")))); + + // when + final ItemContainer result = submodelDelegate.process(itemContainerShellWithTwoSubmodels, jobParameterCollectAspects(), + new AASTransferProcess(), PartChainIdentificationKey.builder().globalAssetId("testId").build()); + + // then + assertThat(result).isNotNull(); + assertThat(result.getTombstones()).hasSize(2); + assertThat(result.getTombstones().get(0).getCatenaXId()).isEqualTo("testId"); + assertThat(result.getTombstones().get(0).getProcessingError().getProcessStep()).isEqualTo( + ProcessStep.SUBMODEL_REQUEST); + } @Test void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException { // given @@ -123,7 +151,7 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException when(submodelFacade.getSubmodelRawPayload(any(), any(), any())).thenThrow(new UsagePolicyException("itemId")); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("connector.endpoint.nl")); final ItemContainer result = submodelDelegate.process(itemContainerShellWithTwoSubmodels, - jobParameterCollectAspects(), new AASTransferProcess(), "itemId"); + jobParameterCollectAspects(), new AASTransferProcess(), createKey()); // then assertThat(result).isNotNull(); @@ -151,12 +179,13 @@ void shouldRequestForAllEndpoints() throws EdcClientException, InvalidSchemaExce when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn( List.of("connector.endpoint.n1", "connector.endpoint.n2")); final ItemContainer result = submodelDelegate.process(itemContainerShellWithOneSubmodel, - jobParameterCollectAspects(), new AASTransferProcess(), "itemId"); + jobParameterCollectAspects(), new AASTransferProcess(), createKey()); // then assertThat(result).isNotNull(); assertThat(result.getSubmodels()).hasSize(1); - assertThat(result.getSubmodels().get(0).getAspectType()).isEqualTo("urn:bamm:com.catenax.serial_part:1.0.0#SerialPart"); + assertThat(result.getSubmodels().get(0).getAspectType()).isEqualTo( + "urn:bamm:com.catenax.serial_part:1.0.0#SerialPart"); assertThat(result.getTombstones()).isEmpty(); } @@ -176,7 +205,7 @@ void shouldCatchRestClientExceptionAndPutTombstone() throws SchemaNotFoundExcept when(semanticsHubFacade.getModelJsonSchema(any())).thenThrow( new RestClientException("Payload did not match expected submodel")); final ItemContainer result = submodelDelegate.process(itemContainerShellWithTwoSubmodels, - jobParameterCollectAspects(), new AASTransferProcess(), "itemId"); + jobParameterCollectAspects(), new AASTransferProcess(), createKey()); // then assertThat(result).isNotNull(); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryServiceSpringBootTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryServiceSpringBootTest.java index f4efe32125..790b7441e2 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryServiceSpringBootTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/services/IrsItemGraphQueryServiceSpringBootTest.java @@ -120,9 +120,8 @@ void registerJobWithoutDepthShouldBuildFullTree() { // given final RegisterJob registerJob = registerJobWithoutDepth(); final int expectedRelationshipsSizeFullTree = 44; // stub - when(connectorEndpointsService.fetchConnectorEndpoints(registerJob.getKey().getBpn())).thenReturn( - List.of("singleLevelBomAsBuilt")); - + when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn( + List.of("http://localhost/discovery")); // when final JobHandle registeredJob = service.registerItemJob(registerJob); @@ -186,8 +185,8 @@ void registerJobShouldCreateTombstonesWhenNotPassingJsonSchemaValidation() throw void registerJobWithDepthShouldBuildTreeUntilGivenDepth() { // given final RegisterJob registerJob = registerJobWithDepthAndAspect(1, null); - when(connectorEndpointsService.fetchConnectorEndpoints(registerJob.getKey().getBpn())).thenReturn( - List.of("singleLevelBomAsBuilt")); + when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn( + List.of("http://localhost/discovery")); final int expectedRelationshipsSizeFirstDepth = 34; // stub @@ -206,8 +205,8 @@ void registerJobWithUpwardDirectionShouldBuildRelationships() { // given final RegisterJob registerJob = registerJobWithDirection("urn:uuid:0b45c63b-0e5e-4232-9074-a05607783c33", Direction.UPWARD); - when(connectorEndpointsService.fetchConnectorEndpoints(registerJob.getKey().getBpn())).thenReturn( - List.of("singleLevelUsageAsBuilt")); + when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn( + List.of("http://localhost/discovery")); final int expectedRelationshipsSizeFirstDepth = 1; // stub @@ -261,8 +260,8 @@ void registerJobWithoutAspectsShouldUseDefault() { final String defaultAspectType = AspectType.SERIAL_PART.toString(); final List emptyAspectTypeFilterList = List.of(); final RegisterJob registerJob = registerJobWithDepthAndAspect(null, emptyAspectTypeFilterList); - when(connectorEndpointsService.fetchConnectorEndpoints(registerJob.getKey().getBpn())).thenReturn( - List.of("singleLevelBomAsBuilt")); + when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn( + List.of("http://localhost/discovery")); // when final JobHandle jobHandle = service.registerItemJob(registerJob); diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClient.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClient.java index 10fe4d4551..6c606ff387 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClient.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClient.java @@ -89,7 +89,7 @@ public CompletableFuture getSubmodelRawPayload(final String connectorEnd if ("urn:uuid:c35ee875-5443-4a2d-bc14-fdacd64b9446".equals(assetId)) { throw new EdcClientException("Dummy Exception"); } - final Map submodel = testdataCreator.createSubmodelForId(assetId + "_" + connectorEndpoint); + final Map submodel = testdataCreator.createSubmodelForId(assetId + "_" + submodelSuffix); return CompletableFuture.completedFuture(StringMapper.mapToString(submodel)); } diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java index f55e3b4289..8979d3191d 100644 --- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java +++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java @@ -44,8 +44,8 @@ public class Tombstone { public static final int CATENA_X_ID_LENGTH = 45; @Schema(description = "CATENA-X global asset id in the format urn:uuid:uuid4.", - example = "urn:uuid:6c311d29-5753-46d4-b32c-19b918ea93b0", - minLength = CATENA_X_ID_LENGTH, maxLength = CATENA_X_ID_LENGTH, + example = "urn:uuid:6c311d29-5753-46d4-b32c-19b918ea93b0", minLength = CATENA_X_ID_LENGTH, + maxLength = CATENA_X_ID_LENGTH, pattern = "^urn:uuid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") private final String catenaXId; private final String endpointURL; @@ -53,11 +53,17 @@ public class Tombstone { public static Tombstone from(final String catenaXId, final String endpointURL, final Exception exception, final int retryCount, final ProcessStep processStep) { + return from(catenaXId, endpointURL, exception.getMessage(), retryCount, processStep); + } + + public static Tombstone from(final String catenaXId, final String endpointURL, final String errorDetails, + final int retryCount, final ProcessStep processStep) { + final ProcessingError processingError = ProcessingError.builder() .withProcessStep(processStep) .withRetryCounter(retryCount) .withLastAttempt(ZonedDateTime.now(ZoneOffset.UTC)) - .withErrorDetail(exception.getMessage()) + .withErrorDetail(errorDetails) .build(); return Tombstone.builder() .endpointURL(endpointURL)