diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/exception/ContractNegotiationException.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/exception/ContractNegotiationException.java index d1eac30166..48754905c0 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/exception/ContractNegotiationException.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/exception/ContractNegotiationException.java @@ -19,9 +19,15 @@ package org.eclipse.tractusx.traceability.notification.domain.base.exception; +import lombok.Getter; + +@Getter public class ContractNegotiationException extends RuntimeException { - public ContractNegotiationException(final String message, final Throwable exception) { + private String reason; + + public ContractNegotiationException(final String message, final String reason, final Throwable exception) { super(message, exception); + this.reason = reason; } public ContractNegotiationException(final String message) { diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/NotificationsEDCFacade.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/NotificationsEDCFacade.java index c917bbedce..9f8ceea407 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/NotificationsEDCFacade.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/NotificationsEDCFacade.java @@ -119,7 +119,7 @@ private String negotiateContractAgreement(final String receiverEdcUrl, final Cat .orElseThrow() .getContractAgreementId(); } catch (Exception e) { - throw new ContractNegotiationException("Failed to negotiate contract agreement. ", e); + throw new ContractNegotiationException("Failed to negotiate contract agreement. ", e.getMessage(), e); } } diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/ContractNegotiationExceptionTest.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/ContractNegotiationExceptionTest.java index 9001b1880e..a0bad7cc62 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/ContractNegotiationExceptionTest.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/ContractNegotiationExceptionTest.java @@ -41,7 +41,7 @@ void givenContractNegotiationExceptionWithThrowable_thenShouldHaveProperMessageA // given final String message = "message"; final Throwable exceptionParam = new RuntimeException("test"); - ContractNegotiationException exception = new ContractNegotiationException(message, exceptionParam); + ContractNegotiationException exception = new ContractNegotiationException(message, exceptionParam.getMessage(), exceptionParam); // then assertThat(exception.getMessage()).isEqualTo(message); diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/InvestigationPolicyExpirationIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/InvestigationPolicyExpirationIT.java new file mode 100644 index 0000000000..81d55adfe6 --- /dev/null +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/InvestigationPolicyExpirationIT.java @@ -0,0 +1,142 @@ +/******************************************************************************** + * Copyright (c) 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.traceability.integration.notification.investigation; + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.restassured.http.ContentType; +import lombok.val; +import notification.request.NotificationSeverityRequest; +import notification.request.NotificationTypeRequest; +import notification.request.StartNotificationRequest; +import org.eclipse.tractusx.traceability.assets.domain.asbuilt.repository.AssetAsBuiltRepository; +import org.eclipse.tractusx.traceability.common.request.OwnPageable; +import org.eclipse.tractusx.traceability.common.request.PageableFilterRequest; +import org.eclipse.tractusx.traceability.common.request.SearchCriteriaRequestParam; +import org.eclipse.tractusx.traceability.integration.IntegrationTestSpecification; +import org.eclipse.tractusx.traceability.integration.common.support.AssetsSupport; +import org.eclipse.tractusx.traceability.integration.common.support.DiscoveryFinderSupport; +import org.eclipse.tractusx.traceability.integration.common.support.EdcSupport; +import org.eclipse.tractusx.traceability.integration.common.support.IrsApiSupport; +import org.eclipse.tractusx.traceability.integration.common.support.NotificationApiSupport; +import org.eclipse.tractusx.traceability.integration.common.support.NotificationMessageSupport; +import org.eclipse.tractusx.traceability.integration.common.support.NotificationSupport; +import org.eclipse.tractusx.traceability.integration.common.support.OAuth2ApiSupport; +import org.eclipse.tractusx.traceability.notification.domain.notification.service.NotificationReceiverService; +import org.hamcrest.Matchers; +import org.jose4j.lang.JoseException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.TestPropertySource; + +import java.util.Collections; +import java.util.List; + +import static io.restassured.RestAssured.given; +import static org.eclipse.tractusx.traceability.common.security.JwtRole.SUPERVISOR; + +@TestPropertySource(properties = "traceability.validUntil=2020-07-04T16:01:05.309Z") +public class InvestigationPolicyExpirationIT extends IntegrationTestSpecification { + @Autowired + NotificationReceiverService notificationReceiverService; + @Autowired + AssetsSupport assetsSupport; + @Autowired + NotificationMessageSupport notificationMessageSupport; + @Autowired + NotificationSupport notificationSupport; + @Autowired + AssetAsBuiltRepository assetAsBuiltRepository; + @Autowired + NotificationApiSupport notificationApiSupport; + @Autowired + EdcSupport edcSupport; + + @Autowired + DiscoveryFinderSupport discoveryFinderSupport; + + @Autowired + OAuth2ApiSupport oauth2ApiSupport; + + @Autowired + IrsApiSupport irsApiSupport; + + ObjectMapper objectMapper; + + @BeforeEach + void setUp() { + objectMapper = new ObjectMapper(); + } + + @Test + void shouldNotApproveInvestigationStatus_whenPolicyIsExpired() throws JoseException, com.fasterxml.jackson.core.JsonProcessingException { + // given + irsApiSupport.irsApiReturnsPolicies(); + discoveryFinderSupport.discoveryFinderWillReturnEndpointAddress(); + discoveryFinderSupport.discoveryFinderWillReturnConnectorEndpoints(); + oauth2ApiSupport.oauth2ApiReturnsDtrToken(); + edcSupport.performSupportActionsForAsyncNotificationMessageExecutor(); + List partIds = List.of( + "urn:uuid:fe99da3d-b0de-4e80-81da-882aebcca978", // BPN: BPNL00000003AYRE + "urn:uuid:0ce83951-bc18-4e8f-892d-48bad4eb67ef" // BPN: BPNL00000003AXS3 + ); + String description = "at least 15 characters long investigation description"; + + assetsSupport.defaultAssetsStored(); + val startInvestigationRequest = StartNotificationRequest.builder() + .affectedPartIds(partIds) + .description(description) + .severity(NotificationSeverityRequest.MINOR) + .type(NotificationTypeRequest.INVESTIGATION) + .receiverBpn("BPNL00000003CNKC") + .build(); + + // when + val investigationId = notificationApiSupport.createNotificationRequest_withDefaultAssetsStored(oAuth2Support.jwtAuthorization(SUPERVISOR), startInvestigationRequest, 201); + + + notificationSupport.assertInvestigationsSize(1); + + given() + .contentType(ContentType.JSON) + .header(oAuth2Support.jwtAuthorization(SUPERVISOR)) + .when() + .post("/api/notifications/{investigationId}/approve", investigationId) + .then() + .log().all() + .statusCode(503); + + // then + given() + .header(oAuth2Support.jwtAuthorization(SUPERVISOR)) + .body(new PageableFilterRequest(new OwnPageable(0, 10, Collections.emptyList()), new SearchCriteriaRequestParam(List.of("channel,EQUAL,SENDER,AND")))) + .contentType(ContentType.JSON) + .when() + .post("/api/notifications/filter") + .then() + .log().all() + .statusCode(200) + .body("page", Matchers.is(0)) + .body("pageSize", Matchers.is(10)) + .body("content", Matchers.hasSize(1)) + .body("content[0].sendTo", Matchers.is(Matchers.not(Matchers.blankOrNullString()))); + + notificationMessageSupport.assertMessageSize(2); + } +} diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/PublisherInvestigationsControllerIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/PublisherInvestigationsControllerIT.java index 7dbad99cbb..6d7b4fc223 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/PublisherInvestigationsControllerIT.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/PublisherInvestigationsControllerIT.java @@ -579,4 +579,59 @@ void shouldBeCreatedBySender() throws JoseException, JsonProcessingException { .body("content", Matchers.hasSize(1)); } + @Test + void shouldNotApproveInvestigationStatus_whenPolicyIsExpired() throws JoseException, com.fasterxml.jackson.core.JsonProcessingException { + // given + irsApiSupport.irsApiReturnsPolicies(); + discoveryFinderSupport.discoveryFinderWillReturnEndpointAddress(); + discoveryFinderSupport.discoveryFinderWillReturnConnectorEndpoints(); + oauth2ApiSupport.oauth2ApiReturnsDtrToken(); + edcSupport.performSupportActionsForAsyncNotificationMessageExecutor(); + List partIds = List.of( + "urn:uuid:fe99da3d-b0de-4e80-81da-882aebcca978", // BPN: BPNL00000003AYRE + "urn:uuid:0ce83951-bc18-4e8f-892d-48bad4eb67ef" // BPN: BPNL00000003AXS3 + ); + String description = "at least 15 characters long investigation description"; + + assetsSupport.defaultAssetsStored(); + val startInvestigationRequest = StartNotificationRequest.builder() + .affectedPartIds(partIds) + .description(description) + .severity(NotificationSeverityRequest.MINOR) + .type(NotificationTypeRequest.INVESTIGATION) + .receiverBpn("BPNL00000003CNKC") + .build(); + + // when + val investigationId = notificationApiSupport.createNotificationRequest_withDefaultAssetsStored(oAuth2Support.jwtAuthorization(SUPERVISOR), startInvestigationRequest, 201); + + + notificationSupport.assertInvestigationsSize(1); + + given() + .contentType(ContentType.JSON) + .header(oAuth2Support.jwtAuthorization(SUPERVISOR)) + .when() + .post("/api/notifications/{investigationId}/approve", investigationId) + .then() + .statusCode(204); + + // then + given() + .header(oAuth2Support.jwtAuthorization(SUPERVISOR)) + .body(new PageableFilterRequest(new OwnPageable(0, 10, Collections.emptyList()), new SearchCriteriaRequestParam(List.of("channel,EQUAL,SENDER,AND")))) + .contentType(ContentType.JSON) + .when() + .post("/api/notifications/filter") + .then() + .log().all() + .statusCode(200) + .body("page", Matchers.is(0)) + .body("pageSize", Matchers.is(10)) + .body("content", Matchers.hasSize(1)) + .body("content[0].sendTo", Matchers.is(Matchers.not(Matchers.blankOrNullString()))); + + notificationMessageSupport.assertMessageSize(4); + } + }