From 6657e389249e8e518a22c0a31ea9b0a47ca2cfd0 Mon Sep 17 00:00:00 2001 From: ds-lcapellino Date: Mon, 10 Jun 2024 16:18:20 +0200 Subject: [PATCH] feature: eclipse-tractusx/traceability-foss#639 rework handling of expired policies --- CHANGELOG.md | 1 + ...oning-of-contractAgreementId-for-assets.md | 2 +- .../job/delegate/RelationshipDelegate.java | 4 +- .../job/delegate/SubmodelDelegate.java | 4 +- .../delegate/RelationshipDelegateTest.java | 4 +- .../job/delegate/SubmodelDelegateTest.java | 9 ++-- .../client/ContractNegotiationService.java | 19 +++++-- .../irs/edc/client/EdcSubmodelClientImpl.java | 6 ++- .../UsagePolicyExpiredException.java | 40 +++++++++++++++ ...va => UsagePolicyPermissionException.java} | 9 ++-- .../client/policy/PolicyCheckerService.java | 26 +++++++--- .../ContractNegotiationServiceTest.java | 23 ++++++--- .../irs/edc/client/EdcSubmodelClientTest.java | 6 ++- .../client/SubmodelFacadeWiremockTest.java | 6 +-- .../policy/PolicyCheckerServiceTest.java | 50 +++++++++++++++++++ 15 files changed, 170 insertions(+), 39 deletions(-) create mode 100644 irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyExpiredException.java rename irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/{UsagePolicyException.java => UsagePolicyPermissionException.java} (82%) diff --git a/CHANGELOG.md b/CHANGELOG.md index b05757cb75..788db95a27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ _**For better traceability add the corresponding GitHub issue number in each cha - Added missing @context values in edc asset creation. eclipse-tractusx/traceability-foss#978 - Switch to `dct:type` `https://w3id.org/catenax/taxonomy#` for notification asset creation. eclipse-tractusx/traceability-foss#978 - Shells in Job response will contain all submodel descriptors returned by provider, instead filtered by aspect-type parameter. #510 +- Handling of expired policies when approving a notification eclipse-tractusx/traceability-foss#639 ## Added diff --git a/docs/concept/#322-Provisioning-of-contractAgreementId-for-assets/#322-Provisioning-of-contractAgreementId-for-assets.md b/docs/concept/#322-Provisioning-of-contractAgreementId-for-assets/#322-Provisioning-of-contractAgreementId-for-assets.md index 53d0124c66..42c30b2dde 100644 --- a/docs/concept/#322-Provisioning-of-contractAgreementId-for-assets/#322-Provisioning-of-contractAgreementId-for-assets.md +++ b/docs/concept/#322-Provisioning-of-contractAgreementId-for-assets/#322-Provisioning-of-contractAgreementId-for-assets.md @@ -384,7 +384,7 @@ policy store in order to receice further on assets with the specific policy. }, "processingError": { "processStep": "UsagePolicyValidation", - "errorDetail": "Consumption of asset (itemId) is not permitted as the required catalog offer policies do not comply with defined IRS policies.", + "errorDetail": "Consumption of asset (itemId) is not permitted as the required catalog offer policies do not comply with defined policies.", "lastAttempt": "2024-01-17T09:02:36.648055745Z", "retryCounter": 3 } 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 28c1703aa5..7f774d410f 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 @@ -41,7 +41,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.UsagePolicyException; +import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyPermissionException; import org.eclipse.tractusx.irs.edc.client.relationships.RelationshipAspect; import org.eclipse.tractusx.irs.registryclient.discovery.ConnectorEndpointsService; import org.eclipse.tractusx.irs.util.JsonUtil; @@ -114,7 +114,7 @@ private void processEndpoint(final Endpoint endpoint, final RelationshipAspect r aasTransferProcess.addIdsToProcess(idsToProcess); itemContainerBuilder.relationships(relationships); itemContainerBuilder.bpns(getBpnsFrom(relationships)); - } catch (final UsagePolicyException e) { + } catch (final UsagePolicyPermissionException e) { log.info("Encountered usage policy exception: {}. Creating Tombstone.", e.getMessage()); itemContainerBuilder.tombstone( Tombstone.from(itemId.getGlobalAssetId(), endpoint.getProtocolInformation().getHref(), e, 0, 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 c7315cd7f1..f9f0f2d3a9 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 @@ -41,7 +41,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.UsagePolicyException; +import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyPermissionException; import org.eclipse.tractusx.irs.registryclient.discovery.ConnectorEndpointsService; import org.eclipse.tractusx.irs.semanticshub.SemanticsHubFacade; import org.eclipse.tractusx.irs.services.validation.InvalidSchemaException; @@ -142,7 +142,7 @@ private List getSubmodels(final SubmodelDescriptor submodelDescriptor, itemContainerBuilder.tombstone(Tombstone.from(itemId, endpoint.getProtocolInformation().getHref(), e, 0, ProcessStep.SCHEMA_REQUEST)); log.info("Cannot load JSON schema for validation. Creating Tombstone."); - } catch (final UsagePolicyException e) { + } catch (final UsagePolicyPermissionException 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, e.getBusinessPartnerNumber(), 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 e2df971471..b6dea229fa 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 @@ -63,7 +63,7 @@ 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; -import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyException; +import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyPermissionException; import org.eclipse.tractusx.irs.edc.client.model.SubmodelDescriptor; import org.eclipse.tractusx.irs.registryclient.discovery.ConnectorEndpointsService; import org.eclipse.tractusx.irs.util.JsonUtil; @@ -391,7 +391,7 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException // when when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenThrow( - new UsagePolicyException("itemId", null, businessPartnerNumber)); + new UsagePolicyPermissionException("itemId", null, businessPartnerNumber)); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("connector.endpoint.nl")); final ItemContainer result = relationshipDelegate.process(itemContainerWithShell, jobParameter(), new AASTransferProcess(), createKey()); 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 b5567f3aa3..ab98d6123e 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 @@ -24,12 +24,12 @@ package org.eclipse.tractusx.irs.aaswrapper.job.delegate; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.tractusx.irs.SemanticModelNames.SERIAL_PART_3_0_0; +import static org.eclipse.tractusx.irs.SemanticModelNames.SINGLE_LEVEL_BOM_AS_BUILT_3_0_0; import static org.eclipse.tractusx.irs.util.TestMother.jobParameterCollectAspects; import static org.eclipse.tractusx.irs.util.TestMother.jobParameterFilter; -import static org.eclipse.tractusx.irs.SemanticModelNames.SERIAL_PART_3_0_0; import static org.eclipse.tractusx.irs.util.TestMother.shell; import static org.eclipse.tractusx.irs.util.TestMother.shellDescriptor; -import static org.eclipse.tractusx.irs.SemanticModelNames.SINGLE_LEVEL_BOM_AS_BUILT_3_0_0; import static org.eclipse.tractusx.irs.util.TestMother.submodelDescriptor; import static org.eclipse.tractusx.irs.util.TestMother.submodelDescriptorWithDspEndpoint; import static org.mockito.ArgumentMatchers.any; @@ -46,7 +46,7 @@ import org.eclipse.tractusx.irs.edc.client.EdcSubmodelFacade; import org.eclipse.tractusx.irs.edc.client.ItemNotFoundInCatalogException; import org.eclipse.tractusx.irs.edc.client.exceptions.EdcClientException; -import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyException; +import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyPermissionException; import org.eclipse.tractusx.irs.edc.client.model.SubmodelDescriptor; import org.eclipse.tractusx.irs.registryclient.discovery.ConnectorEndpointsService; import org.eclipse.tractusx.irs.semanticshub.SemanticsHubFacade; @@ -152,7 +152,8 @@ void shouldCatchUsagePolicyExceptionAndPutTombstone() throws EdcClientException "testSingleLevelBomAsBuiltEndpoint"))))); // when - when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenThrow(new UsagePolicyException("itemId", null, businessPartnerNumber)); + when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenThrow( + new UsagePolicyPermissionException("itemId", null, businessPartnerNumber)); when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of("connector.endpoint.nl")); final ItemContainer result = submodelDelegate.process(itemContainerShellWithTwoSubmodels, jobParameterCollectAspects(), new AASTransferProcess(), createKey()); diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationService.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationService.java index 107c90a202..d45e24dac5 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationService.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationService.java @@ -40,7 +40,8 @@ import org.eclipse.tractusx.irs.edc.client.cache.endpointdatareference.EndpointDataReferenceStatus; import org.eclipse.tractusx.irs.edc.client.exceptions.ContractNegotiationException; import org.eclipse.tractusx.irs.edc.client.exceptions.TransferProcessException; -import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyException; +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.model.CatalogItem; import org.eclipse.tractusx.irs.edc.client.model.ContractOffer; import org.eclipse.tractusx.irs.edc.client.model.NegotiationRequest; @@ -70,7 +71,8 @@ public class ContractNegotiationService { public NegotiationResponse negotiate(final String providerConnectorUrl, final CatalogItem catalogItem, final EndpointDataReferenceStatus endpointDataReferenceStatus, final String bpn) - throws ContractNegotiationException, UsagePolicyException, TransferProcessException { + throws ContractNegotiationException, UsagePolicyPermissionException, TransferProcessException, + UsagePolicyExpiredException { EndpointDataReferenceStatus resultEndpointDataReferenceStatus; @@ -119,12 +121,19 @@ public NegotiationResponse negotiate(final String providerConnectorUrl, final Ca } private CompletableFuture startNewNegotiation(final String providerConnectorUrl, - final CatalogItem catalogItem, final String bpn) throws UsagePolicyException { + final CatalogItem catalogItem, final String bpn) + throws UsagePolicyPermissionException, UsagePolicyExpiredException { log.info("Staring new contract negotiation."); if (!policyCheckerService.isValid(catalogItem.getPolicy(), bpn)) { - log.info("Policy was not allowed, canceling negotiation."); - throw new UsagePolicyException(catalogItem.getItemId(), catalogItem.getPolicy(), + log.warn("Policy was not allowed, canceling negotiation."); + throw new UsagePolicyPermissionException(catalogItem.getItemId(), catalogItem.getPolicy(), + catalogItem.getConnectorId()); + } + + if (policyCheckerService.isExpired(catalogItem.getPolicy(), bpn)) { + log.warn("Policy is expired, canceling negotiation."); + throw new UsagePolicyExpiredException(catalogItem.getItemId(), catalogItem.getPolicy(), catalogItem.getConnectorId()); } diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientImpl.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientImpl.java index fee863c97c..9a0ed6bec3 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientImpl.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientImpl.java @@ -46,7 +46,8 @@ import org.eclipse.tractusx.irs.edc.client.exceptions.ContractNegotiationException; import org.eclipse.tractusx.irs.edc.client.exceptions.EdcClientException; import org.eclipse.tractusx.irs.edc.client.exceptions.TransferProcessException; -import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyException; +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.model.CatalogItem; import org.eclipse.tractusx.irs.edc.client.model.NegotiationResponse; import org.eclipse.tractusx.irs.edc.client.model.SubmodelDescriptor; @@ -318,7 +319,8 @@ private NegotiationResponse negotiateContract(final EndpointDataReferenceStatus try { response = contractNegotiationService.negotiate(providerWithSuffix, catalogItem, endpointDataReferenceStatus, bpn); - } catch (TransferProcessException | UsagePolicyException | ContractNegotiationException e) { + } catch (TransferProcessException | UsagePolicyPermissionException | UsagePolicyExpiredException + | ContractNegotiationException e) { throw new EdcClientException(("Negotiation failed for endpoint '%s', " + "tokenStatus '%s', " + "providerWithSuffix '%s', catalogItem '%s'").formatted( endpointDataReferenceStatus.endpointDataReference(), endpointDataReferenceStatus.tokenStatus(), diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyExpiredException.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyExpiredException.java new file mode 100644 index 0000000000..e9c4e44fa7 --- /dev/null +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyExpiredException.java @@ -0,0 +1,40 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +package org.eclipse.tractusx.irs.edc.client.exceptions; + +import lombok.Getter; +import org.eclipse.edc.policy.model.Policy; + +/** + * Usage Policy Expired Exception errors in the contract negotiation. + */ +@Getter +public class UsagePolicyExpiredException extends EdcClientException { + + private final transient Policy policy; + private final String businessPartnerNumber; + + public UsagePolicyExpiredException(final String itemId, final Policy policy, final String businessPartnerNumber) { + super("Consumption of asset '" + itemId + + "' is not permitted as the required catalog offer policies are expired."); + this.policy = policy; + this.businessPartnerNumber = businessPartnerNumber; + } +} diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyException.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyPermissionException.java similarity index 82% rename from irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyException.java rename to irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyPermissionException.java index 5956b37c94..c289672f12 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyException.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/exceptions/UsagePolicyPermissionException.java @@ -27,17 +27,18 @@ import org.eclipse.edc.policy.model.Policy; /** - * Usage Policy Exception errors in the contract negotiation. + * Usage Policy Permission Exception errors in the contract negotiation. */ @Getter -public class UsagePolicyException extends EdcClientException { +public class UsagePolicyPermissionException extends EdcClientException { private final transient Policy policy; private final String businessPartnerNumber; - public UsagePolicyException(final String itemId, final Policy policy, final String businessPartnerNumber) { + public UsagePolicyPermissionException(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."); + + "' is not permitted as the required catalog offer policies do not comply with defined policies."); this.policy = policy; this.businessPartnerNumber = businessPartnerNumber; } diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerService.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerService.java index 062bdafad8..daa34c81d6 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerService.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerService.java @@ -44,20 +44,34 @@ public class PolicyCheckerService { private final ConstraintCheckerService constraintCheckerService; public boolean isValid(final Policy policy, final String bpn) { - return policy.getPermissions().stream().allMatch(permission -> isValid(permission, getValidStoredPolicies(bpn))); + final List validStoredPolicies = getValidStoredPolicies(bpn); + return policy.getPermissions() + .stream() + .allMatch(permission -> hasValidConstraints(permission, validStoredPolicies)); } - private boolean isValid(final Permission permission, final List validStoredPolicies) { + private boolean hasValidConstraints(final Permission permission, final List validStoredPolicies) { return validStoredPolicies.stream() .anyMatch(acceptedPolicy -> constraintCheckerService.hasAllConstraint( acceptedPolicy.policy(), permission.getConstraints())); } + public boolean isExpired(final Policy policy, final String bpn) { + return policy.getPermissions() + .stream() + .allMatch(permission -> hasExpiredConstraint(permission, getValidStoredPolicies(bpn))); + } + + private boolean hasExpiredConstraint(final Permission permission, final List validStoredPolicies) { + return validStoredPolicies.stream() + .filter(acceptedPolicy -> constraintCheckerService.hasAllConstraint( + acceptedPolicy.policy(), permission.getConstraints())) + .allMatch( + acceptedPolicy -> acceptedPolicy.validUntil().isBefore(OffsetDateTime.now())); + } + private List getValidStoredPolicies(final String bpn) { - return policyStore.getAcceptedPolicies(bpn) - .stream() - .filter(p -> p.validUntil().isAfter(OffsetDateTime.now())) - .toList(); + return policyStore.getAcceptedPolicies(bpn).stream().toList(); } } diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationServiceTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationServiceTest.java index 25bbc9d1d3..b031bfb25f 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationServiceTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/ContractNegotiationServiceTest.java @@ -40,7 +40,8 @@ import org.eclipse.tractusx.irs.edc.client.exceptions.ContractNegotiationException; import org.eclipse.tractusx.irs.edc.client.exceptions.EdcClientException; import org.eclipse.tractusx.irs.edc.client.exceptions.TransferProcessException; -import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyException; +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.model.CatalogItem; import org.eclipse.tractusx.irs.edc.client.model.NegotiationResponse; import org.eclipse.tractusx.irs.edc.client.model.Response; @@ -80,12 +81,14 @@ private static CatalogItem createCatalogItem(final String assetId, final String @Test void shouldNegotiateSuccessfully() - throws ContractNegotiationException, UsagePolicyException, TransferProcessException { + throws ContractNegotiationException, UsagePolicyPermissionException, TransferProcessException, + UsagePolicyExpiredException { // arrange final var assetId = "testTarget"; final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isExpired(any(), any())).thenReturn(Boolean.FALSE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); CompletableFuture response = CompletableFuture.completedFuture( @@ -112,6 +115,7 @@ void shouldThrowErrorWhenRetrievingNegotiationResult() { final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isExpired(any(), any())).thenReturn(Boolean.FALSE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); CompletableFuture response = CompletableFuture.failedFuture( @@ -131,6 +135,7 @@ void shouldThrowErrorWhenRetrievingTransferResult() { final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isExpired(any(), any())).thenReturn(Boolean.FALSE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); @@ -159,7 +164,8 @@ void shouldThrowErrorWhenPolicyCheckerReturnFalse() { .policy(createPolicy(assetId)) .assetPropId(assetId) .build(); - when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.FALSE); + when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isExpired(any(), any())).thenReturn(Boolean.TRUE); // act & assert assertThatThrownBy(() -> testee.negotiate(CONNECTOR_URL, catalogItem, @@ -169,12 +175,14 @@ void shouldThrowErrorWhenPolicyCheckerReturnFalse() { @Test void shouldStartNegotiationProcessWhenTokenStatusIsRequiredNew() - throws TransferProcessException, UsagePolicyException, ContractNegotiationException { + throws TransferProcessException, UsagePolicyPermissionException, ContractNegotiationException, + UsagePolicyExpiredException { // given final var assetId = "testTarget"; final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isExpired(any(), any())).thenReturn(Boolean.FALSE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); CompletableFuture negotiationResponse = CompletableFuture.completedFuture( @@ -195,12 +203,14 @@ void shouldStartNegotiationProcessWhenTokenStatusIsRequiredNew() @Test void shouldStartNegotiationProcessWhenTokenStatusIsMissing() - throws TransferProcessException, UsagePolicyException, ContractNegotiationException { + throws TransferProcessException, UsagePolicyPermissionException, ContractNegotiationException, + UsagePolicyExpiredException { // given final var assetId = "testTarget"; final String offerId = "offerId"; final CatalogItem catalogItem = createCatalogItem(assetId, offerId); when(policyCheckerService.isValid(any(), any())).thenReturn(Boolean.TRUE); + when(policyCheckerService.isExpired(any(), any())).thenReturn(Boolean.FALSE); when(edcControlPlaneClient.startNegotiations(any())).thenReturn( Response.builder().responseId("negotiationId").build()); CompletableFuture negotiationResponse = CompletableFuture.completedFuture( @@ -220,7 +230,8 @@ void shouldStartNegotiationProcessWhenTokenStatusIsMissing() @Test void shouldNotStartNewNegotiationWhenTokenIsExpired() - throws TransferProcessException, UsagePolicyException, ContractNegotiationException { + throws TransferProcessException, UsagePolicyPermissionException, ContractNegotiationException, + UsagePolicyExpiredException { // given final var assetId = "testTarget"; final String offerId = "offerId"; diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientTest.java index 7bc2c5b22a..c62320ae94 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/EdcSubmodelClientTest.java @@ -71,7 +71,8 @@ import org.eclipse.tractusx.irs.edc.client.exceptions.ContractNegotiationException; import org.eclipse.tractusx.irs.edc.client.exceptions.EdcClientException; import org.eclipse.tractusx.irs.edc.client.exceptions.TransferProcessException; -import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyException; +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.model.CatalogItem; import org.eclipse.tractusx.irs.edc.client.model.NegotiationResponse; import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification; @@ -586,7 +587,8 @@ void shouldCreateCacheRecordWhenTokenIsNotValid() throws EdcClientException { } private void prepareTestdata(final String catenaXId, final String submodelDataSuffix) - throws ContractNegotiationException, IOException, UsagePolicyException, TransferProcessException { + throws ContractNegotiationException, IOException, UsagePolicyPermissionException, TransferProcessException, + UsagePolicyExpiredException { final String agreementId = "agreementId"; when(contractNegotiationService.negotiate(any(), any(), diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelFacadeWiremockTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelFacadeWiremockTest.java index 5ae4c9b945..135fd74842 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelFacadeWiremockTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/SubmodelFacadeWiremockTest.java @@ -64,7 +64,7 @@ import org.eclipse.tractusx.irs.edc.client.cache.endpointdatareference.EndpointDataReferenceCacheService; import org.eclipse.tractusx.irs.edc.client.configuration.JsonLdConfiguration; import org.eclipse.tractusx.irs.edc.client.exceptions.EdcClientException; -import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyException; +import org.eclipse.tractusx.irs.edc.client.exceptions.UsagePolicyPermissionException; import org.eclipse.tractusx.irs.edc.client.model.EDRAuthCode; import org.eclipse.tractusx.irs.edc.client.policy.AcceptedPoliciesProvider; import org.eclipse.tractusx.irs.edc.client.policy.AcceptedPolicy; @@ -241,8 +241,8 @@ void shouldThrowExceptionWhenPoliciesAreNotAccepted() { givenThat(get(urlPathEqualTo(SUBMODEL_DATAPLANE_PATH)).willReturn(responseWithStatus(200).withBody("test"))); // Act & Assert - final String errorMessage = "Consumption of asset '5a7ab616-989f-46ae-bdf2-32027b9f6ee6-31b614f5-ec14-4ed2-a509-e7b7780083e7' is not permitted as the required catalog offer policies do not comply with defined IRS policies."; - assertThatExceptionOfType(UsagePolicyException.class).isThrownBy( + final String errorMessage = "Consumption of asset '5a7ab616-989f-46ae-bdf2-32027b9f6ee6-31b614f5-ec14-4ed2-a509-e7b7780083e7' is not permitted as the required catalog offer policies do not comply with defined policies."; + assertThatExceptionOfType(UsagePolicyPermissionException.class).isThrownBy( () -> edcSubmodelClient.getSubmodelPayload(CONNECTOR_ENDPOINT_URL, SUBMODEL_DATAPLANE_URL, ASSET_ID, "bpn") .get()).withMessageEndingWith(errorMessage); } diff --git a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerServiceTest.java b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerServiceTest.java index f62c317d4d..5f5c5df0fb 100644 --- a/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerServiceTest.java +++ b/irs-edc-client/src/test/java/org/eclipse/tractusx/irs/edc/client/policy/PolicyCheckerServiceTest.java @@ -252,4 +252,54 @@ private org.eclipse.tractusx.irs.edc.client.policy.Policy policy(final String po .build(); } + @Test + void shouldHaveNoExpiredConstraints() { + // given + final Constraint constraint1 = new Constraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, + new Operator(OperatorType.EQ), TestConstants.STATUS_ACTIVE); + final Constraint constraint2 = new Constraint(TestConstants.MEMBERSHIP, new Operator(OperatorType.EQ), + TestConstants.STATUS_ACTIVE); + final Constraint constraint3 = new Constraint(TestConstants.FRAMEWORK_AGREEMENT_DISMANTLER, + new Operator(OperatorType.EQ), TestConstants.STATUS_ACTIVE); + final var policyList = List.of( + new AcceptedPolicy(policy("and-policy", List.of(), List.of(constraint1, constraint2, constraint3)), + OffsetDateTime.now().plusYears(1))); + + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); + Policy policy = createOrConstraintPolicy( + List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, + TestConstants.STATUS_ACTIVE), + createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); + // when + boolean result = policyCheckerService.isExpired(policy, "bpn"); + + // then + assertThat(result).isFalse(); + } + + @Test + void shouldHaveExpiredConstraints() { + // given + final Constraint constraint1 = new Constraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, + new Operator(OperatorType.EQ), TestConstants.STATUS_ACTIVE); + final Constraint constraint2 = new Constraint(TestConstants.MEMBERSHIP, new Operator(OperatorType.EQ), + TestConstants.STATUS_ACTIVE); + final Constraint constraint3 = new Constraint(TestConstants.FRAMEWORK_AGREEMENT_DISMANTLER, + new Operator(OperatorType.EQ), TestConstants.STATUS_ACTIVE); + final var policyList = List.of( + new AcceptedPolicy(policy("and-policy", List.of(), List.of(constraint1, constraint2, constraint3)), + OffsetDateTime.now().minusYears(1))); + + when(policyStore.getAcceptedPolicies(any())).thenReturn(policyList); + Policy policy = createOrConstraintPolicy( + List.of(createAtomicConstraint(TestConstants.FRAMEWORK_AGREEMENT_TRACEABILITY, + TestConstants.STATUS_ACTIVE), + createAtomicConstraint(TestConstants.MEMBERSHIP, TestConstants.STATUS_ACTIVE))); + // when + boolean result = policyCheckerService.isExpired(policy, "bpn"); + + // then + assertThat(result).isTrue(); + } + } \ No newline at end of file