diff --git a/CHANGELOG.md b/CHANGELOG.md index 75b3e7e9ab..6b7da7f340 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ _**For better traceability add the corresponding GitHub issue number in each cha - #1037 extended autocomplete api by contractAgreementId - #985 Added function to save Contracts based on notification contractAgreementIds into the database - #985 Added function to filter notifications for contractAgreementIds +- XXX updated JsonSchemaTest now the test pulls the latest version of the json file +- XXX deactivated a test class in tx-backend which behaved undesirably +- #1017 updated contributing, notice, and readme files for TRG 7 +- #639 handle expired or incorrect policies when sending notifications - #786 Added authorization as admin for submodel api & registry api ### Added @@ -25,6 +29,7 @@ _**For better traceability add the corresponding GitHub issue number in each cha - XXX Added interceptor to EdcRestTemplates to log requests - #915 Added section to documentation: EDC-BPN configuration - #1037 Added link from contracts view to the corresponding filtered part table view +- #1017 added file for CC BY 4.0 license for TRG 7 - #985 Added reference to part/notification under contract - #786 Added icons on part table to let admin reload registry / sync assets via IRS @@ -33,19 +38,6 @@ _**For better traceability add the corresponding GitHub issue number in each cha - XXX Removed EdcNotifiactionMockServiceImpl class and replaced with mocks - #1033 removed action jira-publish-release workflow -### Changed - -- XXX updated JsonSchemaTest now the test pulls the latest version of the json file -- XXX deactivated a test class in tx-backend which behaved undesirably - -### Added - -- #1017 added file for CC BY 4.0 license for TRG 7 - -### Changed - -- #1017 updated contributing, notice, and readme files for TRG 7 - ## [11.0.2 - 29.05.2024] ### Added - #1010 Made submodel path configurable diff --git a/pom.xml b/pom.xml index a6deac18b2..d3dede946f 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ SPDX-License-Identifier: Apache-2.0 5.10.2 4.2.1 - 2.0.5 + 2.1.1 5.4.0 jacoco diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/infrastructure/base/irs/model/response/mapping/submodel/PartSiteInformationAsPlannedMapper.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/infrastructure/base/irs/model/response/mapping/submodel/PartSiteInformationAsPlannedMapper.java index 35212cbb4a..1a6cf2fe2e 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/infrastructure/base/irs/model/response/mapping/submodel/PartSiteInformationAsPlannedMapper.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/assets/infrastructure/base/irs/model/response/mapping/submodel/PartSiteInformationAsPlannedMapper.java @@ -55,7 +55,7 @@ private static List extractDetailAspectModelsPartSiteInformat List detailAspectModels = new ArrayList<>(); emptyIfNull(sites).forEach(site -> { DetailAspectDataPartSiteInformationAsPlanned detailAspectDataPartSiteInformationAsPlanned = DetailAspectDataPartSiteInformationAsPlanned.builder() - .catenaXSiteId(site.catenaXSiteId()) + .catenaXSiteId(site.catenaXsiteId()) .functionValidFrom(site.functionValidFrom().toOffsetDateTime()) .function(site.function()) .functionValidUntil(site.functionValidUntil().toOffsetDateTime()) diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/AbstractNotificationService.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/AbstractNotificationService.java index 27c081763d..de46d594dc 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/AbstractNotificationService.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/AbstractNotificationService.java @@ -156,7 +156,7 @@ public void approve(Long notificationId) { approvedInvestigation = notificationPublisherService.approveNotification(notification); } catch (SendNotificationException exception) { log.info("Notification status rollback", exception); - throw new SendNotificationException(exception.getMessage()); + throw new SendNotificationException(exception.getMessage(), exception); } getNotificationRepository().updateNotification(approvedInvestigation); } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/EdcNotificationServiceImpl.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/EdcNotificationServiceImpl.java index c688f8ef00..83e0aa012b 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/EdcNotificationServiceImpl.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/base/service/EdcNotificationServiceImpl.java @@ -86,7 +86,7 @@ public CompletableFuture asyncNotificationMessageExecutor(N return CompletableFuture.completedFuture(null); } catch (DiscoveryFinderException discoveryFinderException) { - enrichNotificationByError(discoveryFinderException, notification); + enrichNotificationByError(discoveryFinderException, notification, message); return CompletableFuture.completedFuture(null); } } @@ -97,30 +97,25 @@ private boolean handleSendingNotification(NotificationMessage message, String se return true; } catch (NoCatalogItemException e) { log.warn("Could not send message to {} no catalog item found. ", receiverUrl, e); - enrichNotificationByError(e, notification); + enrichNotificationByError(e, notification, message); } catch (SendNotificationException e) { log.warn("Could not send message to {} ", receiverUrl, e); - enrichNotificationByError(e, notification); + enrichNotificationByError(e, notification, message); } catch (NoEndpointDataReferenceException e) { log.warn("Could not send message to {} no endpoint data reference found", receiverUrl, e); - enrichNotificationByError(e, notification); + enrichNotificationByError(e, notification, message); } catch (ContractNegotiationException e) { log.warn("Could not send message to {} could not negotiate contract agreement", receiverUrl, e); - enrichNotificationByError(e, notification); + enrichNotificationByError(e, notification, message); } return false; } - private void enrichNotificationByError(Exception e, Notification notification) { + private void enrichNotificationByError(Exception e, Notification notification, NotificationMessage message) { - log.info("Notification for error message enrichment {}", notification); - notification.getNotifications().forEach(message1 -> log.info("Message found {}", message1)); - notification.secondLatestNotifications().forEach(qmMessage -> { - log.info("Message from second latest notification {}", qmMessage); - qmMessage.setErrorMessage(e.getMessage()); - }); - - notificationRepository.updateErrorMessage(notification); + log.info("Notification for error message enrichment {}", message); + message.setErrorMessage(e.getMessage()); + notificationRepository.updateErrorMessage(notification, 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 b2fb81a840..f5b481bb7e 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 @@ -129,7 +129,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); } } @@ -164,14 +164,6 @@ private CatalogItem getCatalogItem(final NotificationMessage notification, final .build()) .build() ).stream() - .filter(catalogItem -> { - log.info("-- catalog item check --"); - log.info("Item {}: {}", catalogItem.getItemId(), catalogItem); - boolean isValid = policyCheckerService.isValid(catalogItem.getPolicy(), notification.getSentTo() - ); - log.info("IsValid : {}", isValid); - return isValid; - }) .findFirst() .orElseThrow(); } catch (Exception e) { diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/notification/repository/NotificationRepository.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/notification/repository/NotificationRepository.java index 2ad016bbd6..3607540683 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/notification/repository/NotificationRepository.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/domain/notification/repository/NotificationRepository.java @@ -26,6 +26,7 @@ import org.eclipse.tractusx.traceability.common.model.SearchCriteria; import org.eclipse.tractusx.traceability.notification.domain.base.model.Notification; import org.eclipse.tractusx.traceability.notification.domain.base.model.NotificationId; +import org.eclipse.tractusx.traceability.notification.domain.base.model.NotificationMessage; import org.eclipse.tractusx.traceability.notification.domain.base.model.NotificationSide; import org.eclipse.tractusx.traceability.notification.domain.base.model.NotificationType; import org.springframework.data.domain.Pageable; @@ -53,7 +54,7 @@ public interface NotificationRepository { List getDistinctFieldValues(String fieldName, String startWith, Integer resultLimit, NotificationSide owner); - void updateErrorMessage(Notification investigation); + void updateErrorMessage(Notification notification, NotificationMessage message); void deleteByIdIn(List messageIds); diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/infrastructure/notification/repository/JpaNotificationMessageRepository.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/infrastructure/notification/repository/JpaNotificationMessageRepository.java index e7d01e536f..7b609f0755 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/infrastructure/notification/repository/JpaNotificationMessageRepository.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/infrastructure/notification/repository/JpaNotificationMessageRepository.java @@ -22,7 +22,12 @@ import org.eclipse.tractusx.traceability.notification.infrastructure.notification.model.NotificationMessageEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; @Repository public interface JpaNotificationMessageRepository extends JpaRepository { + @Transactional + default NotificationMessageEntity updateOrInsert(NotificationMessageEntity notificationMessageEntity) { + return save(notificationMessageEntity); + } } diff --git a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/infrastructure/notification/repository/NotificationRepositoryImpl.java b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/infrastructure/notification/repository/NotificationRepositoryImpl.java index 0268b78681..7ceae9ac47 100644 --- a/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/infrastructure/notification/repository/NotificationRepositoryImpl.java +++ b/tx-backend/src/main/java/org/eclipse/tractusx/traceability/notification/infrastructure/notification/repository/NotificationRepositoryImpl.java @@ -21,7 +21,6 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; -import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.traceability.assets.domain.base.model.Owner; @@ -48,6 +47,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; import java.time.Clock; import java.time.LocalDateTime; @@ -163,19 +163,16 @@ public List getDistinctFieldValues(String fieldName, String startWith, I } @Override - public void updateErrorMessage(Notification notification) { + public void updateErrorMessage(Notification notification, NotificationMessage message) { log.info("Starting update of error message with notification {}", notification); NotificationEntity notificationEntity = jpaNotificationRepository.findById(notification.getNotificationId().value()) .orElseThrow(() -> new IllegalArgumentException(String.format("Notification with id %s not found!", notification.getNotificationId().value()))); - for (NotificationMessage notificationMessage : notification.getNotifications()) { - List assetEntitiesByNotification = getAssetEntitiesByNotification(notification); - NotificationMessageEntity notificationMessageEntity = toNotificationMessageEntity(notificationEntity, notificationMessage, assetEntitiesByNotification); - notificationMessageEntity.setErrorMessage(notificationMessage.getErrorMessage()); - notificationMessageEntity.setUpdated(LocalDateTime.ofInstant(clock.instant(), clock.getZone())); - jpaNotificationMessageRepository.save(notificationMessageEntity); - } - jpaNotificationRepository.save(notificationEntity); + List assetEntitiesByNotification = getAssetEntitiesByNotification(notification); + NotificationMessageEntity notificationMessageEntity = toNotificationMessageEntity(notificationEntity, message, assetEntitiesByNotification); + notificationMessageEntity.setErrorMessage(message.getErrorMessage()); + notificationMessageEntity.setUpdated(LocalDateTime.ofInstant(clock.instant(), clock.getZone())); + jpaNotificationMessageRepository.updateOrInsert(notificationMessageEntity); } @Override diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/NotificationsEDCFacadeTest.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/NotificationsEDCFacadeTest.java index 3b5aa06db1..a74104197b 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/NotificationsEDCFacadeTest.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/infrastructure/edc/blackbox/NotificationsEDCFacadeTest.java @@ -63,12 +63,8 @@ class NotificationsEDCFacadeTest { @Mock EndpointDataReferenceStorage endpointDataReferenceStorage; @Mock - PolicyCheckerService policyCheckerService; - @Mock EndpointDataReference endpointDataReference; @Mock - NotificationRepository notificationRepository; - @Mock Notification notification; @InjectMocks NotificationsEDCFacade notificationsEDCFacade; @@ -92,7 +88,6 @@ void givenCorrectInvestigationMessageButSendRequestThrowsException_whenStartEdcT when(notification.getSeverity()).thenReturn(NotificationSeverity.MAJOR); when(edcProperties.getIdsPath()).thenReturn(idsPath); when(edcCatalogFacade.fetchCatalogItems(any())).thenReturn(List.of(catalogItem)); - when(policyCheckerService.isValid(null, null)).thenReturn(true); when(contractNegotiationService.negotiate(receiverEdcUrl + idsPath, catalogItem, null, null)) .thenReturn(NegotiationResponse.builder().contractAgreementId(agreementId).build()); when(endpointDataReference.getEndpoint()).thenReturn("endpoint"); @@ -121,7 +116,6 @@ void givenCorrectInvestigationMessageButNegotiateContractAgreementHasNoCatalogIt final String idsPath = "/api/v1/dsp"; when(edcProperties.getIdsPath()).thenReturn(idsPath); when(edcCatalogFacade.fetchCatalogItems(any())).thenReturn(List.of(catalogItem)); - when(policyCheckerService.isValid(null, null)).thenReturn(true); when(contractNegotiationService.negotiate(receiverEdcUrl + idsPath, catalogItem, null, null)) .thenReturn(null); diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/IntegrationTestSpecification.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/IntegrationTestSpecification.java index 176e60bd98..48318e10d4 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/IntegrationTestSpecification.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/IntegrationTestSpecification.java @@ -19,6 +19,7 @@ package org.eclipse.tractusx.traceability.integration; import groovy.json.JsonBuilder; +import io.restassured.RestAssured; import org.awaitility.Awaitility; import org.eclipse.tractusx.traceability.integration.common.config.PostgreSQLConfig; import org.eclipse.tractusx.traceability.integration.common.config.RestAssuredConfig; @@ -33,6 +34,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; @@ -56,8 +58,12 @@ public class IntegrationTestSpecification { @Autowired DatabaseSupport databaseSupport; + @LocalServerPort + private Integer port; + @BeforeEach void beforeEach() throws JoseException { + RestAssured.port = port; oAuth2ApiSupport.oauth2ApiReturnsTechnicalUserToken(); oAuth2ApiSupport.oauth2ApiReturnsJwkCerts(oAuth2Support.jwk()); } 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..9b8c3ea1e6 --- /dev/null +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/InvestigationPolicyExpirationIT.java @@ -0,0 +1,152 @@ +/******************************************************************************** + * 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.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; + +import java.util.Collections; +import java.util.List; + +import static io.restassured.RestAssured.given; +import static org.eclipse.tractusx.traceability.common.security.JwtRole.SUPERVISOR; + +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; + + + @DynamicPropertySource + static void dynamicProperties(DynamicPropertyRegistry registry) { + registry.add("traceability.validUntil", () -> "2020-07-04T16:01:05.309Z"); + registry.add("server.port", () -> "9997"); + registry.add("management.server.port", () -> "8083"); + } + + @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()))) + .body("content[0].messages[0].errorMessage", Matchers.is("Failed to negotiate contract agreement: Policy from BPNL00000003CNKC has expired.")) + .body("content[0].messages[1].errorMessage", Matchers.is("Failed to negotiate contract agreement: Policy from BPNL00000003CNKC has expired.")); + + notificationMessageSupport.assertMessageSize(2); + } +} diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/InvestigationPolicyNotSupportedIT.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/InvestigationPolicyNotSupportedIT.java new file mode 100644 index 0000000000..335210a109 --- /dev/null +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/integration/notification/investigation/InvestigationPolicyNotSupportedIT.java @@ -0,0 +1,152 @@ +/******************************************************************************** + * 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.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; + +import java.util.Collections; +import java.util.List; + +import static io.restassured.RestAssured.given; +import static org.eclipse.tractusx.traceability.common.security.JwtRole.SUPERVISOR; + +public class InvestigationPolicyNotSupportedIT 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; + + + @DynamicPropertySource + static void dynamicProperties(DynamicPropertyRegistry registry) { + registry.add("traceability.leftOperand", () -> "unsopperted operand"); + registry.add("server.port", () -> "9996"); + registry.add("management.server.port", () -> "8084"); + } + + @BeforeEach + void setUp() { + objectMapper = new ObjectMapper(); + } + + @Test + void shouldNotApproveInvestigationStatus_whenPolicyDoesNotComply() 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()))) + .body("content[0].messages[0].errorMessage", Matchers.endsWith("did not match with policy from BPNL00000003CNKC.")) + .body("content[0].messages[1].errorMessage", Matchers.endsWith("did not match with policy from BPNL00000003CNKC.")); + + notificationMessageSupport.assertMessageSize(2); + } +} diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/notification/infrastructure/investigation/repository/InvestigationsRepositoryImplTest.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/notification/infrastructure/investigation/repository/InvestigationsRepositoryImplTest.java index 6d2c18df08..979af1cda0 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/notification/infrastructure/investigation/repository/InvestigationsRepositoryImplTest.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/notification/infrastructure/investigation/repository/InvestigationsRepositoryImplTest.java @@ -78,9 +78,9 @@ void updateErrorMessage() { when(clock.instant()).thenReturn(Instant.now()); when(clock.getZone()).thenReturn(ZoneId.systemDefault()); // When - investigationsRepository.updateErrorMessage(notification); + investigationsRepository.updateErrorMessage(notification, message); // Then - verify(jpaNotificationMessageRepository, times(1)).save(any()); + verify(jpaNotificationMessageRepository, times(1)).updateOrInsert(any()); } } diff --git a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/notification/infrastructure/investigation/repository/NotificationRepositoryImplTest.java b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/notification/infrastructure/investigation/repository/NotificationRepositoryImplTest.java index a40606cf15..4699938753 100644 --- a/tx-backend/src/test/java/org/eclipse/tractusx/traceability/notification/infrastructure/investigation/repository/NotificationRepositoryImplTest.java +++ b/tx-backend/src/test/java/org/eclipse/tractusx/traceability/notification/infrastructure/investigation/repository/NotificationRepositoryImplTest.java @@ -78,9 +78,9 @@ void updateErrorMessage() { when(clock.instant()).thenReturn(Instant.now()); when(clock.getZone()).thenReturn(ZoneId.systemDefault()); // When - notificationRepository.updateErrorMessage(notification); + notificationRepository.updateErrorMessage(notification, message); // Then - verify(jpaNotificationMessageRepository, times(1)).save(any()); + verify(jpaNotificationMessageRepository, times(1)).updateOrInsert(any()); } }