Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/841 fix get root error messages #864

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b8a3255
chore(quality): [#841] remove obsolete method
dsmf Jul 30, 2024
39780ce
chore(quality): [#841] increase visibility of getRootErrorMessages
dsmf Jul 30, 2024
3cef700
chore(quality): [#841] mark unhandy construction methods as deprecated
dsmf Jul 30, 2024
a95e960
chore(quality): [#841] add bpn and edcUrl attributes to EdcRetrieverE…
dsmf Jul 30, 2024
f2d88aa
chore(quality): [#841] simplify builder for EdcReceiverException
dsmf Jul 31, 2024
543daf6
fix(exception-handling): [#841] Fixes, improvements, test
dsmf Jul 31, 2024
b4def46
Merge branch 'main' into fix/841-fill-bpn-in-tombstone
dsmf Aug 1, 2024
dd74856
chore(quality): [#841] formatting
dsmf Aug 1, 2024
9ea3551
fix(exception-handling): [#841] make constructor private (builder)
dsmf Aug 1, 2024
2fe49e9
fix(exception-handling): [#841] add bpn to validation tombstone
dsmf Aug 1, 2024
7778cc4
fix(exception-handling): [#841] add assertions, improve test readability
dsmf Aug 1, 2024
5290a25
fix(exception-handling): [#841] fix PMD warning
dsmf Aug 1, 2024
7c80642
Merge branch 'main' into fix/841-fill-bpn-in-tombstone
dsmf Aug 1, 2024
1c4ab9e
fix(exception-handling): [#841] remove obsolete todos
dsmf Aug 1, 2024
b6fd328
fix(exception-handling): [#841] fix test
dsmf Aug 1, 2024
6e309ad
fix(exception-handling): [#841] add prepareEmptyCatalog
dsmf Aug 2, 2024
fef51fc
fix(exception-handling): [#841] add successfulDiscovery
dsmf Aug 2, 2024
147f701
fix(exception-handling): [#841] add methods for multiple edc urls
dsmf Aug 2, 2024
d3c8af7
fix(exception-handling): [#841] remove todo
dsmf Aug 2, 2024
d89603b
fix(exception-handling): [#841] add test
dsmf Aug 2, 2024
76d22fa
fix(exception-handling): [#841] add todo
dsmf Aug 2, 2024
d6f6920
fix(exception-handling): [#841] PMD
dsmf Aug 2, 2024
913d0a6
fix(exception-handling): [#841] fix getRootErrorMessages
dsmf Aug 2, 2024
1a6a677
fix(exception-handling): [#841] fix checkstyle warning
dsmf Aug 2, 2024
2e7f4ad
Merge branch 'fix/841-fill-bpn-in-tombstone' into fix/841-fix-getRoot…
dsmf Aug 2, 2024
fb9dc0d
Merge branch 'main' into fix/841-fix-getRootErrorMessages
dsmf Aug 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ protected SubmodelDescriptor requestSubmodel(final EdcSubmodelFacade submodelFac
private SubmodelDescriptor getSubmodel(final EdcSubmodelFacade submodelFacade,
final Endpoint digitalTwinRegistryEndpoint, final List<String> connectorEndpoints, final String bpn)
throws EdcClientException {

for (final String connectorEndpoint : connectorEndpoints) {
try {
return submodelFacade.getSubmodelPayload(connectorEndpoint,
Expand All @@ -118,6 +119,7 @@ private SubmodelDescriptor getSubmodel(final EdcSubmodelFacade submodelFacade,
log.info("EdcClientException while accessing digitalTwinRegistryEndpoint '{}'", connectorEndpoint, e);
}
}

throw new EdcClientException(
String.format("Called %s connectorEndpoints but did not get any submodels. Connectors: '%s'",
connectorEndpoints.size(), String.join(", ", connectorEndpoints)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.eclipse.tractusx.irs.registryclient.DigitalTwinRegistryKey;
import org.eclipse.tractusx.irs.registryclient.DigitalTwinRegistryService;
import org.eclipse.tractusx.irs.registryclient.exceptions.RegistryServiceException;
import org.eclipse.tractusx.irs.registryclient.exceptions.ShellNotFoundException;

/**
* Retrieves AAShell from Digital Twin Registry service and storing it inside {@link ItemContainer}.
Expand Down Expand Up @@ -72,22 +73,20 @@ public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContai
final var dtrKeys = List.of(new DigitalTwinRegistryKey(itemId.getGlobalAssetId(), itemId.getBpn()));
final var shells = digitalTwinRegistryService.fetchShells(dtrKeys);
final var shell = shells.stream()
// we use findFirst here, because we query only for one
// DigitalTwinRegistryKey here
.map(Either::getOrNull)
.filter(Objects::nonNull)
.findFirst()
.orElseThrow(() -> shellNotFound(shells));
// we use findFirst here, because we query only for one
// DigitalTwinRegistryKey here
.map(Either::getOrNull)
.filter(Objects::nonNull)
.findFirst()
.orElseThrow(() -> shellNotFound(shells));

itemContainerBuilder.shell(
jobData.isAuditContractNegotiation() ? shell : shell.withoutContractAgreementId());

} catch (final RegistryServiceException | RuntimeException e) {
// catching generic exception is intended here,
// otherwise Jobs stay in state RUNNING forever
log.info("Shell Endpoint could not be retrieved for Item: {}. Creating Tombstone.", itemId);
itemContainerBuilder.tombstone(
Tombstone.from(itemId.getGlobalAssetId(), null, e, e.getSuppressed(), retryCount,
ProcessStep.DIGITAL_TWIN_REQUEST));
createShellEndpointCouldNotBeRetrievedTombstone(itemContainerBuilder, itemId, e);
}

if (expectedDepthOfTreeIsNotReached(jobData.getDepth(), aasTransferProcess.getDepth())) {
Expand All @@ -98,7 +97,38 @@ public ItemContainer process(final ItemContainer.ItemContainerBuilder itemContai
return itemContainerBuilder.build();
}

private Tombstone createNoBpnProvidedTombstone(final JobParameter jobData, final PartChainIdentificationKey itemId) {
private void createShellEndpointCouldNotBeRetrievedTombstone(
final ItemContainer.ItemContainerBuilder itemContainerBuilder, final PartChainIdentificationKey itemId,
final Exception exception) {

// TODO (mfischer) is this log message and method name correct?
log.info("Shell Endpoint could not be retrieved for Item: {}. Creating Tombstone.", itemId);
log.debug(exception.getMessage(), exception);

final List<String> rootErrorMessages = Tombstone.getRootErrorMessages(exception.getSuppressed());
final ProcessingError error = ProcessingError.builder()
.withProcessStep(ProcessStep.DIGITAL_TWIN_REQUEST)
.withRetryCounterAndLastAttemptNow(retryCount)
.withErrorDetail(exception.getMessage())
.withRootCauses(rootErrorMessages)
.build();

String endpointURL = null;
if (exception instanceof ShellNotFoundException) {
endpointURL = String.join("; ", ((ShellNotFoundException) exception).getCalledEndpoints());
}

final Tombstone tombstone = Tombstone.builder()
.endpointURL(endpointURL)
.catenaXId(itemId.getGlobalAssetId())
.processingError(error)
.businessPartnerNumber(itemId.getBpn())
.build();
itemContainerBuilder.tombstone(tombstone);
}

private Tombstone createNoBpnProvidedTombstone(final JobParameter jobData,
final PartChainIdentificationKey itemId) {
log.warn("Could not process item with id {} because no BPN was provided. Creating Tombstone.",
itemId.getGlobalAssetId());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
package org.eclipse.tractusx.irs.aaswrapper.job.delegate;

import java.util.List;
import java.util.Map;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -32,6 +33,7 @@
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.ProcessingError;
import org.eclipse.tractusx.irs.component.Relationship;
import org.eclipse.tractusx.irs.component.Tombstone;
import org.eclipse.tractusx.irs.component.assetadministrationshell.Endpoint;
Expand All @@ -41,6 +43,7 @@
import org.eclipse.tractusx.irs.data.JsonParseException;
import org.eclipse.tractusx.irs.edc.client.EdcSubmodelFacade;
import org.eclipse.tractusx.irs.edc.client.exceptions.EdcClientException;
import org.eclipse.tractusx.irs.edc.client.exceptions.PolicyException;
import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyExpiredException;
import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyPermissionException;
import org.eclipse.tractusx.irs.edc.client.relationships.RelationshipAspect;
Expand Down Expand Up @@ -94,9 +97,7 @@ private void processEndpoint(final Endpoint endpoint, final RelationshipAspect r
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));
itemContainerBuilder.tombstone(createNoBpnProvidedTombstone(endpoint, itemId));
return;
}

Expand All @@ -111,30 +112,77 @@ private void processEndpoint(final Endpoint endpoint, final RelationshipAspect r
relationshipAspect.getDirection());

log.info("Processing Relationships with {} items", idsToProcess.size());

aasTransferProcess.addIdsToProcess(idsToProcess);
itemContainerBuilder.relationships(relationships);
itemContainerBuilder.bpns(getBpnsFrom(relationships));

} catch (final UsagePolicyPermissionException | UsagePolicyExpiredException e) {
log.info("Encountered usage policy exception: {}. Creating Tombstone.", e.getMessage());
itemContainerBuilder.tombstone(
Tombstone.from(itemId.getGlobalAssetId(), endpoint.getProtocolInformation().getHref(), e, 0,
ProcessStep.USAGE_POLICY_VALIDATION, e.getBusinessPartnerNumber(),
jsonUtil.asMap(e.getPolicy())));
final Tombstone tombstone = createPolicyTombstone(endpoint, itemId, e);
itemContainerBuilder.tombstone(tombstone);

} catch (final EdcClientException e) {
log.info("Submodel Endpoint could not be retrieved for Endpoint: {}. Creating Tombstone.",
endpoint.getProtocolInformation().getHref());
itemContainerBuilder.tombstone(
Tombstone.from(itemId.getGlobalAssetId(), endpoint.getProtocolInformation().getHref(), e, 0,
ProcessStep.SUBMODEL_REQUEST));
final Tombstone tombstone = createEdcClientExceptionTombstone(endpoint, itemId, e);
itemContainerBuilder.tombstone(tombstone);

} catch (final JsonParseException e) {
log.info("Submodel payload did not match the expected AspectType. Creating Tombstone.");
itemContainerBuilder.tombstone(
Tombstone.from(itemId.getGlobalAssetId(), endpoint.getProtocolInformation().getHref(), e, 0,
ProcessStep.SUBMODEL_REQUEST));
final Tombstone tombstone = createJsonParseSubmodelPayloadTombstone(endpoint, itemId, e);
itemContainerBuilder.tombstone(tombstone);
}
}

private Tombstone createNoBpnProvidedTombstone(final Endpoint endpoint, final PartChainIdentificationKey itemId) {
final ProcessingError error = createProcessingError(ProcessStep.SUBMODEL_REQUEST, retryCount,
"Can't get relationship without a BPN");
return createTombstone(endpoint.getProtocolInformation().getHref(), itemId.getGlobalAssetId(), error,
itemId.getBpn());
}

private Tombstone createPolicyTombstone(final Endpoint endpoint, final PartChainIdentificationKey itemId,
final PolicyException exception) {
final Map<String, Object> policy = jsonUtil.asMap(exception.getPolicy());
final ProcessingError error = createProcessingError(ProcessStep.USAGE_POLICY_VALIDATION, 0,
exception.getMessage());
return createTombstone(endpoint.getProtocolInformation().getHref(), itemId.getGlobalAssetId(), error,
exception.getBusinessPartnerNumber()).toBuilder().policy(policy).build();
}

private Tombstone createEdcClientExceptionTombstone(final Endpoint endpoint,
final PartChainIdentificationKey itemId, final EdcClientException exception) {
final ProcessingError error = createProcessingError(ProcessStep.SUBMODEL_REQUEST, 0, exception.getMessage());
return createTombstone(endpoint.getProtocolInformation().getHref(), itemId.getGlobalAssetId(), error,
itemId.getBpn());
}

private Tombstone createJsonParseSubmodelPayloadTombstone(final Endpoint endpoint,
final PartChainIdentificationKey itemId, final JsonParseException exception) {
final ProcessingError error = createProcessingError(ProcessStep.SUBMODEL_REQUEST, 0, exception.getMessage());
return createTombstone(endpoint.getProtocolInformation().getHref(), itemId.getGlobalAssetId(), error,
itemId.getBpn());
}

private ProcessingError createProcessingError(final ProcessStep processStep, final int retryCount,
final String exception) {
return ProcessingError.builder()
.withProcessStep(processStep)
.withRetryCounterAndLastAttemptNow(retryCount)
.withErrorDetail(exception)
.build();
}

private Tombstone createTombstone(final String endpointURL, final String globalAssetId, final ProcessingError error,
final String bpn) {
return Tombstone.builder()
.endpointURL(endpointURL)
.catenaXId(globalAssetId)
.processingError(error)
.businessPartnerNumber(bpn)
.build();
}

private static List<Bpn> getBpnsFrom(final List<Relationship> relationships) {
return relationships.stream()
.map(Relationship::getBpn)
Expand Down
Loading
Loading