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

feat(impl):[#404] add bpn to tombstone #790

Merged
merged 6 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed
- Change logo of irs
- Added 'businessPartnerNumber' field to Tombstone model. This will be filled only when UsagePolicyValidation tombstone is being created.

### Fixed
- Update to Spring Boot 3.1.9 to fix CVE's.

## [4.6.0] - 2024-02-20
### Added
Expand Down
2 changes: 2 additions & 0 deletions docs/src/api/irs-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2700,6 +2700,8 @@ components:
additionalProperties: false
description: Tombstone with information about request failure
properties:
businessPartnerNumber:
type: string
catenaXId:
type: string
description: CATENA-X global asset id in the format urn:uuid:uuid4.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private void processEndpoint(final Endpoint endpoint, final RelationshipAspect r
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, jsonUtil.asMap(e.getPolicy())));
0, ProcessStep.USAGE_POLICY_VALIDATION, e.getBusinessPartnerNumber(), jsonUtil.asMap(e.getPolicy())));
} catch (final EdcClientException e) {
log.info("Submodel Endpoint could not be retrieved for Endpoint: {}. Creating Tombstone.",
endpoint.getProtocolInformation().getHref());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ private List<Submodel> getSubmodels(final SubmodelDescriptor submodelDescriptor,
} catch (final UsagePolicyException e) {
log.info("Encountered usage policy exception: {}. Creating Tombstone.", e.getMessage());
itemContainerBuilder.tombstone(Tombstone.from(itemId, endpoint.getProtocolInformation().getHref(), e, 0,
ProcessStep.USAGE_POLICY_VALIDATION, jsonUtil.asMap(e.getPolicy())));
ProcessStep.USAGE_POLICY_VALIDATION, e.getBusinessPartnerNumber(), jsonUtil.asMap(e.getPolicy())));
} catch (final EdcClientException e) {
log.info("Submodel Endpoint could not be retrieved for Item: {}. Creating Tombstone.", itemId);
itemContainerBuilder.tombstone(Tombstone.from(itemId, endpoint.getProtocolInformation().getHref(), e, 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,15 @@ void shouldCatchJsonParseExceptionAndPutTombstone() throws EdcClientException {
@Test
void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException {
// given
final String businessPartnerNumber = "BPNL000000011111";
final ItemContainer.ItemContainerBuilder itemContainerWithShell = ItemContainer.builder()
.shell(shell("", shellDescriptor(
List.of(submodelDescriptorWithDspEndpoint(
singleLevelBomAsBuiltAspectName,
"address")))));

// when
when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null));
when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null, businessPartnerNumber));
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("connector.endpoint.nl"));
final ItemContainer result = relationshipDelegate.process(itemContainerWithShell, jobParameter(),
new AASTransferProcess(), createKey());
Expand All @@ -207,6 +208,7 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException
assertThat(result).isNotNull();
assertThat(result.getTombstones()).hasSize(1);
assertThat(result.getTombstones().get(0).getCatenaXId()).isEqualTo("itemId");
assertThat(result.getTombstones().get(0).getBusinessPartnerNumber()).isEqualTo(businessPartnerNumber);
assertThat(result.getTombstones().get(0).getProcessingError().getProcessStep()).isEqualTo(
ProcessStep.USAGE_POLICY_VALIDATION);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ void shouldPutTombstoneForMissingBpn() {
@Test
void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException {
// given
final String businessPartnerNumber = "BPNL000000011111";
final ItemContainer.ItemContainerBuilder itemContainerShellWithTwoSubmodels = ItemContainer.builder()
.shell(shell("", shellDescriptor(
List.of(submodelDescriptorWithDspEndpoint(
Expand All @@ -149,7 +150,7 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException
"testSingleLevelBomAsBuiltEndpoint")))));

// when
when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null));
when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null, businessPartnerNumber));
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("connector.endpoint.nl"));
final ItemContainer result = submodelDelegate.process(itemContainerShellWithTwoSubmodels,
jobParameterCollectAspects(), new AASTransferProcess(), createKey());
Expand All @@ -158,6 +159,7 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException
assertThat(result).isNotNull();
assertThat(result.getTombstones()).hasSize(2);
assertThat(result.getTombstones().get(0).getCatenaXId()).isEqualTo("itemId");
assertThat(result.getTombstones().get(0).getBusinessPartnerNumber()).isEqualTo(businessPartnerNumber);
assertThat(result.getTombstones().get(0).getProcessingError().getProcessStep()).isEqualTo(
ProcessStep.USAGE_POLICY_VALIDATION);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private CompletableFuture<NegotiationResponse> startNewNegotiation(final String

if (!policyCheckerService.isValid(catalogItem.getPolicy())) {
log.info("Policy was not allowed, canceling negotiation.");
throw new UsagePolicyException(catalogItem.getItemId(), catalogItem.getPolicy());
throw new UsagePolicyException(catalogItem.getItemId(), catalogItem.getPolicy(), catalogItem.getConnectorId());
}

final NegotiationRequest negotiationRequest = createNegotiationRequestFromCatalogItem(providerConnectorUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
public class UsagePolicyException extends EdcClientException {

private final transient Policy policy;
private final String businessPartnerNumber;

public UsagePolicyException(final String itemId, final Policy policy) {
public UsagePolicyException(final String itemId, final Policy policy, final String businessPartnerNumber) {
super("Consumption of asset '" + itemId
+ "' is not permitted as the required catalog offer policies do not comply with defined IRS policies.");
this.policy = policy;
this.businessPartnerNumber = businessPartnerNumber;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,39 +51,45 @@ public class Tombstone {
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;
private final String businessPartnerNumber;
private final ProcessingError processingError;
private final Map<String, Object> policy;

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, null);
}

public static Tombstone from(final String catenaXId, final String endpointURL, final String errorDetails,
final int retryCount, final ProcessStep processStep) {
return from(catenaXId, endpointURL, errorDetails, retryCount, processStep, null);
return from(catenaXId, endpointURL, exception.getMessage(), retryCount, processStep);
}

public static Tombstone from(final String catenaXId, final String endpointURL, final Exception exception,
final int retryCount, final ProcessStep processStep, final Map<String, Object> policy) {
return from(catenaXId, endpointURL, exception.getMessage(), retryCount, processStep, policy);
final int retryCount, final ProcessStep processStep, final String businessPartnerNumber, final Map<String, Object> policy) {

return Tombstone.builder()
.endpointURL(endpointURL)
.catenaXId(catenaXId)
.processingError(withProcessingError(processStep, retryCount, exception.getMessage()))
.businessPartnerNumber(businessPartnerNumber)
.policy(policy)
.build();
}

public static Tombstone from(final String catenaXId, final String endpointURL, final String errorDetails,
final int retryCount, final ProcessStep processStep, final Map<String, Object> policy) {
final int retryCount, final ProcessStep processStep) {

final ProcessingError processingError = ProcessingError.builder()
.withProcessStep(processStep)
.withRetryCounter(retryCount)
.withLastAttempt(ZonedDateTime.now(ZoneOffset.UTC))
.withErrorDetail(errorDetails)
.build();
return Tombstone.builder()
.endpointURL(endpointURL)
.catenaXId(catenaXId)
.processingError(processingError)
.policy(policy)
.processingError(withProcessingError(processStep, retryCount, errorDetails))
.build();
}

private static ProcessingError withProcessingError(final ProcessStep processStep, final int retryCount,
final String exception) {
return ProcessingError.builder()
.withProcessStep(processStep)
.withRetryCounter(retryCount)
.withLastAttempt(ZonedDateTime.now(ZoneOffset.UTC))
.withErrorDetail(exception)
.build();
}

}