From 62ecb05dfec3293176876b49202a6b695a5bcf78 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Fri, 27 Oct 2023 10:31:10 +0200 Subject: [PATCH 01/54] feat(impl):[TRI-1641] hops implementation --- .../irs/ess/service/BpnInvestigationJob.java | 28 ++++++---- .../tractusx/irs/ess/service/EssService.java | 12 ++++- ...vestigationJobProcessingEventListener.java | 12 ++--- .../irs/ess/service/SupplyChainImpacted.java | 2 + .../service/SupplyChainImpactedAspect.java | 51 +++++++++++++++++++ .../eclipse/tractusx/irs/util/JsonUtil.java | 13 +++++ .../irs/ess/service/EssServiceTest.java | 10 ++-- .../ResponseNotificationContent.java | 5 ++ 8 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index 718675c882..86228dfad7 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -28,8 +28,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Optional; +import java.util.Set; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -39,6 +39,9 @@ import org.eclipse.tractusx.irs.component.Submodel; import org.eclipse.tractusx.irs.component.Summary; import org.eclipse.tractusx.irs.component.enums.JobState; +import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification; +import org.eclipse.tractusx.irs.edc.client.model.notification.ResponseNotificationContent; +import org.eclipse.tractusx.irs.util.JsonUtil; /** * Object to store in cache @@ -52,7 +55,7 @@ public class BpnInvestigationJob { private Jobs jobSnapshot; private List incidentBpns; private List unansweredNotifications; - private List answeredNotifications; + private List> answeredNotifications; private JobState state; public BpnInvestigationJob(final Jobs jobSnapshot, final List incidentBpns) { @@ -60,11 +63,14 @@ public BpnInvestigationJob(final Jobs jobSnapshot, final List incidentBp } private static Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, - final SupplyChainImpacted supplyChainImpacted) { + final SupplyChainImpacted supplyChainImpacted, final Integer hops) { + final SupplyChainImpactedAspect supplyChainImpactedAspect = SupplyChainImpactedAspect.builder() + .supplyChainImpacted(supplyChainImpacted) + .impactedSuppliersOnFirstTier(Set.of(new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel("", hops))) + .build(); final Submodel supplyChainImpactedSubmodel = Submodel.builder() .aspectType(SUPPLY_CHAIN_ASPECT_TYPE) - .payload(Map.of("supplyChainImpacted", - supplyChainImpacted.getDescription())) + .payload(new JsonUtil().asMap(supplyChainImpactedAspect)) .build(); return irsJob.toBuilder() @@ -78,13 +84,14 @@ private static Jobs updateLastModified(final Jobs irsJob, final ZonedDateTime la return irsJob.toBuilder().job(job).build(); } - public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain) { + public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain, + final Integer hops) { final Optional previousSupplyChain = getSupplyChainImpacted(); final SupplyChainImpacted supplyChainImpacted = previousSupplyChain.map( prevSupplyChain -> prevSupplyChain.or(newSupplyChain)).orElse(newSupplyChain); - this.jobSnapshot = extendJobWithSupplyChainSubmodel(jobSnapshot, supplyChainImpacted); + this.jobSnapshot = extendJobWithSupplyChainSubmodel(jobSnapshot, supplyChainImpacted, hops); this.jobSnapshot = extendSummary(this.jobSnapshot); this.jobSnapshot = updateLastModified(this.jobSnapshot, ZonedDateTime.now(ZoneOffset.UTC)); return this; @@ -116,9 +123,10 @@ public BpnInvestigationJob withNotifications(final List notifications) { return this; } - public BpnInvestigationJob withAnsweredNotification(final String notificationId) { - this.unansweredNotifications.remove(notificationId); - this.answeredNotifications.add(notificationId); + public BpnInvestigationJob withAnsweredNotification(final EdcNotification notification) { + this.unansweredNotifications.remove(notification.getHeader().getOriginalNotificationId()); + notification.getContent().incrementHops(); + this.answeredNotifications.add(notification); return this; } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 0ef9a2bde4..1e1a5a7077 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -23,6 +23,7 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.ess.service; +import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -109,7 +110,7 @@ public void handleNotificationCallback(final EdcNotification { final String originalNotificationId = notification.getHeader().getOriginalNotificationId(); - job.withAnsweredNotification(originalNotificationId); + job.withAnsweredNotification(notification); final Optional notificationResult = Optional.ofNullable(notification.getContent().getResult()) .map(Object::toString); @@ -124,7 +125,14 @@ public void handleNotificationCallback(final EdcNotification minHops = job.getAnsweredNotifications() + .stream() + .map(EdcNotification::getContent) + .min(Comparator.comparing( + ResponseNotificationContent::getHops)); + final Integer hops = minHops.map(ResponseNotificationContent::getHops).orElse(0); + + bpnInvestigationJobCache.store(jobId, job.update(job.getJobSnapshot(), supplyChainImpacted, hops)); recursiveNotificationHandler.handleNotification(jobId, supplyChainImpacted); }); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java index dd9151b495..d474bfbe86 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java @@ -190,7 +190,7 @@ public void handleJobProcessingFinishedEvent(final JobProcessingFinishedEvent jo partSiteInformationAsPlannedValidity, supplyChainImpacted); final BpnInvestigationJob investigationJobUpdate = investigationJob.update(completedJob, - supplyChainImpacted); + supplyChainImpacted, 0); if (leafNodeIsReached(completedJob) || supplyChainIsImpacted(supplyChainImpacted)) { bpnInvestigationJobCache.store(completedJobId, investigationJobUpdate.complete()); @@ -214,7 +214,7 @@ private void triggerInvestigationOnNextLevel(final Jobs completedJob, log.debug("Triggering investigation on the next level."); if (anyBpnIsMissingFromRelationship(completedJob)) { log.error("One or more Relationship items did not contain a BPN."); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); } // Map> final Map> bpns = getBPNsFromRelationships(completedJob.getRelationships()); @@ -231,12 +231,12 @@ private void triggerInvestigationOnNextLevel(final Jobs completedJob, log.debug("BPNs '{}' could not be resolved to an EDC address using DiscoveryService.", unresolvedBPNs); log.info("Some EDC addresses could not be resolved with DiscoveryService. " + "Updating SupplyChainImpacted to {}", SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); recursiveNotificationHandler.handleNotification(investigationJobUpdate.getJobSnapshot().getJob().getId(), SupplyChainImpacted.UNKNOWN); } else if (resolvedBPNs.isEmpty()) { log.info("No BPNs could not be found. Updating SupplyChainImpacted to {}", SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); recursiveNotificationHandler.handleNotification(investigationJobUpdate.getJobSnapshot().getJob().getId(), SupplyChainImpacted.UNKNOWN); } else { @@ -251,7 +251,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo final List edcBaseUrl = connectorEndpointsService.fetchConnectorEndpoints(bpn); if (edcBaseUrl.isEmpty()) { log.warn("No EDC URL found for BPN '{}'. Setting investigation result to '{}'", bpn, SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); } edcBaseUrl.forEach(url -> { try { @@ -260,7 +260,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo investigationJobUpdate.withNotifications(Collections.singletonList(notificationId)); } catch (final EdcClientException e) { log.error("Exception during sending EDC notification.", e); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); } }); }); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpacted.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpacted.java index 019aa5064e..9b617cfe4d 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpacted.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpacted.java @@ -25,6 +25,7 @@ import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonValue; import lombok.Getter; /** @@ -36,6 +37,7 @@ public enum SupplyChainImpacted { UNKNOWN("Unknown"); @Getter + @JsonValue private final String description; SupplyChainImpacted(final String description) { diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java new file mode 100644 index 0000000000..8457b34a02 --- /dev/null +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java @@ -0,0 +1,51 @@ +/******************************************************************************** + * Copyright (c) 2021,2022,2023 + * 2022: ZF Friedrichshafen AG + * 2022: ISTOS GmbH + * 2022,2023: Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * 2022,2023: BOSCH AG + * Copyright (c) 2021,2022,2023 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.ess.service; + +import java.util.Set; + +import lombok.Builder; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +/** + * Supply Chain Impacted aspect representation + */ +@Value +@Builder(toBuilder = true) +@Jacksonized +public class SupplyChainImpactedAspect { + private final SupplyChainImpacted supplyChainImpacted; + private final Set impactedSuppliersOnFirstTier; + + /** + * BPNLs on first tier level where infection was detected + * @param bpnl + * @param hops + */ + @Builder(toBuilder = true) + @Jacksonized + record ImpactedSupplierFirstLevel(String bpnl, Integer hops) { + } +} diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java index 53756a08ae..411616f4d8 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java @@ -23,7 +23,10 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.util; +import java.util.Map; + import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -75,6 +78,16 @@ public String asString(final Object input) { } } + /** + * Serialize an object as a Map {@link Map}. + * + * @param input the object to serialize. + * @return the Map representation of the object + */ + public Map asMap(final Object input) { + return MAPPER.convertValue(input, new TypeReference<>() { }); + } + /** * Deserialize an object from a JSON {@link String}. * diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index c6616494c9..22f61d6365 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -115,7 +115,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { final UUID jobId = UUID.randomUUID(); final String owner = securityHelperService.getClientIdClaim(); - final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").build(); + final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() .notificationId(notificationId) .originalNotificationId(notificationId) @@ -124,7 +124,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { .header(header1) .content(resultNo) .build(); - final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").build(); + final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").hops(0).build(); final EdcNotificationHeader header2 = EdcNotificationHeader.builder() .notificationId(notificationId2) .originalNotificationId(notificationId2) @@ -199,7 +199,7 @@ void shouldCompleteJobIfAllNotificationsSentWereAnswered() { final UUID jobId = UUID.randomUUID(); final Jobs jobSnapshot = job(jobId, owner); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, - null).withAnsweredNotification(notificationId).withNotifications(List.of()); + null)/*.withAnsweredNotification(notificationId)*/.withNotifications(List.of()); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); // Act @@ -220,9 +220,9 @@ void shouldCompleteJobIfFinalNotificationWasReceived() { final Jobs jobSnapshot = job(jobId, owner); final String notificationId = UUID.randomUUID().toString(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, null).update(jobSnapshot, - SupplyChainImpacted.NO).withNotifications(List.of(notificationId)); + SupplyChainImpacted.NO, 0).withNotifications(List.of(notificationId)); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); - final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").build(); + final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() .notificationId(notificationId) .originalNotificationId(notificationId) diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index a9b14d306e..c2ec06ab60 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -35,4 +35,9 @@ @Jacksonized public class ResponseNotificationContent implements NotificationContent { private final String result; + private Integer hops; + + public void incrementHops() { + hops += 1; + } } From 77fa64cf1f8ed03710ac0f60c2c3cc6da95dcca7 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Fri, 27 Oct 2023 13:58:13 +0200 Subject: [PATCH 02/54] feat(impl):[TRI-1641] fixes and improvements --- .../irs/ess/service/BpnInvestigationJob.java | 10 ++++----- .../tractusx/irs/ess/service/EssService.java | 17 ++++++++------- ...vestigationJobProcessingEventListener.java | 2 +- .../irs/ess/service/EssServiceTest.java | 21 +++++++++++++++---- .../ResponseNotificationContent.java | 4 ++++ pom.xml | 1 + 6 files changed, 37 insertions(+), 18 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index 86228dfad7..964f6be58b 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -54,7 +54,7 @@ public class BpnInvestigationJob { private Jobs jobSnapshot; private List incidentBpns; - private List unansweredNotifications; + private List unansweredNotificationIds; private List> answeredNotifications; private JobState state; @@ -112,19 +112,19 @@ private Jobs extendSummary(final Jobs irsJob) { final Summary oldSummary = Optional.ofNullable(irsJob.getJob().getSummary()).orElse(Summary.builder().build()); final NotificationSummary newSummary = new NotificationSummary(oldSummary.getAsyncFetchedItems(), oldSummary.getBpnLookups(), - new NotificationItems(unansweredNotifications.size() + answeredNotifications.size(), + new NotificationItems(unansweredNotificationIds.size() + answeredNotifications.size(), answeredNotifications.size())); final Job job = irsJob.getJob().toBuilder().summary(newSummary).build(); return irsJob.toBuilder().job(job).build(); } - public BpnInvestigationJob withNotifications(final List notifications) { - this.unansweredNotifications.addAll(notifications); + public BpnInvestigationJob withUnansweredNotificationIds(final List notifications) { + this.unansweredNotificationIds.addAll(notifications); return this; } public BpnInvestigationJob withAnsweredNotification(final EdcNotification notification) { - this.unansweredNotifications.remove(notification.getHeader().getOriginalNotificationId()); + this.unansweredNotificationIds.remove(notification.getHeader().getOriginalNotificationId()); notification.getContent().incrementHops(); this.answeredNotifications.add(notification); return this; diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 1e1a5a7077..1c0dc348af 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -118,21 +118,22 @@ public void handleNotificationCallback(final EdcNotification minHops = job.getAnsweredNotifications() + final Optional minHopsWithIncident = job.getAnsweredNotifications() .stream() .map(EdcNotification::getContent) + .filter(ResponseNotificationContent::thereIsIncident) .min(Comparator.comparing( ResponseNotificationContent::getHops)); - final Integer hops = minHops.map(ResponseNotificationContent::getHops).orElse(0); + final Integer minHops = minHopsWithIncident.map(ResponseNotificationContent::getHops).orElse(0); - bpnInvestigationJobCache.store(jobId, job.update(job.getJobSnapshot(), supplyChainImpacted, hops)); + bpnInvestigationJobCache.store(jobId, job.update(job.getJobSnapshot(), supplyChainImpacted, minHops)); recursiveNotificationHandler.handleNotification(jobId, supplyChainImpacted); }); @@ -140,7 +141,7 @@ public void handleNotificationCallback(final EdcNotification investigationJobNotificationPredicate( final EdcNotification notification) { - return investigationJob -> investigationJob.getUnansweredNotifications() + return investigationJob -> investigationJob.getUnansweredNotificationIds() .contains(notification.getHeader().getOriginalNotificationId()); } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java index d474bfbe86..74bf236130 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java @@ -257,7 +257,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo try { final String notificationId = sendEdcNotification(bpn, url, investigationJobUpdate.getIncidentBpns(), globalAssetIds); - investigationJobUpdate.withNotifications(Collections.singletonList(notificationId)); + investigationJobUpdate.withUnansweredNotificationIds(Collections.singletonList(notificationId)); } catch (final EdcClientException e) { log.error("Exception during sending EDC notification.", e); investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index 22f61d6365..c316f1f16d 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -51,6 +51,8 @@ import org.eclipse.tractusx.irs.connector.job.MultiTransferJob; import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification; import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotificationHeader; +import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotificationResponse; +import org.eclipse.tractusx.irs.edc.client.model.notification.NotificationContent; import org.eclipse.tractusx.irs.edc.client.model.notification.ResponseNotificationContent; import org.eclipse.tractusx.irs.services.IrsItemGraphQueryService; import org.junit.jupiter.api.Test; @@ -136,7 +138,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob( Jobs.builder().job(Job.builder().id(jobId).owner(owner).build()).build(), - new ArrayList<>()).withNotifications(List.of(notificationId, notificationId2)); + new ArrayList<>()).withUnansweredNotificationIds(List.of(notificationId, notificationId2)); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); assertDoesNotThrow(() -> essService.handleNotificationCallback(edcNotification)); @@ -174,7 +176,7 @@ void shouldKeepJobInRunningIfNotificationIsOpen() { final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob( Jobs.builder().job(Job.builder().id(jobId).owner(owner).build()).build(), - new ArrayList<>()).withNotifications(Collections.singletonList(notificationId)); + new ArrayList<>()).withUnansweredNotificationIds(Collections.singletonList(notificationId)); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); assertThat(bpnInvestigationJobCache.findAll()).hasSize(1); @@ -198,8 +200,19 @@ void shouldCompleteJobIfAllNotificationsSentWereAnswered() { final UUID jobId = UUID.randomUUID(); final Jobs jobSnapshot = job(jobId, owner); + final EdcNotification answeredNotification = EdcNotification.builder() + .header(EdcNotificationHeader.builder() + .notificationId( + notificationId) + .build()) + .content( + ResponseNotificationContent.builder() + .result(SupplyChainImpacted.YES.getDescription()) + .hops(0) + .build()) + .build(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, - null)/*.withAnsweredNotification(notificationId)*/.withNotifications(List.of()); + null).withAnsweredNotification(answeredNotification).withUnansweredNotificationIds(List.of()); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); // Act @@ -220,7 +233,7 @@ void shouldCompleteJobIfFinalNotificationWasReceived() { final Jobs jobSnapshot = job(jobId, owner); final String notificationId = UUID.randomUUID().toString(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, null).update(jobSnapshot, - SupplyChainImpacted.NO, 0).withNotifications(List.of(notificationId)); + SupplyChainImpacted.NO, 0).withUnansweredNotificationIds(List.of(notificationId)); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index c2ec06ab60..e06de63992 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -40,4 +40,8 @@ public class ResponseNotificationContent implements NotificationContent { public void incrementHops() { hops += 1; } + + public boolean thereIsIncident() { + return this.getResult().equalsIgnoreCase("Yes"); + } } diff --git a/pom.xml b/pom.xml index 25f21614d9..289c4a2fa7 100644 --- a/pom.xml +++ b/pom.xml @@ -232,6 +232,7 @@ **/*IrsApiConstants.class **/*ApiErrorsConstants.class org/eclipse/tractusx/irs/testing/dataintegrity/** + org/eclipse/tractusx/irs/edc/client/model/** From 0999bf629cbef232c18d7dcb64c07e17abe8c48a Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Fri, 27 Oct 2023 14:05:03 +0200 Subject: [PATCH 03/54] feat(impl):[TRI-1641] tool fixes --- .../model/notification/ResponseNotificationContent.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index e06de63992..fc0f121599 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -37,11 +37,17 @@ public class ResponseNotificationContent implements NotificationContent { private final String result; private Integer hops; + /** + * Incrementing hops value + */ public void incrementHops() { hops += 1; } + /** + * @return true if the result is Yes + */ public boolean thereIsIncident() { - return this.getResult().equalsIgnoreCase("Yes"); + return "Yes".equalsIgnoreCase(this.getResult()); } } From 470030d7382c669fd2f8c85850affa69d57eee8a Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Fri, 27 Oct 2023 14:39:01 +0200 Subject: [PATCH 04/54] feat(impl):[TRI-1641] fixes&adjustments --- docs/src/api/irs-api.yaml | 7 +++++-- .../model/notification/ResponseNotificationContent.java | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml index 79985c02d4..d9d1bea720 100644 --- a/docs/src/api/irs-api.yaml +++ b/docs/src/api/irs-api.yaml @@ -2520,6 +2520,9 @@ components: type: object additionalProperties: false properties: + hops: + type: integer + format: int32 result: type: string SemanticId: @@ -2562,10 +2565,10 @@ components: items: $ref: '#/components/schemas/Endpoint' maxItems: 2147483647 - idShort: - type: string id: type: string + idShort: + type: string semanticId: $ref: '#/components/schemas/Reference' Summary: diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index fc0f121599..c5de6c002d 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -39,9 +39,12 @@ public class ResponseNotificationContent implements NotificationContent { /** * Incrementing hops value + * + * @return updated object */ - public void incrementHops() { + public ResponseNotificationContent incrementHops() { hops += 1; + return this; } /** From 6345adb5cf0bb614f05b8df43180d7ea2a83ac2c Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Fri, 27 Oct 2023 14:44:10 +0200 Subject: [PATCH 05/54] feat(impl):[TRI-1641] fixes&adjustments --- .../model/notification/ResponseNotificationContent.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index c5de6c002d..95987954b6 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -23,6 +23,8 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.edc.client.model.notification; +import java.util.Locale; + import lombok.Builder; import lombok.Data; import lombok.extern.jackson.Jacksonized; @@ -51,6 +53,6 @@ public ResponseNotificationContent incrementHops() { * @return true if the result is Yes */ public boolean thereIsIncident() { - return "Yes".equalsIgnoreCase(this.getResult()); + return "yes".equalsIgnoreCase(this.getResult().toLowerCase(Locale.ROOT)); } } From 29b4a3b9e911e1cc9fa7562e2e5e9b1285af8193 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Fri, 27 Oct 2023 14:51:51 +0200 Subject: [PATCH 06/54] feat(impl):[TRI-1641] fixes&adjustments --- .../client/model/notification/ResponseNotificationContent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index 95987954b6..abb15a0e2d 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -53,6 +53,6 @@ public ResponseNotificationContent incrementHops() { * @return true if the result is Yes */ public boolean thereIsIncident() { - return "yes".equalsIgnoreCase(this.getResult().toLowerCase(Locale.ROOT)); + return "yes".equals(this.getResult().toLowerCase(Locale.ROOT)); } } From 207fd840967b4458f4876b266fe0e22fbfccf357 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Fri, 27 Oct 2023 14:57:26 +0200 Subject: [PATCH 07/54] feat(impl):[TRI-1641] fixes&adjustments --- .../model/notification/ResponseNotificationContent.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index abb15a0e2d..4e89d0d037 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -23,8 +23,6 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.edc.client.model.notification; -import java.util.Locale; - import lombok.Builder; import lombok.Data; import lombok.extern.jackson.Jacksonized; @@ -53,6 +51,6 @@ public ResponseNotificationContent incrementHops() { * @return true if the result is Yes */ public boolean thereIsIncident() { - return "yes".equals(this.getResult().toLowerCase(Locale.ROOT)); + return "Yes".equals(this.getResult()); } } From 7bb30366c7e97fcbdcfbf16ada816efbdf57fc42 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Mon, 30 Oct 2023 09:58:36 +0100 Subject: [PATCH 08/54] feat(impl):[TRI-1641] fix spotbugs --- .../src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java index 411616f4d8..2a4e1db886 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java @@ -50,6 +50,7 @@ public class JsonUtil { * JSON object mapper implementation. */ private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final class MapTypeReference extends TypeReference> {}; static { final SimpleModule simpleModule = new SimpleModule().addAbstractTypeMapping(TransferProcess.class, @@ -85,7 +86,7 @@ public String asString(final Object input) { * @return the Map representation of the object */ public Map asMap(final Object input) { - return MAPPER.convertValue(input, new TypeReference<>() { }); + return MAPPER.convertValue(input, new MapTypeReference()); } /** From 94f232b87dcab9fac290e430eec47da5142cde6d Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Mon, 30 Oct 2023 10:11:52 +0100 Subject: [PATCH 09/54] feat(impl):[TRI-1641] add changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da82c88ff1..557ae952c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- ESS + - Added 'hops' parameter to Supply Chain Aspect model - contains relative distance in the supply chain ## [4.0.0] - 2023-10-27 ### Added From 3dd9ac305bc9aae554af2f04fb2a8aedfe3eef99 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Mon, 30 Oct 2023 10:21:04 +0100 Subject: [PATCH 10/54] feat(impl):[TRI-1641] fix pmds --- .../service/InvestigationJobProcessingEventListener.java | 2 +- .../main/java/org/eclipse/tractusx/irs/util/JsonUtil.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java index 25e816088b..7f65ea0dd4 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java @@ -259,4 +259,4 @@ private boolean supplyChainIsImpacted(final SupplyChainImpacted supplyChain) { return !SupplyChainImpacted.NO.equals(supplyChain); } -} \ No newline at end of file +} diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java index 2a4e1db886..7f868c96b4 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/util/JsonUtil.java @@ -50,7 +50,11 @@ public class JsonUtil { * JSON object mapper implementation. */ private static final ObjectMapper MAPPER = new ObjectMapper(); - private static final class MapTypeReference extends TypeReference> {}; + + /** + * Map Type Reference helper + */ + private static final class MapTypeReference extends TypeReference> { } static { final SimpleModule simpleModule = new SimpleModule().addAbstractTypeMapping(TransferProcess.class, From 2e1d69f237ddd4cb8d29997d8036d6b713f39ec2 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Mon, 30 Oct 2023 11:11:50 +0100 Subject: [PATCH 11/54] feat(impl):[TRI-1641] refactoring --- .../irs/ess/service/BpnInvestigationJob.java | 96 +++++++++++-------- .../tractusx/irs/ess/service/EssService.java | 11 +-- ...vestigationJobProcessingEventListener.java | 12 +-- .../service/SupplyChainImpactedAspect.java | 2 +- .../irs/ess/service/EssServiceTest.java | 2 +- 5 files changed, 64 insertions(+), 59 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index 964f6be58b..1a5aac1cd9 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -27,6 +27,7 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.Set; @@ -62,41 +63,35 @@ public BpnInvestigationJob(final Jobs jobSnapshot, final List incidentBp this(jobSnapshot, incidentBpns, new ArrayList<>(), new ArrayList<>(), JobState.RUNNING); } - private static Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, - final SupplyChainImpacted supplyChainImpacted, final Integer hops) { - final SupplyChainImpactedAspect supplyChainImpactedAspect = SupplyChainImpactedAspect.builder() - .supplyChainImpacted(supplyChainImpacted) - .impactedSuppliersOnFirstTier(Set.of(new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel("", hops))) - .build(); - final Submodel supplyChainImpactedSubmodel = Submodel.builder() - .aspectType(SUPPLY_CHAIN_ASPECT_TYPE) - .payload(new JsonUtil().asMap(supplyChainImpactedAspect)) - .build(); - - return irsJob.toBuilder() - .clearSubmodels() - .submodels(Collections.singletonList(supplyChainImpactedSubmodel)) - .build(); - } - - private static Jobs updateLastModified(final Jobs irsJob, final ZonedDateTime lastModifiedOn) { - final Job job = irsJob.getJob().toBuilder().completedOn(lastModifiedOn).lastModifiedOn(lastModifiedOn).build(); - return irsJob.toBuilder().job(job).build(); - } - - public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain, - final Integer hops) { + public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain) { final Optional previousSupplyChain = getSupplyChainImpacted(); final SupplyChainImpacted supplyChainImpacted = previousSupplyChain.map( prevSupplyChain -> prevSupplyChain.or(newSupplyChain)).orElse(newSupplyChain); - this.jobSnapshot = extendJobWithSupplyChainSubmodel(jobSnapshot, supplyChainImpacted, hops); + this.jobSnapshot = extendJobWithSupplyChainSubmodel(jobSnapshot, supplyChainImpacted); this.jobSnapshot = extendSummary(this.jobSnapshot); this.jobSnapshot = updateLastModified(this.jobSnapshot, ZonedDateTime.now(ZoneOffset.UTC)); return this; } + public BpnInvestigationJob withUnansweredNotificationIds(final List notifications) { + this.unansweredNotificationIds.addAll(notifications); + return this; + } + + public BpnInvestigationJob withAnsweredNotification(final EdcNotification notification) { + this.unansweredNotificationIds.remove(notification.getHeader().getOriginalNotificationId()); + notification.getContent().incrementHops(); + this.answeredNotifications.add(notification); + return this; + } + + public BpnInvestigationJob complete() { + this.state = JobState.COMPLETED; + return this; + } + /* package */ Optional getSupplyChainImpacted() { return this.getJobSnapshot() .getSubmodels() @@ -108,6 +103,41 @@ public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpac .findFirst(); } + private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyChainImpacted supplyChainImpacted) { + final SupplyChainImpactedAspect.SupplyChainImpactedAspectBuilder supplyChainImpactedAspectBuilder = SupplyChainImpactedAspect.builder() + .supplyChainImpacted( + supplyChainImpacted); + + if (getUnansweredNotificationIds().isEmpty()) { + final Optional incidentWithMinHopsValue = getAnsweredNotifications().stream() + .map(EdcNotification::getContent) + .filter(ResponseNotificationContent::thereIsIncident) + .min(Comparator.comparing( + ResponseNotificationContent::getHops)); + + final List suppliersFirstLevel = incidentWithMinHopsValue.map( + min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel("", min.getHops())) + .stream() + .toList(); + supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); + } + + final Submodel supplyChainImpactedSubmodel = Submodel.builder() + .aspectType(SUPPLY_CHAIN_ASPECT_TYPE) + .payload(new JsonUtil().asMap(supplyChainImpactedAspectBuilder.build())) + .build(); + + return irsJob.toBuilder() + .clearSubmodels() + .submodels(Collections.singletonList(supplyChainImpactedSubmodel)) + .build(); + } + + private Jobs updateLastModified(final Jobs irsJob, final ZonedDateTime lastModifiedOn) { + final Job job = irsJob.getJob().toBuilder().completedOn(lastModifiedOn).lastModifiedOn(lastModifiedOn).build(); + return irsJob.toBuilder().job(job).build(); + } + private Jobs extendSummary(final Jobs irsJob) { final Summary oldSummary = Optional.ofNullable(irsJob.getJob().getSummary()).orElse(Summary.builder().build()); final NotificationSummary newSummary = new NotificationSummary(oldSummary.getAsyncFetchedItems(), @@ -118,20 +148,4 @@ private Jobs extendSummary(final Jobs irsJob) { return irsJob.toBuilder().job(job).build(); } - public BpnInvestigationJob withUnansweredNotificationIds(final List notifications) { - this.unansweredNotificationIds.addAll(notifications); - return this; - } - - public BpnInvestigationJob withAnsweredNotification(final EdcNotification notification) { - this.unansweredNotificationIds.remove(notification.getHeader().getOriginalNotificationId()); - notification.getContent().incrementHops(); - this.answeredNotifications.add(notification); - return this; - } - - public BpnInvestigationJob complete() { - this.state = JobState.COMPLETED; - return this; - } } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 1c0dc348af..3fd4f8e6ca 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -23,7 +23,6 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.ess.service; -import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -125,15 +124,7 @@ public void handleNotificationCallback(final EdcNotification minHopsWithIncident = job.getAnsweredNotifications() - .stream() - .map(EdcNotification::getContent) - .filter(ResponseNotificationContent::thereIsIncident) - .min(Comparator.comparing( - ResponseNotificationContent::getHops)); - final Integer minHops = minHopsWithIncident.map(ResponseNotificationContent::getHops).orElse(0); - - bpnInvestigationJobCache.store(jobId, job.update(job.getJobSnapshot(), supplyChainImpacted, minHops)); + bpnInvestigationJobCache.store(jobId, job.update(job.getJobSnapshot(), supplyChainImpacted)); recursiveNotificationHandler.handleNotification(jobId, supplyChainImpacted); }); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java index 7f65ea0dd4..8f7ebd1c94 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java @@ -110,7 +110,7 @@ public void handleJobProcessingFinishedEvent(final JobProcessingFinishedEvent jo completedJobId); final BpnInvestigationJob investigationJobUpdate = investigationJob.update( - investigationResult.completedJob(), investigationResult.supplyChainImpacted(), 0); + investigationResult.completedJob(), investigationResult.supplyChainImpacted()); if (leafNodeIsReached(investigationResult.completedJob()) || supplyChainIsImpacted( investigationResult.supplyChainImpacted())) { @@ -153,7 +153,7 @@ private void triggerInvestigationOnNextLevel(final Jobs completedJob, log.debug("Triggering investigation on the next level."); if (anyBpnIsMissingFromRelationship(completedJob)) { log.error("One or more Relationship items did not contain a BPN."); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); } // Map> final Map> bpns = getBPNsFromRelationships(completedJob.getRelationships()); @@ -170,12 +170,12 @@ private void triggerInvestigationOnNextLevel(final Jobs completedJob, log.debug("BPNs '{}' could not be resolved to an EDC address using DiscoveryService.", unresolvedBPNs); log.info("Some EDC addresses could not be resolved with DiscoveryService. " + "Updating SupplyChainImpacted to {}", SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); recursiveNotificationHandler.handleNotification(investigationJobUpdate.getJobSnapshot().getJob().getId(), SupplyChainImpacted.UNKNOWN); } else if (resolvedBPNs.isEmpty()) { log.info("No BPNs could not be found. Updating SupplyChainImpacted to {}", SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); recursiveNotificationHandler.handleNotification(investigationJobUpdate.getJobSnapshot().getJob().getId(), SupplyChainImpacted.UNKNOWN); } else { @@ -191,7 +191,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo if (edcBaseUrl.isEmpty()) { log.warn("No EDC URL found for BPN '{}'. Setting investigation result to '{}'", bpn, SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); } edcBaseUrl.forEach(url -> { try { @@ -200,7 +200,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo investigationJobUpdate.withUnansweredNotificationIds(Collections.singletonList(notificationId)); } catch (final EdcClientException e) { log.error("Exception during sending EDC notification.", e); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, 0); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); } }); }); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java index 8457b34a02..daa070715a 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java @@ -46,6 +46,6 @@ public class SupplyChainImpactedAspect { */ @Builder(toBuilder = true) @Jacksonized - record ImpactedSupplierFirstLevel(String bpnl, Integer hops) { + public record ImpactedSupplierFirstLevel(String bpnl, Integer hops) { } } diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index c316f1f16d..f971db3cef 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -233,7 +233,7 @@ void shouldCompleteJobIfFinalNotificationWasReceived() { final Jobs jobSnapshot = job(jobId, owner); final String notificationId = UUID.randomUUID().toString(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, null).update(jobSnapshot, - SupplyChainImpacted.NO, 0).withUnansweredNotificationIds(List.of(notificationId)); + SupplyChainImpacted.NO).withUnansweredNotificationIds(List.of(notificationId)); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() From a9416043438445ed425dcaf428ee4cf5dbbfe4a6 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Mon, 30 Oct 2023 16:25:19 +0100 Subject: [PATCH 12/54] feat(impl):[TRI-1641] adjustments and test --- .../irs/ess/service/SupplyChainImpacted.java | 4 ++- .../service/SupplyChainImpactedAspect.java | 25 ++++++++++++------- .../irs/ess/service/EssServiceTest.java | 25 +++++++++++-------- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpacted.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpacted.java index 9b617cfe4d..7ad28b8369 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpacted.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpacted.java @@ -25,6 +25,7 @@ import java.util.Locale; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; import lombok.Getter; @@ -44,7 +45,8 @@ public enum SupplyChainImpacted { this.description = description; } - static SupplyChainImpacted fromString(final String name) { + @JsonCreator + public static SupplyChainImpacted fromString(final String name) { return SupplyChainImpacted.valueOf(name.toUpperCase(Locale.ROOT)); } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java index daa070715a..3f20e186cb 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java @@ -25,27 +25,34 @@ import java.util.Set; +import lombok.AllArgsConstructor; import lombok.Builder; -import lombok.Value; +import lombok.Data; +import lombok.NoArgsConstructor; import lombok.extern.jackson.Jacksonized; /** * Supply Chain Impacted aspect representation */ -@Value -@Builder(toBuilder = true) +@Data @Jacksonized +@AllArgsConstructor +@NoArgsConstructor +@Builder public class SupplyChainImpactedAspect { - private final SupplyChainImpacted supplyChainImpacted; - private final Set impactedSuppliersOnFirstTier; + private SupplyChainImpacted supplyChainImpacted; + private Set impactedSuppliersOnFirstTier; /** * BPNLs on first tier level where infection was detected - * @param bpnl - * @param hops */ - @Builder(toBuilder = true) + @Data @Jacksonized - public record ImpactedSupplierFirstLevel(String bpnl, Integer hops) { + @AllArgsConstructor + @NoArgsConstructor + @Builder + public static class ImpactedSupplierFirstLevel { + private String bpnl; + private Integer hops; } } diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index f971db3cef..de3f6f90af 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -34,6 +34,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -55,9 +56,11 @@ import org.eclipse.tractusx.irs.edc.client.model.notification.NotificationContent; import org.eclipse.tractusx.irs.edc.client.model.notification.ResponseNotificationContent; import org.eclipse.tractusx.irs.services.IrsItemGraphQueryService; +import org.eclipse.tractusx.irs.util.JsonUtil; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.web.server.ResponseStatusException; +import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; class EssServiceTest { @@ -146,25 +149,25 @@ void shouldUpdateJobSnapshotIfNotificationFound() { final BpnInvestigationJob job = bpnInvestigationJobCache.findAll().get(0); final String supplyChainImpacted = (String) job.getJobSnapshot() - .getSubmodels() - .get(0) - .getPayload() - .get("supplyChainImpacted"); + .getSubmodels() + .get(0) + .getPayload() + .get("supplyChainImpacted"); assertThat(supplyChainImpacted).isEqualTo("No"); assertThat(job.getState()).isEqualTo(JobState.RUNNING); assertDoesNotThrow(() -> essService.handleNotificationCallback(edcNotification2)); assertThat(bpnInvestigationJobCache.findAll()).hasSize(1); + final BpnInvestigationJob job2 = bpnInvestigationJobCache.findAll().get(0); assertThat(job2.getJobSnapshot().getSubmodels()).hasSize(1); - final String supplyChainImpacted2 = (String) job.getJobSnapshot() - .getSubmodels() - .get(0) - .getPayload() - .get("supplyChainImpacted"); - assertThat(supplyChainImpacted2).isEqualTo("Yes"); - assertThat(job.getState()).isEqualTo(JobState.COMPLETED); + final Map supplyChainPayload = job2.getJobSnapshot().getSubmodels().get(0).getPayload(); + final SupplyChainImpactedAspect supplyChainImpactedAspect = new ObjectMapper().convertValue(supplyChainPayload, SupplyChainImpactedAspect.class); + assertThat(supplyChainImpactedAspect.getSupplyChainImpacted()).isEqualTo(SupplyChainImpacted.YES); + assertThat(supplyChainImpactedAspect.getImpactedSuppliersOnFirstTier()).isNotEmpty(); + assertThat(supplyChainImpactedAspect.getImpactedSuppliersOnFirstTier().stream().findAny().get().getHops()).isPositive(); + assertThat(job.getState()).isEqualTo(JobState.COMPLETED); } @Test From 16c051958b156e01def6065a2f40feedde02ac2a Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Tue, 31 Oct 2023 10:25:04 +0100 Subject: [PATCH 13/54] feat(impl):[TRI-1641] adjustments review comments --- CHANGELOG.md | 2 +- .../model/notification/ResponseNotificationContent.java | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 557ae952c4..73755a8b53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed - ESS - - Added 'hops' parameter to Supply Chain Aspect model - contains relative distance in the supply chain + - Added 'hops' parameter to SupplyChainImpacted Aspect model - contains relative distance in the supply chain ## [4.0.0] - 2023-10-27 ### Added diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index 4e89d0d037..819fd9c456 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -34,6 +34,9 @@ @Builder @Jacksonized public class ResponseNotificationContent implements NotificationContent { + + private static final String INFECTED_SUPPLY_CHAIN_RESULT = "Yes"; + private final String result; private Integer hops; @@ -43,7 +46,7 @@ public class ResponseNotificationContent implements NotificationContent { * @return updated object */ public ResponseNotificationContent incrementHops() { - hops += 1; + this.hops += 1; return this; } @@ -51,6 +54,6 @@ public ResponseNotificationContent incrementHops() { * @return true if the result is Yes */ public boolean thereIsIncident() { - return "Yes".equals(this.getResult()); + return INFECTED_SUPPLY_CHAIN_RESULT.equals(this.getResult()); } } From 6b2cebe651aa680702d2f28a8d90303565fdaa2b Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 2 Nov 2023 16:22:46 +0100 Subject: [PATCH 14/54] feat(impl):[TRI-1641] send hop in notification --- .../ess/service/EdcNotificationSender.java | 3 ++- .../EssRecursiveNotificationHandler.java | 19 +++++++++++++++++-- .../irs/ess/service/EssRecursiveService.java | 4 +++- .../tractusx/irs/ess/service/EssService.java | 1 - .../service/EdcNotificationSenderTest.java | 2 +- .../EssRecursiveNotificationHandlerTest.java | 6 ++++-- .../ess/service/EssRecursiveServiceTest.java | 3 ++- 7 files changed, 29 insertions(+), 9 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java index 43e133584f..41bba21bef 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java @@ -60,7 +60,7 @@ public EdcNotificationSender(final EdcSubmodelFacade edcSubmodelFacade, } public void sendEdcNotification(final EdcNotification originalEdcNotification, - final SupplyChainImpacted supplyChainImpacted) { + final SupplyChainImpacted supplyChainImpacted, final Integer hops) { final String notificationId = UUID.randomUUID().toString(); final String originalNotificationId = originalEdcNotification.getHeader().getNotificationId(); final String recipientBpn = originalEdcNotification.getHeader().getSenderBpn(); @@ -69,6 +69,7 @@ public void sendEdcNotification(final EdcNotification responseNotification = edcRequest(notificationId, originalNotificationId, essLocalEdcEndpoint, localBpn, recipientBpn, notificationContent); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java index 49f5381a32..937846c53c 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java @@ -23,12 +23,15 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.ess.service; +import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification; +import org.eclipse.tractusx.irs.edc.client.model.notification.ResponseNotificationContent; import org.springframework.stereotype.Service; /** @@ -39,6 +42,8 @@ @Slf4j public class EssRecursiveNotificationHandler { + private static final Integer FIRST_HOP = 0; + private final RelatedInvestigationJobsCache relatedInvestigationJobsCache; private final BpnInvestigationJobCache bpnInvestigationJobCache; private final EdcNotificationSender edcNotificationSender; @@ -51,7 +56,7 @@ public class EssRecursiveNotificationHandler { relatedJobsId.ifPresentOrElse(relatedJobs -> { if (SupplyChainImpacted.YES.equals(supplyChainImpacted)) { log.debug("SupplyChain is impacted. Sending notification back to requestor."); - edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted); + edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, FIRST_HOP); relatedInvestigationJobsCache.remove( relatedJobs.originalNotification().getHeader().getNotificationId()); } else { @@ -75,9 +80,19 @@ private void sendNotificationAfterAllCompleted(final RelatedInvestigationJobs re .flatMap(Optional::stream) .reduce(SupplyChainImpacted.NO, SupplyChainImpacted::or); - edcNotificationSender.sendEdcNotification(relatedInvestigationJobs.originalNotification(), finalResult); + edcNotificationSender.sendEdcNotification(relatedInvestigationJobs.originalNotification(), finalResult, getMinHops(allInvestigationJobs)); } + } + private Integer getMinHops(final List allInvestigationJobs) { + return allInvestigationJobs + .stream() + .flatMap(investigationJobs -> investigationJobs.getAnsweredNotifications().stream()) + .map(EdcNotification::getContent) + .filter(ResponseNotificationContent::thereIsIncident) + .min(Comparator.comparing(ResponseNotificationContent::getHops)) + .map(ResponseNotificationContent::getHops) + .orElse(FIRST_HOP); } private boolean checkAllFinished(final List allInvestigationJobs) { diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveService.java index edc001412b..1f3cb4dfeb 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveService.java @@ -43,6 +43,8 @@ @Slf4j public class EssRecursiveService { + private static final Integer FIRST_HOP = 0; + private final EssService essService; private final RelatedInvestigationJobsCache relatedInvestigationJobsCache; private final String localBpn; @@ -65,7 +67,7 @@ public void handleNotification(final EdcNotification bpns = incidentBPNSs.get(); final List concernedCatenaXIds = concernedCatenaXIdsNotification.get(); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 3fd4f8e6ca..8ef2054691 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -126,7 +126,6 @@ public void handleNotificationCallback(final EdcNotification uuids) { diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveServiceTest.java index 7519fd3877..52a90ea41e 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveServiceTest.java @@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -66,7 +67,7 @@ void shouldResponseWithoutRecursiveWhenLocalBpnIsPartOfIncident() { EdcNotification edcNotification = EdcNotification.builder() .content(notificationContent) .build(); - Mockito.doNothing().when(edcNotificationSender).sendEdcNotification(any(), supplyChainCaptor.capture()); + Mockito.doNothing().when(edcNotificationSender).sendEdcNotification(any(), supplyChainCaptor.capture(), eq(0)); // when essRecursiveService.handleNotification(edcNotification); From 4e71336949c5636b4e97cb52a23668149ce234cd Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 2 Nov 2023 16:31:36 +0100 Subject: [PATCH 15/54] feat(impl):[TRI-1641] fix DEP file --- DEPENDENCIES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index 9cf69e6a42..80cb5990bd 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -170,7 +170,7 @@ maven/mavencentral/io.rest-assured/xml-path/5.3.0, Apache-2.0, approved, #9267 maven/mavencentral/io.rest-assured/xml-path/5.3.2, Apache-2.0, approved, #9267 maven/mavencentral/io.suzaku/boopickle_2.13/1.3.3, Apache-2.0, approved, clearlydefined maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.15, Apache-2.0, approved, #5947 -maven/mavencentral/io.swagger.core.v3/swagger-annotations/2.2.16, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.swagger.core.v3/swagger-annotations/2.2.16, Apache-2.0, approved, #11362 maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.15, Apache-2.0, approved, #5929 maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.15, Apache-2.0, approved, #5919 maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.2, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf From a48f914310e010ea056c0a1d11912bf12d5b8997 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Fri, 3 Nov 2023 15:36:18 +0100 Subject: [PATCH 16/54] feat(impl):[TRI-1658] added bpn number of the first level chain --- docs/src/api/irs-api.yaml | 2 ++ .../irs/ess/service/BpnInvestigationJob.java | 9 ++++---- .../ess/service/EdcNotificationSender.java | 3 ++- .../EssRecursiveNotificationHandler.java | 12 ++++++---- .../irs/ess/service/EssRecursiveService.java | 2 +- .../tractusx/irs/ess/service/EssService.java | 4 ++-- ...vestigationJobProcessingEventListener.java | 23 +++++++++---------- .../service/EdcNotificationSenderTest.java | 2 +- .../EssRecursiveNotificationHandlerTest.java | 11 +++++---- .../ess/service/EssRecursiveServiceTest.java | 2 +- .../irs/ess/service/EssServiceTest.java | 6 ++--- ...igationJobProcessingEventListenerTest.java | 6 +++-- .../ResponseNotificationContent.java | 1 + 13 files changed, 46 insertions(+), 37 deletions(-) diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml index 263419a97e..dce6586307 100644 --- a/docs/src/api/irs-api.yaml +++ b/docs/src/api/irs-api.yaml @@ -2524,6 +2524,8 @@ components: hops: type: integer format: int32 + bpn: + type: string result: type: string SemanticId: diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index 1a5aac1cd9..b4f941d6e5 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -63,13 +63,13 @@ public BpnInvestigationJob(final Jobs jobSnapshot, final List incidentBp this(jobSnapshot, incidentBpns, new ArrayList<>(), new ArrayList<>(), JobState.RUNNING); } - public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain) { + public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain, final String bpn) { final Optional previousSupplyChain = getSupplyChainImpacted(); final SupplyChainImpacted supplyChainImpacted = previousSupplyChain.map( prevSupplyChain -> prevSupplyChain.or(newSupplyChain)).orElse(newSupplyChain); - this.jobSnapshot = extendJobWithSupplyChainSubmodel(jobSnapshot, supplyChainImpacted); + this.jobSnapshot = extendJobWithSupplyChainSubmodel(jobSnapshot, supplyChainImpacted, bpn); this.jobSnapshot = extendSummary(this.jobSnapshot); this.jobSnapshot = updateLastModified(this.jobSnapshot, ZonedDateTime.now(ZoneOffset.UTC)); return this; @@ -103,7 +103,8 @@ public BpnInvestigationJob complete() { .findFirst(); } - private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyChainImpacted supplyChainImpacted) { + private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyChainImpacted supplyChainImpacted, + final String bpn) { final SupplyChainImpactedAspect.SupplyChainImpactedAspectBuilder supplyChainImpactedAspectBuilder = SupplyChainImpactedAspect.builder() .supplyChainImpacted( supplyChainImpacted); @@ -116,7 +117,7 @@ private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyCha ResponseNotificationContent::getHops)); final List suppliersFirstLevel = incidentWithMinHopsValue.map( - min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel("", min.getHops())) + min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) .stream() .toList(); supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java index 41bba21bef..78373abcbb 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java @@ -60,7 +60,7 @@ public EdcNotificationSender(final EdcSubmodelFacade edcSubmodelFacade, } public void sendEdcNotification(final EdcNotification originalEdcNotification, - final SupplyChainImpacted supplyChainImpacted, final Integer hops) { + final SupplyChainImpacted supplyChainImpacted, final Integer hops, final String bpn) { final String notificationId = UUID.randomUUID().toString(); final String originalNotificationId = originalEdcNotification.getHeader().getNotificationId(); final String recipientBpn = originalEdcNotification.getHeader().getSenderBpn(); @@ -70,6 +70,7 @@ public void sendEdcNotification(final EdcNotification responseNotification = edcRequest(notificationId, originalNotificationId, essLocalEdcEndpoint, localBpn, recipientBpn, notificationContent); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java index 937846c53c..8b4cce1d6e 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java @@ -48,7 +48,7 @@ public class EssRecursiveNotificationHandler { private final BpnInvestigationJobCache bpnInvestigationJobCache; private final EdcNotificationSender edcNotificationSender; - /* package */ void handleNotification(final UUID finishedJobId, final SupplyChainImpacted supplyChainImpacted) { + /* package */ void handleNotification(final UUID finishedJobId, final SupplyChainImpacted supplyChainImpacted, final String bpn) { final Optional relatedJobsId = relatedInvestigationJobsCache.findByRecursiveRelatedJobId( finishedJobId); @@ -56,19 +56,20 @@ public class EssRecursiveNotificationHandler { relatedJobsId.ifPresentOrElse(relatedJobs -> { if (SupplyChainImpacted.YES.equals(supplyChainImpacted)) { log.debug("SupplyChain is impacted. Sending notification back to requestor."); - edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, FIRST_HOP); + edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, FIRST_HOP, bpn); relatedInvestigationJobsCache.remove( relatedJobs.originalNotification().getHeader().getNotificationId()); } else { log.debug( "SupplyChainImpacted in state '{}'. Waiting for Jobs to complete to send notification back to requestor.", supplyChainImpacted); - sendNotificationAfterAllCompleted(relatedJobs); + sendNotificationAfterAllCompleted(relatedJobs, bpn); } }, () -> log.debug("No RelatedInvestigationJob found for id '{}'.", finishedJobId)); } - private void sendNotificationAfterAllCompleted(final RelatedInvestigationJobs relatedInvestigationJobs) { + private void sendNotificationAfterAllCompleted(final RelatedInvestigationJobs relatedInvestigationJobs, + final String bpn) { final List allInvestigationJobs = relatedInvestigationJobs.recursiveRelatedJobIds() .stream() .map(bpnInvestigationJobCache::findByJobId) @@ -80,7 +81,8 @@ private void sendNotificationAfterAllCompleted(final RelatedInvestigationJobs re .flatMap(Optional::stream) .reduce(SupplyChainImpacted.NO, SupplyChainImpacted::or); - edcNotificationSender.sendEdcNotification(relatedInvestigationJobs.originalNotification(), finalResult, getMinHops(allInvestigationJobs)); + + edcNotificationSender.sendEdcNotification(relatedInvestigationJobs.originalNotification(), finalResult, getMinHops(allInvestigationJobs), bpn); } } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveService.java index 1f3cb4dfeb..f2ff334fc8 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveService.java @@ -67,7 +67,7 @@ public void handleNotification(final EdcNotification bpns = incidentBPNSs.get(); final List concernedCatenaXIds = concernedCatenaXIdsNotification.get(); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 8ef2054691..8aeedb8a84 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -124,8 +124,8 @@ public void handleNotificationCallback(final EdcNotification> final Map> bpns = getBPNsFromRelationships(completedJob.getRelationships()); log.debug("Extracted BPNs '{}'", bpns); @@ -170,14 +169,14 @@ private void triggerInvestigationOnNextLevel(final Jobs completedJob, log.debug("BPNs '{}' could not be resolved to an EDC address using DiscoveryService.", unresolvedBPNs); log.info("Some EDC addresses could not be resolved with DiscoveryService. " + "Updating SupplyChainImpacted to {}", SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, jobBpn); recursiveNotificationHandler.handleNotification(investigationJobUpdate.getJobSnapshot().getJob().getId(), - SupplyChainImpacted.UNKNOWN); + SupplyChainImpacted.UNKNOWN, jobBpn); } else if (resolvedBPNs.isEmpty()) { log.info("No BPNs could not be found. Updating SupplyChainImpacted to {}", SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, jobBpn); recursiveNotificationHandler.handleNotification(investigationJobUpdate.getJobSnapshot().getJob().getId(), - SupplyChainImpacted.UNKNOWN); + SupplyChainImpacted.UNKNOWN, jobBpn); } else { log.debug("Sending notification for BPNs '{}'", bpns); sendNotifications(completedJob, investigationJobUpdate, bpns); @@ -191,7 +190,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo if (edcBaseUrl.isEmpty()) { log.warn("No EDC URL found for BPN '{}'. Setting investigation result to '{}'", bpn, SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, bpn); } edcBaseUrl.forEach(url -> { try { @@ -200,7 +199,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo investigationJobUpdate.withUnansweredNotificationIds(Collections.singletonList(notificationId)); } catch (final EdcClientException e) { log.error("Exception during sending EDC notification.", e); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, bpn); } }); }); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSenderTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSenderTest.java index b786ab6176..ecf1b0a8a6 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSenderTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSenderTest.java @@ -69,7 +69,7 @@ void shouldSendEdcNotificationWithSuccess() throws EdcClientException { when(connectorEndpointsService.fetchConnectorEndpoints("senderBpn")).thenReturn(List.of("senderEdc")); // when - sender.sendEdcNotification(edcNotification, SupplyChainImpacted.NO, 1); + sender.sendEdcNotification(edcNotification, SupplyChainImpacted.NO, 1, "senderBpn"); // then final ResponseNotificationContent content = (ResponseNotificationContent) notificationCaptor.getValue() diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandlerTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandlerTest.java index 5bcf223505..0c3a543004 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandlerTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandlerTest.java @@ -57,7 +57,7 @@ class EssRecursiveNotificationHandlerTest { @Test void shouldDoNothingWhenThereIsNoInvestigationJob() { // when - cut.handleNotification(UUID.randomUUID(), SupplyChainImpacted.UNKNOWN); + cut.handleNotification(UUID.randomUUID(), SupplyChainImpacted.UNKNOWN, ""); // then verifyNoInteractions(edcNotificationSender); @@ -70,10 +70,10 @@ void shouldReplyWhenJobIsPresentAndSupplyChainIsImpacted() { relatedInvestigationJobsCache.store("notification-id", createRelatedJobsWith(List.of(jobId))); // when - cut.handleNotification(jobId, SupplyChainImpacted.YES); + cut.handleNotification(jobId, SupplyChainImpacted.YES, "bpn"); // then - verify(edcNotificationSender).sendEdcNotification(any(), eq(SupplyChainImpacted.YES), eq(hops)); + verify(edcNotificationSender).sendEdcNotification(any(), eq(SupplyChainImpacted.YES), eq(hops), eq("bpn")); } @Test @@ -81,6 +81,7 @@ void shouldReplyOnlyWhenAllJobsAreCompleted() { // given final UUID anotherJobId = UUID.randomUUID(); final int hops = 0; + final String bpn = "bpn"; relatedInvestigationJobsCache.store("notification-id", createRelatedJobsWith(List.of(jobId, anotherJobId))); bpnInvestigationJobCache.store(jobId, currentBpnInvestigationJob); bpnInvestigationJobCache.store(anotherJobId, pastBpnInvestigationJob); @@ -89,10 +90,10 @@ void shouldReplyOnlyWhenAllJobsAreCompleted() { when(pastBpnInvestigationJob.getSupplyChainImpacted()).thenReturn(Optional.of(SupplyChainImpacted.NO)); // when - cut.handleNotification(jobId, SupplyChainImpacted.NO); + cut.handleNotification(jobId, SupplyChainImpacted.NO, bpn); // then - verify(edcNotificationSender, times(1)).sendEdcNotification(any(), eq(SupplyChainImpacted.NO), eq(hops)); + verify(edcNotificationSender, times(1)).sendEdcNotification(any(), eq(SupplyChainImpacted.NO), eq(hops), eq(bpn)); } private RelatedInvestigationJobs createRelatedJobsWith(List uuids) { diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveServiceTest.java index 52a90ea41e..1006bc0064 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveServiceTest.java @@ -67,7 +67,7 @@ void shouldResponseWithoutRecursiveWhenLocalBpnIsPartOfIncident() { EdcNotification edcNotification = EdcNotification.builder() .content(notificationContent) .build(); - Mockito.doNothing().when(edcNotificationSender).sendEdcNotification(any(), supplyChainCaptor.capture(), eq(0)); + Mockito.doNothing().when(edcNotificationSender).sendEdcNotification(any(), supplyChainCaptor.capture(), eq(0), eq(localBpn)); // when essRecursiveService.handleNotification(edcNotification); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index de3f6f90af..afc468b906 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -120,7 +120,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { final UUID jobId = UUID.randomUUID(); final String owner = securityHelperService.getClientIdClaim(); - final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).build(); + final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).bpn("bot-impacted-bpn").build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() .notificationId(notificationId) .originalNotificationId(notificationId) @@ -129,7 +129,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { .header(header1) .content(resultNo) .build(); - final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").hops(0).build(); + final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").hops(0).bpn("impacted-bpn").build(); final EdcNotificationHeader header2 = EdcNotificationHeader.builder() .notificationId(notificationId2) .originalNotificationId(notificationId2) @@ -236,7 +236,7 @@ void shouldCompleteJobIfFinalNotificationWasReceived() { final Jobs jobSnapshot = job(jobId, owner); final String notificationId = UUID.randomUUID().toString(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, null).update(jobSnapshot, - SupplyChainImpacted.NO).withUnansweredNotificationIds(List.of(notificationId)); + SupplyChainImpacted.NO, "bpn").withUnansweredNotificationIds(List.of(notificationId)); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListenerTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListenerTest.java index 19a69f428e..39e3f39585 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListenerTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListenerTest.java @@ -42,6 +42,7 @@ import org.eclipse.tractusx.irs.common.JobProcessingFinishedEvent; import org.eclipse.tractusx.irs.component.GlobalAssetIdentification; import org.eclipse.tractusx.irs.component.Job; +import org.eclipse.tractusx.irs.component.JobParameter; import org.eclipse.tractusx.irs.component.Jobs; import org.eclipse.tractusx.irs.component.LinkedItem; import org.eclipse.tractusx.irs.component.Relationship; @@ -148,7 +149,7 @@ void shouldStopProcessingIfNoRelationshipContainsBPN() throws EdcClientException jobProcessingEventListener.handleJobProcessingFinishedEvent(jobProcessingFinishedEvent); // then - verify(this.recursiveNotificationHandler, times(1)).handleNotification(any(), eq(SupplyChainImpacted.UNKNOWN)); + verify(this.recursiveNotificationHandler, times(1)).handleNotification(any(), eq(SupplyChainImpacted.UNKNOWN), eq("bpn")); } @Test @@ -225,7 +226,7 @@ void shouldSendCallbackIfNoMoreRelationshipsAreFound() throws EdcClientException // then verify(this.edcSubmodelFacade, times(0)).sendNotification(anyString(), anyString(), any(EdcNotification.class)); - verify(this.recursiveNotificationHandler, times(1)).handleNotification(any(), eq(SupplyChainImpacted.NO)); + verify(this.recursiveNotificationHandler, times(1)).handleNotification(any(), eq(SupplyChainImpacted.NO), eq("bpn")); } @Test @@ -371,6 +372,7 @@ private void createMockJob(final UUID mockedJobId, final List rela .job(Job.builder() .id(mockedJobId) .globalAssetId(GlobalAssetIdentification.of("dummyGlobalAssetId")) + .parameter(JobParameter.builder().bpn("bpn").build()) .build()) .relationships(relationships) .shells(shells) diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index 819fd9c456..9a5d3c7aa3 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -39,6 +39,7 @@ public class ResponseNotificationContent implements NotificationContent { private final String result; private Integer hops; + private final String bpn; /** * Incrementing hops value From e4d7ac56db87d4cd7d130712268b0d38320842ef Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Mon, 6 Nov 2023 13:03:08 +0100 Subject: [PATCH 17/54] feat(impl):[TRI-1658] changed bpn in notification callback to sender bpn --- .../java/org/eclipse/tractusx/irs/ess/service/EssService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 8aeedb8a84..ce4bc6fd27 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -124,7 +124,7 @@ public void handleNotificationCallback(final EdcNotification Date: Mon, 6 Nov 2023 14:25:05 +0100 Subject: [PATCH 18/54] feat(impl):[TRI-1658] extended unanswered notification to contain bpn number --- docs/src/api/irs-api.yaml | 2 +- .../irs/ess/service/BpnInvestigationJob.java | 27 ++++++++++++------- .../ess/service/EdcNotificationSender.java | 2 +- .../tractusx/irs/ess/service/EssService.java | 25 ++++++++++------- ...vestigationJobProcessingEventListener.java | 3 ++- .../irs/ess/service/EssServiceTest.java | 16 +++++------ .../ResponseNotificationContent.java | 2 +- .../tractusx/irs/component/Notification.java | 27 +++++++++++++++++++ 8 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml index dce6586307..984d1be77b 100644 --- a/docs/src/api/irs-api.yaml +++ b/docs/src/api/irs-api.yaml @@ -2524,7 +2524,7 @@ components: hops: type: integer format: int32 - bpn: + parentBpn: type: string result: type: string diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index b4f941d6e5..65b55eef74 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -37,6 +37,7 @@ import lombok.Getter; import org.eclipse.tractusx.irs.component.Job; import org.eclipse.tractusx.irs.component.Jobs; +import org.eclipse.tractusx.irs.component.Notification; import org.eclipse.tractusx.irs.component.Submodel; import org.eclipse.tractusx.irs.component.Summary; import org.eclipse.tractusx.irs.component.enums.JobState; @@ -55,7 +56,7 @@ public class BpnInvestigationJob { private Jobs jobSnapshot; private List incidentBpns; - private List unansweredNotificationIds; + private List unansweredNotifications; private List> answeredNotifications; private JobState state; @@ -75,16 +76,24 @@ public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpac return this; } - public BpnInvestigationJob withUnansweredNotificationIds(final List notifications) { - this.unansweredNotificationIds.addAll(notifications); + public BpnInvestigationJob withUnansweredNotifications(final List notifications) { + this.unansweredNotifications.addAll(notifications); return this; } public BpnInvestigationJob withAnsweredNotification(final EdcNotification notification) { - this.unansweredNotificationIds.remove(notification.getHeader().getOriginalNotificationId()); - notification.getContent().incrementHops(); - this.answeredNotifications.add(notification); - return this; + this.unansweredNotifications.removeIf(unansweredNotification -> unansweredNotification.notificationId().equals(notification.getHeader().getOriginalNotificationId())); + final Optional parentBpn = this.unansweredNotifications.stream() + .filter(unansweredNotification -> unansweredNotification.notificationId() + .equals(notification.getHeader() + .getOriginalNotificationId())) + .map(Notification::bpn) + .findAny(); + + notification.getContent().setParentBpn(parentBpn.orElse(null)); + notification.getContent().incrementHops(); + this.answeredNotifications.add(notification); + return this; } public BpnInvestigationJob complete() { @@ -109,7 +118,7 @@ private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyCha .supplyChainImpacted( supplyChainImpacted); - if (getUnansweredNotificationIds().isEmpty()) { + if (getUnansweredNotifications().isEmpty()) { final Optional incidentWithMinHopsValue = getAnsweredNotifications().stream() .map(EdcNotification::getContent) .filter(ResponseNotificationContent::thereIsIncident) @@ -143,7 +152,7 @@ private Jobs extendSummary(final Jobs irsJob) { final Summary oldSummary = Optional.ofNullable(irsJob.getJob().getSummary()).orElse(Summary.builder().build()); final NotificationSummary newSummary = new NotificationSummary(oldSummary.getAsyncFetchedItems(), oldSummary.getBpnLookups(), - new NotificationItems(unansweredNotificationIds.size() + answeredNotifications.size(), + new NotificationItems(unansweredNotifications.size() + answeredNotifications.size(), answeredNotifications.size())); final Job job = irsJob.getJob().toBuilder().summary(newSummary).build(); return irsJob.toBuilder().job(job).build(); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java index 78373abcbb..3195b71d20 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java @@ -70,7 +70,7 @@ public void sendEdcNotification(final EdcNotification responseNotification = edcRequest(notificationId, originalNotificationId, essLocalEdcEndpoint, localBpn, recipientBpn, notificationContent); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index ce4bc6fd27..934c16efc0 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -33,6 +33,7 @@ import org.eclipse.tractusx.irs.common.auth.SecurityHelperService; import org.eclipse.tractusx.irs.component.JobHandle; import org.eclipse.tractusx.irs.component.Jobs; +import org.eclipse.tractusx.irs.component.Notification; import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.RegisterBpnInvestigationJob; import org.eclipse.tractusx.irs.component.RegisterJob; @@ -67,7 +68,8 @@ public JobHandle startIrsJob(final RegisterBpnInvestigationJob request) { } public JobHandle startIrsJob(final RegisterBpnInvestigationJob request, final UUID batchId, final String owner) { - final JobHandle jobHandle = irsItemGraphQueryService.registerItemJob(bpnInvestigations(request.getKey(), request.getBomLifecycle()), batchId, owner); + final JobHandle jobHandle = irsItemGraphQueryService.registerItemJob( + bpnInvestigations(request.getKey(), request.getBomLifecycle()), batchId, owner); final UUID createdJobId = jobHandle.getId(); final Optional multiTransferJob = jobStore.find(createdJobId.toString()); @@ -117,21 +119,23 @@ public void handleNotificationCallback(final EdcNotification investigationJobNotificationPredicate( final EdcNotification notification) { - return investigationJob -> investigationJob.getUnansweredNotificationIds() - .contains(notification.getHeader().getOriginalNotificationId()); + return investigationJob -> investigationJob.getUnansweredNotifications() + .stream() + .map(Notification::notificationId) + .anyMatch(notificationId -> notificationId.equals( + notification.getHeader().getOriginalNotificationId())); } private RegisterJob bpnInvestigations(final PartChainIdentificationKey key, final BomLifecycle bomLifecycle) { diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java index c7f03a798f..ae86cf9a65 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/InvestigationJobProcessingEventListener.java @@ -34,6 +34,7 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.irs.common.JobProcessingFinishedEvent; import org.eclipse.tractusx.irs.component.Jobs; +import org.eclipse.tractusx.irs.component.Notification; import org.eclipse.tractusx.irs.component.Relationship; import org.eclipse.tractusx.irs.connector.job.JobStore; import org.eclipse.tractusx.irs.connector.job.MultiTransferJob; @@ -196,7 +197,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo try { final String notificationId = sendEdcNotification(bpn, url, investigationJobUpdate.getIncidentBpns(), globalAssetIds); - investigationJobUpdate.withUnansweredNotificationIds(Collections.singletonList(notificationId)); + investigationJobUpdate.withUnansweredNotifications(Collections.singletonList(new Notification(notificationId, bpn))); } catch (final EdcClientException e) { log.error("Exception during sending EDC notification.", e); investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, bpn); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index afc468b906..c65f7cd56c 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -44,6 +44,7 @@ import org.eclipse.tractusx.irs.component.Job; import org.eclipse.tractusx.irs.component.JobHandle; import org.eclipse.tractusx.irs.component.Jobs; +import org.eclipse.tractusx.irs.component.Notification; import org.eclipse.tractusx.irs.component.PartChainIdentificationKey; import org.eclipse.tractusx.irs.component.RegisterBpnInvestigationJob; import org.eclipse.tractusx.irs.component.RegisterJob; @@ -52,11 +53,8 @@ import org.eclipse.tractusx.irs.connector.job.MultiTransferJob; import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification; import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotificationHeader; -import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotificationResponse; -import org.eclipse.tractusx.irs.edc.client.model.notification.NotificationContent; import org.eclipse.tractusx.irs.edc.client.model.notification.ResponseNotificationContent; import org.eclipse.tractusx.irs.services.IrsItemGraphQueryService; -import org.eclipse.tractusx.irs.util.JsonUtil; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.web.server.ResponseStatusException; @@ -120,7 +118,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { final UUID jobId = UUID.randomUUID(); final String owner = securityHelperService.getClientIdClaim(); - final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).bpn("bot-impacted-bpn").build(); + final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).parentBpn("bot-impacted-bpn").build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() .notificationId(notificationId) .originalNotificationId(notificationId) @@ -129,7 +127,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { .header(header1) .content(resultNo) .build(); - final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").hops(0).bpn("impacted-bpn").build(); + final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").hops(0).parentBpn("impacted-bpn").build(); final EdcNotificationHeader header2 = EdcNotificationHeader.builder() .notificationId(notificationId2) .originalNotificationId(notificationId2) @@ -141,7 +139,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob( Jobs.builder().job(Job.builder().id(jobId).owner(owner).build()).build(), - new ArrayList<>()).withUnansweredNotificationIds(List.of(notificationId, notificationId2)); + new ArrayList<>()).withUnansweredNotifications(List.of(new Notification(notificationId, "bpn"), new Notification(notificationId2, "bpn"))); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); assertDoesNotThrow(() -> essService.handleNotificationCallback(edcNotification)); @@ -179,7 +177,7 @@ void shouldKeepJobInRunningIfNotificationIsOpen() { final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob( Jobs.builder().job(Job.builder().id(jobId).owner(owner).build()).build(), - new ArrayList<>()).withUnansweredNotificationIds(Collections.singletonList(notificationId)); + new ArrayList<>()).withUnansweredNotifications(Collections.singletonList(new Notification(notificationId, "bpn"))); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); assertThat(bpnInvestigationJobCache.findAll()).hasSize(1); @@ -215,7 +213,7 @@ void shouldCompleteJobIfAllNotificationsSentWereAnswered() { .build()) .build(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, - null).withAnsweredNotification(answeredNotification).withUnansweredNotificationIds(List.of()); + null).withAnsweredNotification(answeredNotification).withUnansweredNotifications(List.of()); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); // Act @@ -236,7 +234,7 @@ void shouldCompleteJobIfFinalNotificationWasReceived() { final Jobs jobSnapshot = job(jobId, owner); final String notificationId = UUID.randomUUID().toString(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, null).update(jobSnapshot, - SupplyChainImpacted.NO, "bpn").withUnansweredNotificationIds(List.of(notificationId)); + SupplyChainImpacted.NO, "bpn").withUnansweredNotifications(List.of(new Notification(notificationId, "bpn"))); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index 9a5d3c7aa3..68bc50a09a 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -39,7 +39,7 @@ public class ResponseNotificationContent implements NotificationContent { private final String result; private Integer hops; - private final String bpn; + private String parentBpn; /** * Incrementing hops value diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java new file mode 100644 index 0000000000..9a19dc0841 --- /dev/null +++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java @@ -0,0 +1,27 @@ +/******************************************************************************** + * Copyright (c) 2021,2022,2023 + * 2022: ZF Friedrichshafen AG + * 2022: ISTOS GmbH + * 2022,2023: Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * 2022,2023: BOSCH AG + * Copyright (c) 2021,2022,2023 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.component; + +public record Notification(String notificationId, String bpn) { +} \ No newline at end of file From 9db14212286450031cc40e0823bc3768df45affb Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Mon, 6 Nov 2023 14:28:21 +0100 Subject: [PATCH 19/54] feat(impl):[TRI-1658] added checkstyle fixes --- .../org/eclipse/tractusx/irs/component/Notification.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java index 9a19dc0841..9641d1e37c 100644 --- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java +++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java @@ -23,5 +23,8 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.component; +/** + * Response notification body containing notificationId and parent bpn + */ public record Notification(String notificationId, String bpn) { -} \ No newline at end of file +} From d43991739815efd13c74277dc352672bbabd87bd Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Mon, 6 Nov 2023 14:33:58 +0100 Subject: [PATCH 20/54] feat(impl):[TRI-1658] added checkstyle fixes for tabs --- .../irs/ess/service/BpnInvestigationJob.java | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index 65b55eef74..150f4be013 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -64,7 +64,8 @@ public BpnInvestigationJob(final Jobs jobSnapshot, final List incidentBp this(jobSnapshot, incidentBpns, new ArrayList<>(), new ArrayList<>(), JobState.RUNNING); } - public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain, final String bpn) { + public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain, + final String bpn) { final Optional previousSupplyChain = getSupplyChainImpacted(); final SupplyChainImpacted supplyChainImpacted = previousSupplyChain.map( @@ -81,19 +82,22 @@ public BpnInvestigationJob withUnansweredNotifications(final List return this; } - public BpnInvestigationJob withAnsweredNotification(final EdcNotification notification) { - this.unansweredNotifications.removeIf(unansweredNotification -> unansweredNotification.notificationId().equals(notification.getHeader().getOriginalNotificationId())); - final Optional parentBpn = this.unansweredNotifications.stream() - .filter(unansweredNotification -> unansweredNotification.notificationId() - .equals(notification.getHeader() - .getOriginalNotificationId())) - .map(Notification::bpn) - .findAny(); - - notification.getContent().setParentBpn(parentBpn.orElse(null)); - notification.getContent().incrementHops(); - this.answeredNotifications.add(notification); - return this; + public BpnInvestigationJob withAnsweredNotification( + final EdcNotification notification) { + this.unansweredNotifications.removeIf(unansweredNotification -> unansweredNotification.notificationId() + .equals(notification.getHeader() + .getOriginalNotificationId())); + final Optional parentBpn = this.unansweredNotifications.stream() + .filter(unansweredNotification -> unansweredNotification.notificationId() + .equals(notification.getHeader() + .getOriginalNotificationId())) + .map(Notification::bpn) + .findAny(); + + notification.getContent().setParentBpn(parentBpn.orElse(null)); + notification.getContent().incrementHops(); + this.answeredNotifications.add(notification); + return this; } public BpnInvestigationJob complete() { @@ -126,15 +130,16 @@ private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyCha ResponseNotificationContent::getHops)); final List suppliersFirstLevel = incidentWithMinHopsValue.map( - min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) - .stream() - .toList(); + min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) + .stream() + .toList(); supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); } final Submodel supplyChainImpactedSubmodel = Submodel.builder() .aspectType(SUPPLY_CHAIN_ASPECT_TYPE) - .payload(new JsonUtil().asMap(supplyChainImpactedAspectBuilder.build())) + .payload(new JsonUtil().asMap( + supplyChainImpactedAspectBuilder.build())) .build(); return irsJob.toBuilder() From a0fe225581ab8133dd317546999b48a92ae39512 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Mon, 6 Nov 2023 15:53:32 +0100 Subject: [PATCH 21/54] feat(impl):[TRI-1658] fixed problem with missing notification bpn --- .../tractusx/irs/ess/service/BpnInvestigationJob.java | 7 ++++--- .../eclipse/tractusx/irs/ess/service/EssServiceTest.java | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index 150f4be013..08336f9d51 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -84,9 +84,6 @@ public BpnInvestigationJob withUnansweredNotifications(final List public BpnInvestigationJob withAnsweredNotification( final EdcNotification notification) { - this.unansweredNotifications.removeIf(unansweredNotification -> unansweredNotification.notificationId() - .equals(notification.getHeader() - .getOriginalNotificationId())); final Optional parentBpn = this.unansweredNotifications.stream() .filter(unansweredNotification -> unansweredNotification.notificationId() .equals(notification.getHeader() @@ -94,6 +91,10 @@ public BpnInvestigationJob withAnsweredNotification( .map(Notification::bpn) .findAny(); + this.unansweredNotifications.removeIf(unansweredNotification -> unansweredNotification.notificationId() + .equals(notification.getHeader() + .getOriginalNotificationId())); + notification.getContent().setParentBpn(parentBpn.orElse(null)); notification.getContent().incrementHops(); this.answeredNotifications.add(notification); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index c65f7cd56c..8755944fc5 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -129,7 +129,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { .build(); final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").hops(0).parentBpn("impacted-bpn").build(); final EdcNotificationHeader header2 = EdcNotificationHeader.builder() - .notificationId(notificationId2) + .notificationId(notificationId) .originalNotificationId(notificationId2) .build(); final EdcNotification edcNotification2 = EdcNotification.builder() From 8cfe9dec793388883c37ab075f061093ca1e332a Mon Sep 17 00:00:00 2001 From: ds-alexander-bulgakov Date: Tue, 7 Nov 2023 11:55:30 +0100 Subject: [PATCH 22/54] TRI-1658: Corrected Vehicle D assets in ESS_Testdata_v2.0.0-AsPlanned.json --- local/testing/testdata/ESS_Testdata_v2.0.0-AsPlanned.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/local/testing/testdata/ESS_Testdata_v2.0.0-AsPlanned.json b/local/testing/testdata/ESS_Testdata_v2.0.0-AsPlanned.json index 8b6169e05e..cd10c257bc 100644 --- a/local/testing/testdata/ESS_Testdata_v2.0.0-AsPlanned.json +++ b/local/testing/testdata/ESS_Testdata_v2.0.0-AsPlanned.json @@ -773,7 +773,7 @@ "createdOn": "2022-02-03T14:48:54.709Z", "lastModifiedOn": "2022-02-03T14:48:54.709Z", "businessPartner": "BPNL00000004FAIL", - "catenaXId": "urn:uuid:22847bfd-eb8d-41b7-b088-3a548b7541a8" + "catenaXId": "urn:uuid:9846f1c6-0dd0-4d5a-9c7a-30af0b7e0247" }, { "validityPeriod": { @@ -786,8 +786,8 @@ }, "createdOn": "2022-02-03T14:48:54.709Z", "lastModifiedOn": "2022-02-03T14:48:54.709Z", - "businessPartner": "BPNL00ARBITRARY9", - "catenaXId": "urn:uuid:9846f1c6-0dd0-4d5a-9c7a-30af0b7e0247" + "businessPartner": "BPNL00ARBITRARY10", + "catenaXId": "urn:uuid:22847bfd-eb8d-41b7-b088-3a548b7541a8" } ] } @@ -869,7 +869,7 @@ }, "createdOn": "2022-02-03T14:48:54.709Z", "lastModifiedOn": "2022-02-03T14:48:54.709Z", - "businessPartner": "BPNS00ARBITRARY9", + "businessPartner": "BPNS00ARBITRARY11", "catenaXId": "urn:uuid:01796f87-9677-43f0-9c62-61665be29d85" } ] From e2c8d086f293b70b860db5b390058540fb38e39a Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Tue, 7 Nov 2023 12:01:14 +0100 Subject: [PATCH 23/54] feat(impl):[TRI-1658] added tests, code clean up --- CHANGELOG.md | 1 + .../irs/ess/service/BpnInvestigationJob.java | 27 ++++++---- .../EssRecursiveNotificationHandlerTest.java | 2 +- .../irs/ess/service/EssServiceTest.java | 52 +++++++++++++++++++ 4 files changed, 70 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73755a8b53..0635986e9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - ESS - Added 'hops' parameter to SupplyChainImpacted Aspect model - contains relative distance in the supply chain + - Added `impactedSuppliersOnFirstTier` parameter to Supply SupplyChainImpacted Aspect model - contains information of first level supply chain impacted ## [4.0.0] - 2023-10-27 ### Added diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index 08336f9d51..d188987471 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -84,23 +84,28 @@ public BpnInvestigationJob withUnansweredNotifications(final List public BpnInvestigationJob withAnsweredNotification( final EdcNotification notification) { - final Optional parentBpn = this.unansweredNotifications.stream() - .filter(unansweredNotification -> unansweredNotification.notificationId() - .equals(notification.getHeader() - .getOriginalNotificationId())) - .map(Notification::bpn) - .findAny(); - - this.unansweredNotifications.removeIf(unansweredNotification -> unansweredNotification.notificationId() - .equals(notification.getHeader() - .getOriginalNotificationId())); - + final Optional parentBpn = getParentBpn(notification); + removeFromUnansweredNotification(notification); notification.getContent().setParentBpn(parentBpn.orElse(null)); notification.getContent().incrementHops(); this.answeredNotifications.add(notification); + return this; } + private Optional getParentBpn(final EdcNotification notification) { + return this.unansweredNotifications.stream() + .filter(unansweredNotification -> unansweredNotification.notificationId() + .equals(notification.getHeader().getOriginalNotificationId())) + .map(Notification::bpn) + .findAny(); + } + + private void removeFromUnansweredNotification(final EdcNotification notification) { + this.unansweredNotifications.removeIf(unansweredNotification -> unansweredNotification.notificationId() + .equals(notification.getHeader().getOriginalNotificationId())); + } + public BpnInvestigationJob complete() { this.state = JobState.COMPLETED; return this; diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandlerTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandlerTest.java index 0c3a543004..81bca838c8 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandlerTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandlerTest.java @@ -57,7 +57,7 @@ class EssRecursiveNotificationHandlerTest { @Test void shouldDoNothingWhenThereIsNoInvestigationJob() { // when - cut.handleNotification(UUID.randomUUID(), SupplyChainImpacted.UNKNOWN, ""); + cut.handleNotification(UUID.randomUUID(), SupplyChainImpacted.UNKNOWN, "bpn"); // then verifyNoInteractions(edcNotificationSender); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index 8755944fc5..c802be5025 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -168,6 +168,58 @@ void shouldUpdateJobSnapshotIfNotificationFound() { assertThat(job.getState()).isEqualTo(JobState.COMPLETED); } + @Test + void shouldReturnFirstImpactedSupplierWhenNotificationFound() { + // given + final String notificationId = UUID.randomUUID().toString(); + final String notificationId2 = UUID.randomUUID().toString(); + final UUID jobId = UUID.randomUUID(); + final String owner = securityHelperService.getClientIdClaim(); + + final String bpnLevel0 = "bpn-level-0"; + final String bpnLevel1 = "bpn-level-1"; + + final ResponseNotificationContent responseNotificationContentLevel1 = ResponseNotificationContent.builder().result("No").hops(0).parentBpn(bpnLevel0).build(); + final EdcNotificationHeader header1 = EdcNotificationHeader.builder() + .notificationId(notificationId) + .originalNotificationId(notificationId) + .build(); + final EdcNotification responseNotificationLevel1 = EdcNotification.builder() + .header(header1) + .content(responseNotificationContentLevel1) + .build(); + + + final ResponseNotificationContent impactedResponseNotificationContent = ResponseNotificationContent.builder().result("Yes").hops(0).parentBpn(bpnLevel1).build(); + final EdcNotificationHeader header2 = EdcNotificationHeader.builder() + .notificationId(notificationId) + .originalNotificationId(notificationId2) + .build(); + final EdcNotification responseNotificationLevel2 = EdcNotification.builder() + .header(header2) + .content(impactedResponseNotificationContent) + .build(); + + final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob( + Jobs.builder().job(Job.builder().id(jobId).owner(owner).build()).build(), + new ArrayList<>()).withUnansweredNotifications(List.of(new Notification(notificationId, bpnLevel0), new Notification(notificationId2, bpnLevel1))); + bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); + + // when + essService.handleNotificationCallback(responseNotificationLevel1); + essService.handleNotificationCallback(responseNotificationLevel2); + + // then + final BpnInvestigationJob job2 = bpnInvestigationJobCache.findAll().get(0); + final List> supplyChainImpacted2 = (List>) job2.getJobSnapshot() + .getSubmodels() + .get(0) + .getPayload() + .get("impactedSuppliersOnFirstTier"); + + assertThat(supplyChainImpacted2.get(0).get("bpnl").toString()).isEqualTo(bpnLevel1); + } + @Test void shouldKeepJobInRunningIfNotificationIsOpen() { final String notificationId = UUID.randomUUID().toString(); From 78f79fa45a65aa4c94a61827522ad5eede0c9613 Mon Sep 17 00:00:00 2001 From: ds-alexander-bulgakov Date: Wed, 8 Nov 2023 08:00:52 +0100 Subject: [PATCH 24/54] TRI-1658 (#246 and #244): Added tavern tests and according helpers for supplyChainFirstLevelBpn and hops --- .../api-tests/irs-api-tests.tavern.yaml | 345 ++++++++++++++++++ local/testing/api-tests/tavern_helpers.py | 16 + 2 files changed, 361 insertions(+) diff --git a/local/testing/api-tests/irs-api-tests.tavern.yaml b/local/testing/api-tests/irs-api-tests.tavern.yaml index d8127916c8..0c26b0804c 100644 --- a/local/testing/api-tests/irs-api-tests.tavern.yaml +++ b/local/testing/api-tests/irs-api-tests.tavern.yaml @@ -498,6 +498,351 @@ stages: content-type: application/json +--- + + +test_name: Make sure first level supplier BPNL in investigation job with four level request has been detected correctly + +strict: + - headers:off + - json:off + +stages: + - name: register a BPN investigation with valid globalAssetId + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" + json: + key: + # Tested with Vehicle A + globalAssetId: urn:uuid:0733946c-59c6-41ae-9570-cb43a6e4c79e + bpn: BPNL00000003AYRE + bomLifecycle: asPlanned + callbackUrl: http://testikus.com + incidentBPNSs: + - BPNS00000003B6LU + method: POST + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 201 + headers: + content-type: application/json + save: + json: + job_id: id + + - *verify_ESS_job_response_with_desired_test_steps_and_wait_up_to_15_minutes_for_COMPLETED + + - name: get response for created investigation and check results + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations/{job_id}" + params: + returnUncompletedJob: true + method: GET + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 200 + verify_response_with: + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested + - function: local.testing.api-tests.tavern_helpers:supplyChainFirstLevelBpn_is_as_expected + extra_kwargs: + expectedBpnl: BPNL00ARBITRARY1 + headers: + content-type: application/json + + +--- + + +test_name: Make sure first level supplier bpnl in investigation job with three level request has been detected correctly + +strict: + - headers:off + - json:off + +stages: + - name: register a BPN investigation with valid globalAssetId + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" + json: + key: + # Tested with Vehicle C + globalAssetId: urn:uuid:1c7a25ea-0490-4944-b9c9-d8c666d47958 + bpn: BPNL00ARBITRARY4 + incidentBPNSs: + - BPNS00ARBITRARY7 + method: POST + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 201 + headers: + content-type: application/json + save: + json: + job_id: id + + - *verify_ESS_job_response_with_desired_test_steps_and_wait_up_to_15_minutes_for_COMPLETED + + - name: get response for created investigation and check results + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations/{job_id}" + params: + returnUncompletedJob: true + method: GET + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 200 + verify_response_with: + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested + - function: local.testing.api-tests.tavern_helpers:supplyChainFirstLevelBpn_is_as_expected + extra_kwargs: + expectedBpnl: BPNL00ARBITRARY5 + headers: + content-type: application/json + + +--- + + +test_name: Make sure first level supplier bpnl in investigation job with one level request has been detected correctly + +strict: + - headers:off + - json:off + +stages: + - name: register a BPN investigation with valid globalAssetId + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" + json: + key: + #tested with Vehicle D + globalAssetId: urn:uuid:3a2a1ca9-c6c1-49c7-a7ae-1dfc5fb9881f + bpn: BPNL00ARBITRARY8 + incidentBPNSs: + - BPNS0ARBITRARY10 + method: POST + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 201 + headers: + content-type: application/json + save: + json: + job_id: id + + - *verify_ESS_job_response_with_desired_test_steps_and_wait_up_to_15_minutes_for_COMPLETED + + - name: get response for created investigation and check results + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations/{job_id}" + params: + returnUncompletedJob: true + method: GET + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 200 + verify_response_with: + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested + - function: local.testing.api-tests.tavern_helpers:supplyChainFirstLevelBpn_is_as_expected + extra_kwargs: + expectedBpnl: BPNL00ARBITRARY10 + headers: + content-type: application/json + + +--- + + +test_name: Make sure four hops in supplyChain impacted investigation job has been detected correctly + +strict: + - headers:off + - json:off + +stages: + - name: register a BPN investigation with valid globalAssetId + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" + json: + key: + # Tested with Vehicle A + globalAssetId: urn:uuid:0733946c-59c6-41ae-9570-cb43a6e4c79e + bpn: BPNL00000003AYRE + bomLifecycle: asPlanned + callbackUrl: http://testikus.com + incidentBPNSs: + - BPNS00000003B6LU + method: POST + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 201 + headers: + content-type: application/json + save: + json: + job_id: id + + - *verify_ESS_job_response_with_desired_test_steps_and_wait_up_to_15_minutes_for_COMPLETED + + - name: get response for created investigation and check results + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations/{job_id}" + params: + returnUncompletedJob: true + method: GET + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 200 + verify_response_with: + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested + - function: local.testing.api-tests.tavern_helpers:supplyChainhops_is_as_expected + extra_kwargs: + expectedHops: 4 + headers: + content-type: application/json + + +--- + + +test_name: Make sure three hops in supplyChain impacted investigation job has been detected correctly + +strict: + - headers:off + - json:off + +stages: + - name: register a BPN investigation with valid globalAssetId + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" + json: + key: + # Tested with Vehicle C + globalAssetId: urn:uuid:1c7a25ea-0490-4944-b9c9-d8c666d47958 + bpn: BPNL00ARBITRARY4 + incidentBPNSs: + - BPNS00ARBITRARY7 + method: POST + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 201 + headers: + content-type: application/json + save: + json: + job_id: id + + - *verify_ESS_job_response_with_desired_test_steps_and_wait_up_to_15_minutes_for_COMPLETED + + - name: get response for created investigation and check results + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations/{job_id}" + params: + returnUncompletedJob: true + method: GET + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 200 + verify_response_with: + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested + - function: local.testing.api-tests.tavern_helpers:supplyChainhops_is_as_expected + extra_kwargs: + expectedHops: 3 + headers: + content-type: application/json + + +--- + + +test_name: Make sure one hops in supplyChain impacted investigation job has been detected correctly + +strict: + - headers:off + - json:off + +stages: + - name: register a BPN investigation with valid globalAssetId + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" + json: + key: + #tested with Vehicle D + globalAssetId: urn:uuid:3a2a1ca9-c6c1-49c7-a7ae-1dfc5fb9881f + bpn: BPNL00ARBITRARY8 + incidentBPNSs: + - BPNS0ARBITRARY10 + method: POST + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 201 + headers: + content-type: application/json + save: + json: + job_id: id + + - *verify_ESS_job_response_with_desired_test_steps_and_wait_up_to_15_minutes_for_COMPLETED + + - name: get response for created investigation and check results + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations/{job_id}" + params: + returnUncompletedJob: true + method: GET + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 200 + verify_response_with: + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested + - function: local.testing.api-tests.tavern_helpers:supplyChainhops_is_as_expected + extra_kwargs: + expectedHops: 1 + headers: + content-type: application/json + ############################### \/ ESS Tests with T-Systems and submodel servers \/ ############################## ####### !!!!!! Commented out since there is no testdata available for the moment !!!!!! ###### #--- diff --git a/local/testing/api-tests/tavern_helpers.py b/local/testing/api-tests/tavern_helpers.py index f273182c1e..a406138de4 100644 --- a/local/testing/api-tests/tavern_helpers.py +++ b/local/testing/api-tests/tavern_helpers.py @@ -15,6 +15,22 @@ def supplyChainImpacted_is_Yes(response): assert 'Yes' in i.get("payload").get('supplyChainImpacted') +def supplyChainFirstLevelBpn_is_as_expected(response, expectedBpnl): + submodels = response.json().get("submodels") + for i in submodels: + impactedSuppliersOnFirstTier = i.get("payload").get("impactedSuppliersOnFirstTier") + for ii in impactedSuppliersOnFirstTier: + assert expectedBpnl in ii.get('bpnl') + + +def supplyChainhops_is_as_expected(response, expectedHops): + submodels = response.json().get("submodels") + for i in submodels: + impactedSuppliersOnFirstTier = i.get("payload").get("impactedSuppliersOnFirstTier") + for ii in impactedSuppliersOnFirstTier: + assert ii.get('hops') == expectedHops + + def supplyChainImpacted_is_No(response): submodels = response.json().get("submodels") print("submodels ", submodels) From d6da7f81d741f7024dfb6575fcfef28ad0c312cb Mon Sep 17 00:00:00 2001 From: ds-alexander-bulgakov Date: Wed, 8 Nov 2023 09:00:00 +0100 Subject: [PATCH 25/54] refacroting: refactored tavern-helpers for supplyChainImpacted checks --- .../api-tests/irs-api-tests.tavern.yaml | 60 ++++++++++++++----- local/testing/api-tests/tavern_helpers.py | 22 +------ 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/local/testing/api-tests/irs-api-tests.tavern.yaml b/local/testing/api-tests/irs-api-tests.tavern.yaml index 0c26b0804c..c7882c1a75 100644 --- a/local/testing/api-tests/irs-api-tests.tavern.yaml +++ b/local/testing/api-tests/irs-api-tests.tavern.yaml @@ -97,7 +97,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested headers: content-type: application/json @@ -153,7 +155,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_No + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "No" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested headers: content-type: application/json @@ -206,7 +210,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Unknown + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Unknown" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested headers: content-type: application/json @@ -262,7 +268,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested headers: content-type: application/json @@ -319,7 +327,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Unknown + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Unknown" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested headers: content-type: application/json @@ -373,7 +383,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:relationships_for_BPN_investigations_contains_several_childs - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested - function: local.testing.api-tests.tavern_helpers:tombstones_are_empty @@ -433,7 +445,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Unknown + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Unknown" - function: local.testing.api-tests.tavern_helpers:tombstone_for_EssValidation_are_correct extra_kwargs: expectedTombstone: "AspectType 'PartSiteInformationAsPlanned' not found in Job." @@ -490,7 +504,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Unknown + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Unknown" - function: local.testing.api-tests.tavern_helpers:tombstone_for_EssValidation_are_correct extra_kwargs: expectedTombstone: "'PartSiteInformationAsPlanned' exists, but catenaXSiteId could not be found." @@ -548,7 +564,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested - function: local.testing.api-tests.tavern_helpers:supplyChainFirstLevelBpn_is_as_expected extra_kwargs: @@ -605,7 +623,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested - function: local.testing.api-tests.tavern_helpers:supplyChainFirstLevelBpn_is_as_expected extra_kwargs: @@ -662,7 +682,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested - function: local.testing.api-tests.tavern_helpers:supplyChainFirstLevelBpn_is_as_expected extra_kwargs: @@ -721,7 +743,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested - function: local.testing.api-tests.tavern_helpers:supplyChainhops_is_as_expected extra_kwargs: @@ -778,7 +802,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested - function: local.testing.api-tests.tavern_helpers:supplyChainhops_is_as_expected extra_kwargs: @@ -835,7 +861,9 @@ stages: response: status_code: 200 verify_response_with: - - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested - function: local.testing.api-tests.tavern_helpers:supplyChainhops_is_as_expected extra_kwargs: @@ -894,7 +922,9 @@ stages: # response: # status_code: 200 # verify_response_with: -# - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_Yes +# - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected +# extra_kwargs: +# expectedSupplyChainImpacted: "Yes" # - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested # headers: # content-type: application/json diff --git a/local/testing/api-tests/tavern_helpers.py b/local/testing/api-tests/tavern_helpers.py index a406138de4..6cec26fdca 100644 --- a/local/testing/api-tests/tavern_helpers.py +++ b/local/testing/api-tests/tavern_helpers.py @@ -6,13 +6,13 @@ from box import Box -def supplyChainImpacted_is_Yes(response): +def supplyChainImpacted_is_as_expected(response, expectedSupplyChainImpacted): submodels = response.json().get("submodels") print("submodels ", submodels) assert len(submodels) <= 1 for i in submodels: assert 'supply_chain_impacted' in i.get('aspectType') - assert 'Yes' in i.get("payload").get('supplyChainImpacted') + assert expectedSupplyChainImpacted in i.get("payload").get('supplyChainImpacted') def supplyChainFirstLevelBpn_is_as_expected(response, expectedBpnl): @@ -31,24 +31,6 @@ def supplyChainhops_is_as_expected(response, expectedHops): assert ii.get('hops') == expectedHops -def supplyChainImpacted_is_No(response): - submodels = response.json().get("submodels") - print("submodels ", submodels) - assert len(submodels) <= 1 - for i in submodels: - assert 'supply_chain_impacted' in i.get('aspectType') - assert 'No' in i.get("payload").get('supplyChainImpacted') - - -def supplyChainImpacted_is_Unknown(response): - submodels = response.json().get("submodels") - print("submodels ", submodels) - assert len(submodels) <= 1 - for i in submodels: - assert 'supply_chain_impacted' in i.get('aspectType') - assert 'Unknown' in i.get("payload").get('supplyChainImpacted') - - def errors_for_invalid_investigation_request_are_correct(response): print(response.json().get("messages")) error_list = response.json().get("messages") From 72314b01c5425840648ad87b5b4941b90b57ca96 Mon Sep 17 00:00:00 2001 From: ds-alexander-bulgakov Date: Thu, 9 Nov 2023 09:27:52 +0100 Subject: [PATCH 26/54] feat(impl):[244] changed tavern method name --- local/testing/api-tests/irs-api-tests.tavern.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local/testing/api-tests/irs-api-tests.tavern.yaml b/local/testing/api-tests/irs-api-tests.tavern.yaml index c7882c1a75..b9299b9640 100644 --- a/local/testing/api-tests/irs-api-tests.tavern.yaml +++ b/local/testing/api-tests/irs-api-tests.tavern.yaml @@ -491,7 +491,7 @@ stages: - *verify_ESS_job_response_with_desired_test_steps_and_wait_up_to_15_minutes_for_COMPLETED - - name: get response for created investigation + - name: get response for created investigation and check results request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations/{job_id}" params: From 979ae74d880925ca768a0c42a9d34a5c8647d5ac Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Thu, 9 Nov 2023 15:20:07 +0100 Subject: [PATCH 27/54] feat(impl):[244] changed approach for first level supplier incident for bpn and hops --- .../tractusx/irs/ess/service/BpnInvestigationJob.java | 5 ++++- .../irs/ess/service/EssRecursiveNotificationHandler.java | 4 ++-- .../org/eclipse/tractusx/irs/ess/service/EssService.java | 2 +- .../service/InvestigationJobProcessingEventListener.java | 6 +++--- .../ess/service/EssRecursiveNotificationHandlerTest.java | 6 +++--- .../InvestigationJobProcessingEventListenerTest.java | 4 ++-- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index d188987471..ddbc5ce1d3 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -35,6 +35,7 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.irs.component.Job; import org.eclipse.tractusx.irs.component.Jobs; import org.eclipse.tractusx.irs.component.Notification; @@ -50,6 +51,7 @@ */ @Getter @AllArgsConstructor(access = AccessLevel.PRIVATE) +@Slf4j public class BpnInvestigationJob { private static final String SUPPLY_CHAIN_ASPECT_TYPE = "supply_chain_impacted"; @@ -124,6 +126,7 @@ public BpnInvestigationJob complete() { private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyChainImpacted supplyChainImpacted, final String bpn) { + log.debug(bpn); final SupplyChainImpactedAspect.SupplyChainImpactedAspectBuilder supplyChainImpactedAspectBuilder = SupplyChainImpactedAspect.builder() .supplyChainImpacted( supplyChainImpacted); @@ -136,7 +139,7 @@ private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyCha ResponseNotificationContent::getHops)); final List suppliersFirstLevel = incidentWithMinHopsValue.map( - min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) + min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(min.getParentBpn(), min.getHops())) .stream() .toList(); supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java index 8b4cce1d6e..dd6318130d 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java @@ -48,7 +48,7 @@ public class EssRecursiveNotificationHandler { private final BpnInvestigationJobCache bpnInvestigationJobCache; private final EdcNotificationSender edcNotificationSender; - /* package */ void handleNotification(final UUID finishedJobId, final SupplyChainImpacted supplyChainImpacted, final String bpn) { + /* package */ void handleNotification(final UUID finishedJobId, final SupplyChainImpacted supplyChainImpacted, final String bpn, final int hops) { final Optional relatedJobsId = relatedInvestigationJobsCache.findByRecursiveRelatedJobId( finishedJobId); @@ -56,7 +56,7 @@ public class EssRecursiveNotificationHandler { relatedJobsId.ifPresentOrElse(relatedJobs -> { if (SupplyChainImpacted.YES.equals(supplyChainImpacted)) { log.debug("SupplyChain is impacted. Sending notification back to requestor."); - edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, FIRST_HOP, bpn); + edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, hops, bpn); relatedInvestigationJobsCache.remove( relatedJobs.originalNotification().getHeader().getNotificationId()); } else { diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 934c16efc0..5a71931b08 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -129,7 +129,7 @@ public void handleNotificationCallback(final EdcNotification Date: Fri, 10 Nov 2023 15:05:27 +0100 Subject: [PATCH 28/54] feat(impl):[244] added more tests for ESS hops and firstLevelBpn and some renames --- .../api-tests/irs-api-tests.tavern.yaml | 99 +++++++++++++++---- 1 file changed, 80 insertions(+), 19 deletions(-) diff --git a/local/testing/api-tests/irs-api-tests.tavern.yaml b/local/testing/api-tests/irs-api-tests.tavern.yaml index b9299b9640..32ef4cabec 100644 --- a/local/testing/api-tests/irs-api-tests.tavern.yaml +++ b/local/testing/api-tests/irs-api-tests.tavern.yaml @@ -40,7 +40,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -115,7 +115,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId for unknown BPN + - name: register a BPN investigation job with valid globalAssetId for unknown BPN request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -228,7 +228,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId and valid BPN + - name: register a BPN investigation job with valid globalAssetId and valid BPN request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -287,7 +287,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId and valid BPN but not reachable incidentBPN + - name: register a BPN investigation job with valid globalAssetId and valid BPN but not reachable incidentBPN request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -345,7 +345,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId with several relationships + - name: register a BPN investigation job with valid globalAssetId with several relationships request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -406,7 +406,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -465,7 +465,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -524,7 +524,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -578,6 +578,67 @@ stages: --- +test_name: Make sure first level supplier BPNL in investigation job with several impacted nodes has been detected correctly + +strict: + - headers:off + - json:off + +stages: + - name: register a BPN investigation job with valid globalAssetId + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" + json: + key: + # Tested with Vehicle A on second level + globalAssetId: urn:uuid:aad27ddb-43aa-4e42-98c2-01e529ef127c + bpn: BPNL00ARBITRARY1 + bomLifecycle: asPlanned + callbackUrl: http://testikus.com + incidentBPNSs: + - BPNS00000003B6LU + method: POST + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 201 + headers: + content-type: application/json + save: + json: + job_id: id + + - *verify_ESS_job_response_with_desired_test_steps_and_wait_up_to_15_minutes_for_COMPLETED + + - name: get response for created investigation and check results + request: + url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations/{job_id}" + params: + returnUncompletedJob: true + method: GET + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 200 + verify_response_with: + - function: local.testing.api-tests.tavern_helpers:supplyChainImpacted_is_as_expected + extra_kwargs: + expectedSupplyChainImpacted: "Yes" + - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested + - function: local.testing.api-tests.tavern_helpers:supplyChainFirstLevelBpn_is_as_expected + extra_kwargs: + expectedBpnl: BPNS00000003B6LU + headers: + content-type: application/json + + +--- + + test_name: Make sure first level supplier bpnl in investigation job with three level request has been detected correctly strict: @@ -585,7 +646,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -644,7 +705,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -696,21 +757,21 @@ stages: --- -test_name: Make sure four hops in supplyChain impacted investigation job has been detected correctly +test_name: Make sure one hop in several supplyChain impacted nodes has been detected as shortest correctly strict: - headers:off - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: key: - # Tested with Vehicle A - globalAssetId: urn:uuid:0733946c-59c6-41ae-9570-cb43a6e4c79e - bpn: BPNL00000003AYRE + # Tested with Vehicle A on second level + globalAssetId: urn:uuid:aad27ddb-43aa-4e42-98c2-01e529ef127c + bpn: BPNL00ARBITRARY1 bomLifecycle: asPlanned callbackUrl: http://testikus.com incidentBPNSs: @@ -749,7 +810,7 @@ stages: - function: local.testing.api-tests.tavern_helpers:ESS_job_parameter_are_as_requested - function: local.testing.api-tests.tavern_helpers:supplyChainhops_is_as_expected extra_kwargs: - expectedHops: 4 + expectedHops: 1 headers: content-type: application/json @@ -764,7 +825,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -823,7 +884,7 @@ strict: - json:off stages: - - name: register a BPN investigation with valid globalAssetId + - name: register a BPN investigation job with valid globalAssetId request: url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" json: @@ -883,7 +944,7 @@ stages: # - json:off # #stages: -# - name: register a BPN investigation with valid globalAssetId to T-Systems +# - name: register a BPN investigation job with valid globalAssetId to T-Systems # request: # url: "{tavern.env_vars.IRS_ESS_HOST}/ess/bpn/investigations" # json: From b1f3530005a7ee9d23b6649a3afa9626effe8468 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Mon, 13 Nov 2023 12:19:52 +0100 Subject: [PATCH 29/54] feat(irs-api):[#244] Verification of the 1st level supplier bpn in relation to hops --- .../irs/ess/service/BpnInvestigationJob.java | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index d188987471..0830090f68 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -129,17 +129,27 @@ private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyCha supplyChainImpacted); if (getUnansweredNotifications().isEmpty()) { - final Optional incidentWithMinHopsValue = getAnsweredNotifications().stream() - .map(EdcNotification::getContent) - .filter(ResponseNotificationContent::thereIsIncident) - .min(Comparator.comparing( - ResponseNotificationContent::getHops)); - - final List suppliersFirstLevel = incidentWithMinHopsValue.map( - min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) - .stream() - .toList(); - supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); +// final Optional incidentWithMinHopsValue = getAnsweredNotifications().stream() +// .map(EdcNotification::getContent) +// .filter(ResponseNotificationContent::thereIsIncident) +// .min(Comparator.comparing( +// ResponseNotificationContent::getHops)); +// +// final List suppliersFirstLevel = incidentWithMinHopsValue.map( +// min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) +// .stream() +// .toList(); + + final List incidentWithMinHopsValue = getAnsweredNotifications().stream() + .map(EdcNotification::getContent) + .filter(ResponseNotificationContent::thereIsIncident) + .toList(); + + final List suppliersFirstLevel = incidentWithMinHopsValue.stream() + .map(impacted -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(impacted.getParentBpn(), impacted.getHops())) + .toList(); + + supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); } final Submodel supplyChainImpactedSubmodel = Submodel.builder() From ae3b1fddc7f93be0ea6596d7802dd2ef7ed92624 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Mon, 13 Nov 2023 12:26:38 +0100 Subject: [PATCH 30/54] feat(irs-api):[#244] Verification of the 1st level supplier bpn in relation to hops --- .../irs/ess/service/BpnInvestigationJob.java | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index 0830090f68..b4ca2f6a73 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -27,7 +27,6 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.Set; @@ -96,14 +95,16 @@ public BpnInvestigationJob withAnsweredNotification( private Optional getParentBpn(final EdcNotification notification) { return this.unansweredNotifications.stream() .filter(unansweredNotification -> unansweredNotification.notificationId() - .equals(notification.getHeader().getOriginalNotificationId())) + .equals(notification.getHeader() + .getOriginalNotificationId())) .map(Notification::bpn) .findAny(); } private void removeFromUnansweredNotification(final EdcNotification notification) { this.unansweredNotifications.removeIf(unansweredNotification -> unansweredNotification.notificationId() - .equals(notification.getHeader().getOriginalNotificationId())); + .equals(notification.getHeader() + .getOriginalNotificationId())); } public BpnInvestigationJob complete() { @@ -129,16 +130,16 @@ private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyCha supplyChainImpacted); if (getUnansweredNotifications().isEmpty()) { -// final Optional incidentWithMinHopsValue = getAnsweredNotifications().stream() -// .map(EdcNotification::getContent) -// .filter(ResponseNotificationContent::thereIsIncident) -// .min(Comparator.comparing( -// ResponseNotificationContent::getHops)); -// -// final List suppliersFirstLevel = incidentWithMinHopsValue.map( -// min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) -// .stream() -// .toList(); + // final Optional incidentWithMinHopsValue = getAnsweredNotifications().stream() + // .map(EdcNotification::getContent) + // .filter(ResponseNotificationContent::thereIsIncident) + // .min(Comparator.comparing( + // ResponseNotificationContent::getHops)); + // + // final List suppliersFirstLevel = incidentWithMinHopsValue.map( + // min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) + // .stream() + // .toList(); final List incidentWithMinHopsValue = getAnsweredNotifications().stream() .map(EdcNotification::getContent) @@ -146,10 +147,12 @@ private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyCha .toList(); final List suppliersFirstLevel = incidentWithMinHopsValue.stream() - .map(impacted -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(impacted.getParentBpn(), impacted.getHops())) - .toList(); + .map(impacted -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel( + impacted.getParentBpn(), + impacted.getHops())) + .toList(); - supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); + supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); } final Submodel supplyChainImpactedSubmodel = Submodel.builder() From de621fe5feaf5440b5a0e1b0b015f871c5d5ebab Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Mon, 13 Nov 2023 12:33:35 +0100 Subject: [PATCH 31/54] feat(irs-api):[#244] Verification of the 1st level supplier bpn in relation to hops --- .../irs/ess/service/BpnInvestigationJob.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index b4ca2f6a73..ef3682493e 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -34,6 +34,7 @@ import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.irs.component.Job; import org.eclipse.tractusx.irs.component.Jobs; import org.eclipse.tractusx.irs.component.Notification; @@ -49,6 +50,7 @@ */ @Getter @AllArgsConstructor(access = AccessLevel.PRIVATE) +@Slf4j public class BpnInvestigationJob { private static final String SUPPLY_CHAIN_ASPECT_TYPE = "supply_chain_impacted"; @@ -125,22 +127,12 @@ public BpnInvestigationJob complete() { private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyChainImpacted supplyChainImpacted, final String bpn) { + log.debug(bpn); final SupplyChainImpactedAspect.SupplyChainImpactedAspectBuilder supplyChainImpactedAspectBuilder = SupplyChainImpactedAspect.builder() .supplyChainImpacted( supplyChainImpacted); if (getUnansweredNotifications().isEmpty()) { - // final Optional incidentWithMinHopsValue = getAnsweredNotifications().stream() - // .map(EdcNotification::getContent) - // .filter(ResponseNotificationContent::thereIsIncident) - // .min(Comparator.comparing( - // ResponseNotificationContent::getHops)); - // - // final List suppliersFirstLevel = incidentWithMinHopsValue.map( - // min -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel(bpn, min.getHops())) - // .stream() - // .toList(); - final List incidentWithMinHopsValue = getAnsweredNotifications().stream() .map(EdcNotification::getContent) .filter(ResponseNotificationContent::thereIsIncident) From 206f65bcf70b88ddf9323d26cba0ea35c24bbdcf Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Tue, 14 Nov 2023 15:10:40 +0100 Subject: [PATCH 32/54] feat(irs-api):[#244] Fixed chron duration to be in ISO format, added git-commit msg format --- charts/irs-helm/values.yaml | 2 +- irs-api/src/main/resources/application.yml | 2 +- local/development/commit-msg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/irs-helm/values.yaml b/charts/irs-helm/values.yaml index b4e9582324..87fd536fe7 100644 --- a/charts/irs-helm/values.yaml +++ b/charts/irs-helm/values.yaml @@ -203,7 +203,7 @@ edc: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: 86400000 + cacheTTL: PT24H # Time to live for ConnectorEndpointService.class for fetchConnectorEndpoints method cache discovery: oAuthClientId: portal # ID of the OAuth2 client registration to use, see config spring.security.oauth2.client diff --git a/irs-api/src/main/resources/application.yml b/irs-api/src/main/resources/application.yml index be011ca1ef..40f783502d 100644 --- a/irs-api/src/main/resources/application.yml +++ b/irs-api/src/main/resources/application.yml @@ -173,7 +173,7 @@ irs-edc-client: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: 86400000 + cacheTTL: PT24H digitalTwinRegistry: type: ${DIGITALTWINREGISTRY_TYPE:decentral} # The type of DTR. This can be either "central" or "decentral". If "decentral", descriptorEndpoint, shellLookupEndpoint and oAuthClientId is not required. diff --git a/local/development/commit-msg b/local/development/commit-msg index aaf3038d55..c254f038d5 100644 --- a/local/development/commit-msg +++ b/local/development/commit-msg @@ -16,7 +16,7 @@ fi url="$(git remote get-url origin | sed 's/\.git/#commit-messages/')" # check semantic versioning scheme -if ! echo "$commitTitle" | grep -qE '^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)\([a-z0-9/-]+\)\:\[[A-Z0-9-]+\].*$'; then +if ! echo "$commitTitle" | grep -qE '^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)\([a-z0-9/-]+\)\:\[[#0-9]+\].*$'; then echo "Your commit title did not follow semantic versioning: $commitTitle" echo "Please see $url" exit 1 From d438a998707a7d3ca4433c95623928414584abcb Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Tue, 14 Nov 2023 15:18:47 +0100 Subject: [PATCH 33/54] feat(irs-api):[#244] Updated changelog file --- CHANGELOG.md | 4 ++++ charts/irs-helm/values.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9ccccf514..79dc512b87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - IRS can now check the readiness of external services. Use the new ``management.health.dependencies.enabled`` config entry to determine if external dependencies health checks should be checked (false by default). - The map of external services healthcheck endpoints can be configured with ``management.health.dependencies.urls`` property, eg. ``service_name: http://service_name_host/health`` +- Added cache mechanism for ConnectorEndpointService for fetchConnectorEndpoints method cache + +### Changed +- Updated commit message format check to match github pattern ## [4.0.1] - 2023-11-10 ### Changed diff --git a/charts/irs-helm/values.yaml b/charts/irs-helm/values.yaml index 87fd536fe7..0c875b7466 100644 --- a/charts/irs-helm/values.yaml +++ b/charts/irs-helm/values.yaml @@ -203,7 +203,7 @@ edc: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: PT24H # Time to live for ConnectorEndpointService.class for fetchConnectorEndpoints method cache + cacheTTL: PT24H # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache discovery: oAuthClientId: portal # ID of the OAuth2 client registration to use, see config spring.security.oauth2.client From fa6b40032a8ca42b33775d765e366a9faa0f7ff8 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Tue, 14 Nov 2023 15:41:42 +0100 Subject: [PATCH 34/54] feat(irs-api):[#244] Review corrections --- CHANGELOG.md | 3 --- charts/irs-helm/values.yaml | 2 +- irs-api/src/main/resources/application.yml | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79dc512b87..96490d8102 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - IRS can now check the readiness of external services. Use the new ``management.health.dependencies.enabled`` config entry to determine if external dependencies health checks should be checked (false by default). - The map of external services healthcheck endpoints can be configured with ``management.health.dependencies.urls`` property, eg. ``service_name: http://service_name_host/health`` - Added cache mechanism for ConnectorEndpointService for fetchConnectorEndpoints method cache - -### Changed -- Updated commit message format check to match github pattern ## [4.0.1] - 2023-11-10 ### Changed diff --git a/charts/irs-helm/values.yaml b/charts/irs-helm/values.yaml index 0c875b7466..1288bbfa0f 100644 --- a/charts/irs-helm/values.yaml +++ b/charts/irs-helm/values.yaml @@ -203,7 +203,7 @@ edc: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: PT24H # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache + cacheTTL: PT24H # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache discovery: oAuthClientId: portal # ID of the OAuth2 client registration to use, see config spring.security.oauth2.client diff --git a/irs-api/src/main/resources/application.yml b/irs-api/src/main/resources/application.yml index 40f783502d..f2d007d922 100644 --- a/irs-api/src/main/resources/application.yml +++ b/irs-api/src/main/resources/application.yml @@ -173,7 +173,7 @@ irs-edc-client: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: PT24H + cacheTTL: PT24H # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache digitalTwinRegistry: type: ${DIGITALTWINREGISTRY_TYPE:decentral} # The type of DTR. This can be either "central" or "decentral". If "decentral", descriptorEndpoint, shellLookupEndpoint and oAuthClientId is not required. From 29cc701127f87833980eaea1421a70a8b6c66822 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Wed, 15 Nov 2023 12:31:21 +0100 Subject: [PATCH 35/54] feat(impl):[TRI-279] fix returned http status --- CHANGELOG.md | 3 ++ .../irs/controllers/IrsController.java | 11 +++++-- .../tractusx/irs/IrsFunctionalTest.java | 2 +- .../irs/controllers/IrsControllerTest.java | 31 +++++++++++++++++++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8d932182c..9ded20ccd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 token-uri: ``` +### Fixed +- IRS will return 206 Http status from GET /jobs/{id} endpoint if Job is still running + ## [4.0.1] - 2023-11-10 ### Changed - Added state `STARTED` as acceptable state to complete the EDC transfer process to be compatible with EDC 0.5.1 diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/controllers/IrsController.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/controllers/IrsController.java index 4c89914ed7..a3fb4bea4c 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/controllers/IrsController.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/controllers/IrsController.java @@ -65,6 +65,7 @@ import org.springdoc.core.converters.models.PageableAsQueryParam; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -179,15 +180,19 @@ public JobHandle registerJobForGlobalAssetId(final @Valid @RequestBody RegisterJ @IrsTimer("getjob") @GetMapping("/jobs/{id}") @PreAuthorize("@authorizationService.verifyBpn() && hasAnyAuthority('" + IrsRoles.ADMIN_IRS + "', '" + IrsRoles.VIEW_IRS + "')") - public Jobs getJobById( + public ResponseEntity getJobById( @Parameter(description = "Id of the job.", schema = @Schema(implementation = UUID.class), name = "id", example = "6c311d29-5753-46d4-b32c-19b918ea93b0") @Size(min = IrsAppConstants.JOB_ID_SIZE, max = IrsAppConstants.JOB_ID_SIZE) @Valid @PathVariable final UUID id, @Parameter( - description = " Return job with current processed item graph. Return job with item graph if job is in state , otherwise job.") @Schema( + description = "\\ Return job with current processed item graph. \\ Return job with item graph if job is in state COMPLETED, otherwise job.") @Schema( implementation = Boolean.class, defaultValue = "true") @RequestParam(value = "returnUncompletedJob", required = false) final boolean returnUncompletedJob) { - return itemJobService.getJobForJobId(id, returnUncompletedJob); + final Jobs job = itemJobService.getJobForJobId(id, returnUncompletedJob); + if (job.getJob().getState().equals(JobState.RUNNING)) { + return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT).body(job); + } + return ResponseEntity.ok(job); } @Operation(description = "Cancel job for requested jobId.", operationId = "cancelJobByJobId", diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java index 0d72e54a19..0a51ec40a3 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsFunctionalTest.java @@ -198,7 +198,7 @@ private Callable> getJobDetails(final JobHandle jobHandle) { return () -> { try { thereIsJwtAuthentication(); - return Optional.ofNullable(controller.getJobById(jobHandle.getId(), true)); + return Optional.ofNullable(controller.getJobById(jobHandle.getId(), true).getBody()); } catch (Exception e) { e.printStackTrace(); return Optional.empty(); diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/controllers/IrsControllerTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/controllers/IrsControllerTest.java index 21618ef0db..d266e5ad84 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/controllers/IrsControllerTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/controllers/IrsControllerTest.java @@ -31,6 +31,8 @@ import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -50,6 +52,7 @@ import org.eclipse.tractusx.irs.component.Job; import org.eclipse.tractusx.irs.component.JobHandle; import org.eclipse.tractusx.irs.component.JobStatusResult; +import org.eclipse.tractusx.irs.component.Jobs; import org.eclipse.tractusx.irs.component.PageResult; import org.eclipse.tractusx.irs.component.RegisterJob; import org.eclipse.tractusx.irs.component.enums.Direction; @@ -289,4 +292,32 @@ void shouldReturnForbiddenStatusForAspectModelsWhenRequiredAuthorityIsMissing() .andExpect(status().isForbidden()); } + @Test + @WithMockUser(authorities = "view_irs") + void shouldReturnPartialWhenJobCompleted() throws Exception { + final Jobs runningJob = Jobs.builder().job(Job.builder().id(jobId).state(JobState.RUNNING).build()).build(); + final boolean shouldIncludePartial = Boolean.TRUE; + final boolean shouldNotIncludePartial = Boolean.FALSE; + + when(authorizationService.verifyBpn()).thenReturn(Boolean.TRUE); + when(this.service.getJobForJobId(eq(jobId), anyBoolean())).thenReturn(runningJob); + + this.mockMvc.perform(get("/irs/jobs/" + jobId).queryParam("returnUncompletedJob", String.valueOf(shouldIncludePartial))).andExpect(status().isPartialContent()); + this.mockMvc.perform(get("/irs/jobs/" + jobId).queryParam("returnUncompletedJob", String.valueOf(shouldNotIncludePartial))).andExpect(status().isPartialContent()); + } + + @Test + @WithMockUser(authorities = "view_irs") + void shouldReturnOkWhenJobCompleted() throws Exception { + final Jobs completedJob = Jobs.builder().job(Job.builder().id(jobId).state(JobState.COMPLETED).build()).build(); + final boolean shouldIncludePartial = Boolean.TRUE; + final boolean shouldNotIncludePartial = Boolean.FALSE; + + when(authorizationService.verifyBpn()).thenReturn(Boolean.TRUE); + when(this.service.getJobForJobId(eq(jobId), anyBoolean())).thenReturn(completedJob); + + this.mockMvc.perform(get("/irs/jobs/" + jobId).queryParam("returnUncompletedJob", String.valueOf(shouldIncludePartial))).andExpect(status().isOk()); + this.mockMvc.perform(get("/irs/jobs/" + jobId).queryParam("returnUncompletedJob", String.valueOf(shouldNotIncludePartial))).andExpect(status().isOk()); + } + } \ No newline at end of file From c2f4b2760792dad5d52a1d5876da7ecb794a8419 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Wed, 15 Nov 2023 12:43:05 +0100 Subject: [PATCH 36/54] feat(impl):[TRI-279] fix test --- docs/src/api/irs-api.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml index 1b620bfa35..3c82f823d7 100644 --- a/docs/src/api/irs-api.yaml +++ b/docs/src/api/irs-api.yaml @@ -362,8 +362,8 @@ paths: format: uuid maxLength: 36 minLength: 36 - - description: " Return job with current processed item graph. \ - \ Return job with item graph if job is in state , otherwise job." + - description: "\\ Return job with current processed item graph. \\ + Return job with item graph if job is in state COMPLETED, otherwise job." in: query name: returnUncompletedJob required: false From 34370b247cdd3469fcaec1d7936b1dc7657c21df Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Wed, 15 Nov 2023 14:03:24 +0100 Subject: [PATCH 37/54] feat(irs-api):[#246] Changed hops incrementation pattern --- .../ess/service/EssRecursiveNotificationHandler.java | 11 ++++++----- .../eclipse/tractusx/irs/ess/service/EssService.java | 2 +- .../InvestigationJobProcessingEventListener.java | 7 ++++--- .../service/EssRecursiveNotificationHandlerTest.java | 7 ++++--- .../InvestigationJobProcessingEventListenerTest.java | 6 ++++-- .../notification/ResponseNotificationContent.java | 4 +--- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java index 8b4cce1d6e..041899d752 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java @@ -48,7 +48,8 @@ public class EssRecursiveNotificationHandler { private final BpnInvestigationJobCache bpnInvestigationJobCache; private final EdcNotificationSender edcNotificationSender; - /* package */ void handleNotification(final UUID finishedJobId, final SupplyChainImpacted supplyChainImpacted, final String bpn) { + /* package */ void handleNotification(final UUID finishedJobId, final SupplyChainImpacted supplyChainImpacted, final String bpn, + final Integer hops) { final Optional relatedJobsId = relatedInvestigationJobsCache.findByRecursiveRelatedJobId( finishedJobId); @@ -56,20 +57,20 @@ public class EssRecursiveNotificationHandler { relatedJobsId.ifPresentOrElse(relatedJobs -> { if (SupplyChainImpacted.YES.equals(supplyChainImpacted)) { log.debug("SupplyChain is impacted. Sending notification back to requestor."); - edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, FIRST_HOP, bpn); + edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, hops, bpn); relatedInvestigationJobsCache.remove( relatedJobs.originalNotification().getHeader().getNotificationId()); } else { log.debug( "SupplyChainImpacted in state '{}'. Waiting for Jobs to complete to send notification back to requestor.", supplyChainImpacted); - sendNotificationAfterAllCompleted(relatedJobs, bpn); + sendNotificationAfterAllCompleted(relatedJobs, bpn, hops); } }, () -> log.debug("No RelatedInvestigationJob found for id '{}'.", finishedJobId)); } private void sendNotificationAfterAllCompleted(final RelatedInvestigationJobs relatedInvestigationJobs, - final String bpn) { + final String bpn, final Integer hops) { final List allInvestigationJobs = relatedInvestigationJobs.recursiveRelatedJobIds() .stream() .map(bpnInvestigationJobCache::findByJobId) @@ -82,7 +83,7 @@ private void sendNotificationAfterAllCompleted(final RelatedInvestigationJobs re .reduce(SupplyChainImpacted.NO, SupplyChainImpacted::or); - edcNotificationSender.sendEdcNotification(relatedInvestigationJobs.originalNotification(), finalResult, getMinHops(allInvestigationJobs), bpn); + edcNotificationSender.sendEdcNotification(relatedInvestigationJobs.originalNotification(), finalResult, hops, bpn); } } diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 934c16efc0..5a71931b08 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -129,7 +129,7 @@ public void handleNotificationCallback(final EdcNotification Date: Wed, 15 Nov 2023 14:45:58 +0100 Subject: [PATCH 38/54] chore(docs):[253] added known knows to CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0635986e9d..61210bc21b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added 'hops' parameter to SupplyChainImpacted Aspect model - contains relative distance in the supply chain - Added `impactedSuppliersOnFirstTier` parameter to Supply SupplyChainImpacted Aspect model - contains information of first level supply chain impacted +### Known knowns +- [#253] Cancelation of order jobs is not working stable + ## [4.0.0] - 2023-10-27 ### Added - Introduced new API endpoint to register ESS Jobs in Batch - POST {{IRS_HOST}}/irs/ess/orders From ec62c765ecc2d9d51b27f115e1234fafeca24ab3 Mon Sep 17 00:00:00 2001 From: Jaro Hartmann Date: Wed, 15 Nov 2023 16:33:49 +0100 Subject: [PATCH 39/54] chore(charts): Fix healthcheck template --- charts/irs-helm/templates/configmap-spring-app-config.yaml | 4 ++-- charts/irs-helm/values.yaml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/charts/irs-helm/templates/configmap-spring-app-config.yaml b/charts/irs-helm/templates/configmap-spring-app-config.yaml index 344182606c..fbc0d8b35f 100644 --- a/charts/irs-helm/templates/configmap-spring-app-config.yaml +++ b/charts/irs-helm/templates/configmap-spring-app-config.yaml @@ -135,9 +135,9 @@ data: management: health: dependencies: - enabled: {{ tpl (.Values.management.health.dependencies.enabled | default "false") . | quote }} + enabled: {{ .Values.management.health.dependencies.enabled | default false }} urls: - {{- tpl (toYaml .Values.management.health.dependencies.urls) . | nindent 10 }} + {{- tpl (toYaml .Values.management.health.dependencies.urls) . | nindent 12 }} {{- end }} {{- end }} diff --git a/charts/irs-helm/values.yaml b/charts/irs-helm/values.yaml index d3fc3421ab..2a8c20bb1a 100644 --- a/charts/irs-helm/values.yaml +++ b/charts/irs-helm/values.yaml @@ -113,7 +113,8 @@ management: health: dependencies: enabled: false # Flag to determine if external service healthcheck endpoints should be checked - urls: {} # Map of services with corresponding healthcheck endpoint url's, example service_name: http://service_name_host.com/health + urls: {} # Map of services with corresponding healthcheck endpoint url's. Example: + # service_name: http://service_name_host.com/health digitalTwinRegistry: type: decentral # The type of DTR. This can be either "central" or "decentral". If "decentral", descriptorEndpoint, shellLookupEndpoint and oAuthClientId is not required. From 29837db1bedb3d0f3ef61726f4e224489b183518 Mon Sep 17 00:00:00 2001 From: Jaro Hartmann Date: Wed, 15 Nov 2023 16:35:19 +0100 Subject: [PATCH 40/54] chore(docs): Update CHANGELOG.md --- charts/irs-helm/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/charts/irs-helm/CHANGELOG.md b/charts/irs-helm/CHANGELOG.md index 3b49b76f00..a00af20634 100644 --- a/charts/irs-helm/CHANGELOG.md +++ b/charts/irs-helm/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Fixed +- Fixed templating for `management.health.dependencies` ## [6.10.0] ### Changed From 8c8650ffd9e4307d1c9a0a39391e72267f2c5503 Mon Sep 17 00:00:00 2001 From: mk Date: Thu, 16 Nov 2023 08:55:28 +0100 Subject: [PATCH 41/54] fix(document):[#204] fix headings of documentation --- .../ess-top-down/ess-top-down.adoc | 20 +++++++++---------- docs/src/docs/arc42/runtime-view/full.adoc | 1 - 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/src/docs/arc42/runtime-view/ess-top-down/ess-top-down.adoc b/docs/src/docs/arc42/runtime-view/ess-top-down/ess-top-down.adoc index 5062d1b797..d2ab5e630d 100644 --- a/docs/src/docs/arc42/runtime-view/ess-top-down/ess-top-down.adoc +++ b/docs/src/docs/arc42/runtime-view/ess-top-down/ess-top-down.adoc @@ -94,45 +94,45 @@ In case at least one "YES" is received, the process step 3 ends == Application Functionality Overview -== Register an Ess-Investigation-Order +=== Register an Ess-Investigation-Order [plantuml,target=submodel-processing,format=svg] .... include::../../../../uml-diagrams/runtime-view/use-case-ess-top-down/1_ess-top-down-sequence-highlevel.puml[] .... -== 1. Client Request +==== 1. Client Request The _Client App (Script)_ initiates a request to the IRS (Item Relationship Service) by sending a GET request for shell lookup based on a specific BPN (Business Partner Number). -== 2. Shell Lookup +==== 2. Shell Lookup IRS, along with other services like DiscoveryFinder, EDCDiscoveryService, and Digital Twin Registry, collaborates to look up shells for the given BPN, returning an array of AAS identifiers. -== 3. AAS Descriptor Retrieval +==== 3. AAS Descriptor Retrieval For each AAS identifier, the client requests the IRS for the corresponding shell descriptors, adding them to a collection. -== 4. Filtering AAS +==== 4. Filtering AAS The _Client App (Script)_ filters the AAS collection for SubmodelDescriptors marked _asPlanned_, based on certain criteria. -== 5. Incident Registration +==== 5. Incident Registration The client then initiates an IRS incident registration by sending a POST request with specific parameters, including bomLifecycle and callback URL. -== 6. Incident Handling Loop +==== 6. Incident Handling Loop IRS proceeds to handle the incident by iterating through AAS identifiers, extracting child CXIds, and performing checks on associated data. -== 7. Data Validation +==== 7. Data Validation The system checks the validity period of the received data and, if valid, proceeds to extract additional information. -== 8. Incident Response +==== 8. Incident Response If certain conditions are met (e.g., incidentBpns contain catenaXsiteId), the system responds to the client indicating a part-chain infection. -== 9. Notification Handling +==== 9. Notification Handling Otherwise, the system sends an ess-request notification to the next tier level IRS, and after processing the request on the next tier level, receives an ess-response notification. diff --git a/docs/src/docs/arc42/runtime-view/full.adoc b/docs/src/docs/arc42/runtime-view/full.adoc index 678450e74d..21aa1e6b2b 100644 --- a/docs/src/docs/arc42/runtime-view/full.adoc +++ b/docs/src/docs/arc42/runtime-view/full.adoc @@ -17,7 +17,6 @@ include::irs-iterative/scenario-4.adoc[leveloffset=+1] This section covers the main processes of the IRS in a recursive scenario in a network. This recursive scenario is illustrated using the various use cases realized in the scenario. -=== Use Case: ESS (Environmental and Social Standards) Top-Down approach include::ess-top-down/ess-top-down.adoc[leveloffset=+1] include::ess-top-down/ess-top-down-scenario-1.adoc[leveloffset=+1] From 214f2919cd4d715b3e3f3458f812446639de83be Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Thu, 16 Nov 2023 12:43:47 +0100 Subject: [PATCH 42/54] feat(irs-api):[#246] First level supply chain changed to show only lowest level of hops, code clean up, added test --- docs/src/api/irs-api.yaml | 2 +- .../irs/ess/service/BpnInvestigationJob.java | 60 +++++++++--------- .../ess/service/EdcNotificationSender.java | 2 +- .../EssRecursiveNotificationHandler.java | 27 +++----- .../tractusx/irs/ess/service/EssService.java | 4 +- ...vestigationJobProcessingEventListener.java | 20 +++--- .../service/SupplyChainImpactedAspect.java | 4 +- .../irs/ess/service/EssServiceTest.java | 63 ++++++++++++------- .../ResponseNotificationContent.java | 2 +- .../tractusx/irs/component/Notification.java | 2 +- 10 files changed, 94 insertions(+), 92 deletions(-) diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml index 984d1be77b..dce6586307 100644 --- a/docs/src/api/irs-api.yaml +++ b/docs/src/api/irs-api.yaml @@ -2524,7 +2524,7 @@ components: hops: type: integer format: int32 - parentBpn: + bpn: type: string result: type: string diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java index ef3682493e..6ef37b2514 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/BpnInvestigationJob.java @@ -27,9 +27,9 @@ import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Optional; -import java.util.Set; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -65,14 +65,13 @@ public BpnInvestigationJob(final Jobs jobSnapshot, final List incidentBp this(jobSnapshot, incidentBpns, new ArrayList<>(), new ArrayList<>(), JobState.RUNNING); } - public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain, - final String bpn) { + public BpnInvestigationJob update(final Jobs jobSnapshot, final SupplyChainImpacted newSupplyChain) { final Optional previousSupplyChain = getSupplyChainImpacted(); final SupplyChainImpacted supplyChainImpacted = previousSupplyChain.map( prevSupplyChain -> prevSupplyChain.or(newSupplyChain)).orElse(newSupplyChain); - this.jobSnapshot = extendJobWithSupplyChainSubmodel(jobSnapshot, supplyChainImpacted, bpn); + this.jobSnapshot = extendJobWithSupplyChainSubmodel(jobSnapshot, supplyChainImpacted); this.jobSnapshot = extendSummary(this.jobSnapshot); this.jobSnapshot = updateLastModified(this.jobSnapshot, ZonedDateTime.now(ZoneOffset.UTC)); return this; @@ -85,21 +84,21 @@ public BpnInvestigationJob withUnansweredNotifications(final List public BpnInvestigationJob withAnsweredNotification( final EdcNotification notification) { - final Optional parentBpn = getParentBpn(notification); + final Optional bpn = getChildBpn(notification); removeFromUnansweredNotification(notification); - notification.getContent().setParentBpn(parentBpn.orElse(null)); + notification.getContent().setBpn(bpn.orElse(null)); notification.getContent().incrementHops(); this.answeredNotifications.add(notification); return this; } - private Optional getParentBpn(final EdcNotification notification) { + private Optional getChildBpn(final EdcNotification notification) { return this.unansweredNotifications.stream() .filter(unansweredNotification -> unansweredNotification.notificationId() .equals(notification.getHeader() .getOriginalNotificationId())) - .map(Notification::bpn) + .map(Notification::childBpn) .findAny(); } @@ -125,40 +124,41 @@ public BpnInvestigationJob complete() { .findFirst(); } - private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyChainImpacted supplyChainImpacted, - final String bpn) { - log.debug(bpn); + private Jobs extendJobWithSupplyChainSubmodel(final Jobs irsJob, final SupplyChainImpacted supplyChainImpacted) { final SupplyChainImpactedAspect.SupplyChainImpactedAspectBuilder supplyChainImpactedAspectBuilder = SupplyChainImpactedAspect.builder() .supplyChainImpacted( supplyChainImpacted); if (getUnansweredNotifications().isEmpty()) { - final List incidentWithMinHopsValue = getAnsweredNotifications().stream() - .map(EdcNotification::getContent) - .filter(ResponseNotificationContent::thereIsIncident) - .toList(); - - final List suppliersFirstLevel = incidentWithMinHopsValue.stream() - .map(impacted -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel( - impacted.getParentBpn(), - impacted.getHops())) - .toList(); - - supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier(Set.copyOf(suppliersFirstLevel)); + final Optional impactedSupplierWithLowestHopsNumber = getImpactedSupplierWithLowestHopsNumber(); + supplyChainImpactedAspectBuilder.impactedSuppliersOnFirstTier( + impactedSupplierWithLowestHopsNumber.orElse(null)); } - final Submodel supplyChainImpactedSubmodel = Submodel.builder() - .aspectType(SUPPLY_CHAIN_ASPECT_TYPE) - .payload(new JsonUtil().asMap( - supplyChainImpactedAspectBuilder.build())) - .build(); - return irsJob.toBuilder() .clearSubmodels() - .submodels(Collections.singletonList(supplyChainImpactedSubmodel)) + .submodels(Collections.singletonList( + createSupplyChainImpactedSubmodel(supplyChainImpactedAspectBuilder))) .build(); } + private Optional getImpactedSupplierWithLowestHopsNumber() { + return getAnsweredNotifications().stream() + .map(EdcNotification::getContent) + .filter(ResponseNotificationContent::thereIsIncident) + .min(Comparator.comparing(ResponseNotificationContent::getHops)) + .map(impacted -> new SupplyChainImpactedAspect.ImpactedSupplierFirstLevel( + impacted.getBpn(), impacted.getHops())); + } + + private static Submodel createSupplyChainImpactedSubmodel( + final SupplyChainImpactedAspect.SupplyChainImpactedAspectBuilder supplyChainImpactedAspectBuilder) { + return Submodel.builder() + .aspectType(SUPPLY_CHAIN_ASPECT_TYPE) + .payload(new JsonUtil().asMap(supplyChainImpactedAspectBuilder.build())) + .build(); + } + private Jobs updateLastModified(final Jobs irsJob, final ZonedDateTime lastModifiedOn) { final Job job = irsJob.getJob().toBuilder().completedOn(lastModifiedOn).lastModifiedOn(lastModifiedOn).build(); return irsJob.toBuilder().job(job).build(); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java index 3195b71d20..78373abcbb 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EdcNotificationSender.java @@ -70,7 +70,7 @@ public void sendEdcNotification(final EdcNotification responseNotification = edcRequest(notificationId, originalNotificationId, essLocalEdcEndpoint, localBpn, recipientBpn, notificationContent); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java index 041899d752..26f902ab28 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssRecursiveNotificationHandler.java @@ -23,15 +23,12 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.ess.service; -import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotification; -import org.eclipse.tractusx.irs.edc.client.model.notification.ResponseNotificationContent; import org.springframework.stereotype.Service; /** @@ -42,14 +39,12 @@ @Slf4j public class EssRecursiveNotificationHandler { - private static final Integer FIRST_HOP = 0; - private final RelatedInvestigationJobsCache relatedInvestigationJobsCache; private final BpnInvestigationJobCache bpnInvestigationJobCache; private final EdcNotificationSender edcNotificationSender; - /* package */ void handleNotification(final UUID finishedJobId, final SupplyChainImpacted supplyChainImpacted, final String bpn, - final Integer hops) { + /* package */ void handleNotification(final UUID finishedJobId, final SupplyChainImpacted supplyChainImpacted, + final String bpn, final Integer hops) { final Optional relatedJobsId = relatedInvestigationJobsCache.findByRecursiveRelatedJobId( finishedJobId); @@ -57,7 +52,8 @@ public class EssRecursiveNotificationHandler { relatedJobsId.ifPresentOrElse(relatedJobs -> { if (SupplyChainImpacted.YES.equals(supplyChainImpacted)) { log.debug("SupplyChain is impacted. Sending notification back to requestor."); - edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, hops, bpn); + edcNotificationSender.sendEdcNotification(relatedJobs.originalNotification(), supplyChainImpacted, hops, + bpn); relatedInvestigationJobsCache.remove( relatedJobs.originalNotification().getHeader().getNotificationId()); } else { @@ -76,6 +72,7 @@ private void sendNotificationAfterAllCompleted(final RelatedInvestigationJobs re .map(bpnInvestigationJobCache::findByJobId) .flatMap(Optional::stream) .toList(); + if (checkAllFinished(allInvestigationJobs)) { final SupplyChainImpacted finalResult = allInvestigationJobs.stream() .map(BpnInvestigationJob::getSupplyChainImpacted) @@ -83,21 +80,11 @@ private void sendNotificationAfterAllCompleted(final RelatedInvestigationJobs re .reduce(SupplyChainImpacted.NO, SupplyChainImpacted::or); - edcNotificationSender.sendEdcNotification(relatedInvestigationJobs.originalNotification(), finalResult, hops, bpn); + edcNotificationSender.sendEdcNotification(relatedInvestigationJobs.originalNotification(), finalResult, + hops, bpn); } } - private Integer getMinHops(final List allInvestigationJobs) { - return allInvestigationJobs - .stream() - .flatMap(investigationJobs -> investigationJobs.getAnsweredNotifications().stream()) - .map(EdcNotification::getContent) - .filter(ResponseNotificationContent::thereIsIncident) - .min(Comparator.comparing(ResponseNotificationContent::getHops)) - .map(ResponseNotificationContent::getHops) - .orElse(FIRST_HOP); - } - private boolean checkAllFinished(final List allInvestigationJobs) { return allInvestigationJobs.stream() .allMatch(bpnInvestigationJob -> bpnInvestigationJob.getSupplyChainImpacted() diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java index 5a71931b08..e260de0ccb 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/EssService.java @@ -127,9 +127,9 @@ public void handleNotificationCallback(final EdcNotification mockRecursiveEdcAssets; private final EssRecursiveNotificationHandler recursiveNotificationHandler; + private static final int FIRST_HOP = 0; /* package */ InvestigationJobProcessingEventListener(final IrsItemGraphQueryService irsItemGraphQueryService, final ConnectorEndpointsService connectorEndpointsService, final EdcSubmodelFacade edcSubmodelFacade, @@ -111,14 +112,14 @@ public void handleJobProcessingFinishedEvent(final JobProcessingFinishedEvent jo completedJobId); final BpnInvestigationJob investigationJobUpdate = investigationJob.update( - investigationResult.completedJob(), investigationResult.supplyChainImpacted(), job.getJobParameter().getBpn()); + investigationResult.completedJob(), investigationResult.supplyChainImpacted()); if (leafNodeIsReached(investigationResult.completedJob()) || supplyChainIsImpacted( investigationResult.supplyChainImpacted())) { bpnInvestigationJobCache.store(completedJobId, investigationJobUpdate.complete()); recursiveNotificationHandler.handleNotification(investigationJob.getJobSnapshot().getJob().getId(), investigationResult.supplyChainImpacted(), job.getJobParameter().getBpn(), - 0); + FIRST_HOP); } else { triggerInvestigationOnNextLevel(investigationResult.completedJob(), investigationJobUpdate, job.getJobParameter().getBpn()); bpnInvestigationJobCache.store(completedJobId, investigationJobUpdate); @@ -155,8 +156,9 @@ private void triggerInvestigationOnNextLevel(final Jobs completedJob, log.debug("Triggering investigation on the next level."); if (anyBpnIsMissingFromRelationship(completedJob)) { log.error("One or more Relationship items did not contain a BPN."); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, jobBpn); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); } + // Map> final Map> bpns = getBPNsFromRelationships(completedJob.getRelationships()); log.debug("Extracted BPNs '{}'", bpns); @@ -171,14 +173,14 @@ private void triggerInvestigationOnNextLevel(final Jobs completedJob, log.debug("BPNs '{}' could not be resolved to an EDC address using DiscoveryService.", unresolvedBPNs); log.info("Some EDC addresses could not be resolved with DiscoveryService. " + "Updating SupplyChainImpacted to {}", SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, jobBpn); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); recursiveNotificationHandler.handleNotification(investigationJobUpdate.getJobSnapshot().getJob().getId(), - SupplyChainImpacted.UNKNOWN, jobBpn, 0); + SupplyChainImpacted.UNKNOWN, jobBpn, FIRST_HOP); } else if (resolvedBPNs.isEmpty()) { log.info("No BPNs could not be found. Updating SupplyChainImpacted to {}", SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, jobBpn); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); recursiveNotificationHandler.handleNotification(investigationJobUpdate.getJobSnapshot().getJob().getId(), - SupplyChainImpacted.UNKNOWN, jobBpn, 0); + SupplyChainImpacted.UNKNOWN, jobBpn, FIRST_HOP); } else { log.debug("Sending notification for BPNs '{}'", bpns); sendNotifications(completedJob, investigationJobUpdate, bpns); @@ -192,7 +194,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo if (edcBaseUrl.isEmpty()) { log.warn("No EDC URL found for BPN '{}'. Setting investigation result to '{}'", bpn, SupplyChainImpacted.UNKNOWN); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, bpn); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); } edcBaseUrl.forEach(url -> { try { @@ -201,7 +203,7 @@ private void sendNotifications(final Jobs completedJob, final BpnInvestigationJo investigationJobUpdate.withUnansweredNotifications(Collections.singletonList(new Notification(notificationId, bpn))); } catch (final EdcClientException e) { log.error("Exception during sending EDC notification.", e); - investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN, bpn); + investigationJobUpdate.update(completedJob, SupplyChainImpacted.UNKNOWN); } }); }); diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java index 3f20e186cb..633f4a96c0 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/ess/service/SupplyChainImpactedAspect.java @@ -23,8 +23,6 @@ ********************************************************************************/ package org.eclipse.tractusx.irs.ess.service; -import java.util.Set; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -41,7 +39,7 @@ @Builder public class SupplyChainImpactedAspect { private SupplyChainImpacted supplyChainImpacted; - private Set impactedSuppliersOnFirstTier; + private ImpactedSupplierFirstLevel impactedSuppliersOnFirstTier; /** * BPNLs on first tier level where infection was detected diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java index c802be5025..c5eab5527d 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/ess/service/EssServiceTest.java @@ -118,7 +118,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { final UUID jobId = UUID.randomUUID(); final String owner = securityHelperService.getClientIdClaim(); - final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).parentBpn("bot-impacted-bpn").build(); + final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).bpn("bot-impacted-bpn").build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() .notificationId(notificationId) .originalNotificationId(notificationId) @@ -127,7 +127,7 @@ void shouldUpdateJobSnapshotIfNotificationFound() { .header(header1) .content(resultNo) .build(); - final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").hops(0).parentBpn("impacted-bpn").build(); + final ResponseNotificationContent resultYes = ResponseNotificationContent.builder().result("Yes").hops(0).bpn("impacted-bpn").build(); final EdcNotificationHeader header2 = EdcNotificationHeader.builder() .notificationId(notificationId) .originalNotificationId(notificationId2) @@ -163,61 +163,76 @@ void shouldUpdateJobSnapshotIfNotificationFound() { final Map supplyChainPayload = job2.getJobSnapshot().getSubmodels().get(0).getPayload(); final SupplyChainImpactedAspect supplyChainImpactedAspect = new ObjectMapper().convertValue(supplyChainPayload, SupplyChainImpactedAspect.class); assertThat(supplyChainImpactedAspect.getSupplyChainImpacted()).isEqualTo(SupplyChainImpacted.YES); - assertThat(supplyChainImpactedAspect.getImpactedSuppliersOnFirstTier()).isNotEmpty(); - assertThat(supplyChainImpactedAspect.getImpactedSuppliersOnFirstTier().stream().findAny().get().getHops()).isPositive(); + assertThat(supplyChainImpactedAspect.getImpactedSuppliersOnFirstTier()).isNotNull(); + assertThat(supplyChainImpactedAspect.getImpactedSuppliersOnFirstTier().getHops()).isPositive(); assertThat(job.getState()).isEqualTo(JobState.COMPLETED); } @Test - void shouldReturnFirstImpactedSupplierWhenNotificationFound() { + void shouldReturnCorrectFirstLevelImpactedSupplierBpnAndHopsNumberWhenImpactedSupplierIsOnThirdLevel() { // given final String notificationId = UUID.randomUUID().toString(); final String notificationId2 = UUID.randomUUID().toString(); final UUID jobId = UUID.randomUUID(); + final UUID jobId2 = UUID.randomUUID(); + final UUID jobId3 = UUID.randomUUID(); final String owner = securityHelperService.getClientIdClaim(); final String bpnLevel0 = "bpn-level-0"; final String bpnLevel1 = "bpn-level-1"; + final String bpnLevel2 = "bpn-level-2"; - final ResponseNotificationContent responseNotificationContentLevel1 = ResponseNotificationContent.builder().result("No").hops(0).parentBpn(bpnLevel0).build(); + final ResponseNotificationContent responseNotificationContentLevel1 = ResponseNotificationContent.builder().result("Yes").hops(1).bpn(bpnLevel0).build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() .notificationId(notificationId) .originalNotificationId(notificationId) .build(); final EdcNotification responseNotificationLevel1 = EdcNotification.builder() - .header(header1) - .content(responseNotificationContentLevel1) - .build(); - + .header(header1) + .content(responseNotificationContentLevel1) + .build(); - final ResponseNotificationContent impactedResponseNotificationContent = ResponseNotificationContent.builder().result("Yes").hops(0).parentBpn(bpnLevel1).build(); + final ResponseNotificationContent responseNotificationContent2 = ResponseNotificationContent.builder().result("Yes").hops(0).bpn(bpnLevel1).build(); final EdcNotificationHeader header2 = EdcNotificationHeader.builder() .notificationId(notificationId) .originalNotificationId(notificationId2) .build(); final EdcNotification responseNotificationLevel2 = EdcNotification.builder() - .header(header2) - .content(impactedResponseNotificationContent) - .build(); + .header(header2) + .content(responseNotificationContent2) + .build(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob( Jobs.builder().job(Job.builder().id(jobId).owner(owner).build()).build(), - new ArrayList<>()).withUnansweredNotifications(List.of(new Notification(notificationId, bpnLevel0), new Notification(notificationId2, bpnLevel1))); + new ArrayList<>()).withUnansweredNotifications(List.of(new Notification(notificationId, bpnLevel1))); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); + final BpnInvestigationJob bpnInvestigationJob2 = new BpnInvestigationJob( + Jobs.builder().job(Job.builder().id(jobId2).owner(owner).build()).build(), + new ArrayList<>()).withUnansweredNotifications(List.of(new Notification(notificationId2, bpnLevel2))); + bpnInvestigationJobCache.store(jobId2, bpnInvestigationJob2); + + final BpnInvestigationJob bpnInvestigationJob3 = new BpnInvestigationJob( + Jobs.builder().job(Job.builder().id(jobId3).owner(owner).build()).build(), + new ArrayList<>()); + bpnInvestigationJobCache.store(jobId3, bpnInvestigationJob3); + // when - essService.handleNotificationCallback(responseNotificationLevel1); essService.handleNotificationCallback(responseNotificationLevel2); + essService.handleNotificationCallback(responseNotificationLevel1); // then - final BpnInvestigationJob job2 = bpnInvestigationJobCache.findAll().get(0); - final List> supplyChainImpacted2 = (List>) job2.getJobSnapshot() - .getSubmodels() - .get(0) - .getPayload() - .get("impactedSuppliersOnFirstTier"); + final Optional investigationJobLevel1 = bpnInvestigationJobCache.findByJobId(jobId); + assertThat(investigationJobLevel1).isPresent(); + + final Map supplyChainImpacted2 = (Map) investigationJobLevel1.get().getJobSnapshot() + .getSubmodels() + .get(0) + .getPayload() + .get("impactedSuppliersOnFirstTier"); - assertThat(supplyChainImpacted2.get(0).get("bpnl").toString()).isEqualTo(bpnLevel1); + assertThat(supplyChainImpacted2.get("bpnl").toString()).isEqualTo(bpnLevel1); + assertThat(supplyChainImpacted2.get("hops").toString()).isEqualTo("2"); } @Test @@ -286,7 +301,7 @@ void shouldCompleteJobIfFinalNotificationWasReceived() { final Jobs jobSnapshot = job(jobId, owner); final String notificationId = UUID.randomUUID().toString(); final BpnInvestigationJob bpnInvestigationJob = new BpnInvestigationJob(jobSnapshot, null).update(jobSnapshot, - SupplyChainImpacted.NO, "bpn").withUnansweredNotifications(List.of(new Notification(notificationId, "bpn"))); + SupplyChainImpacted.NO).withUnansweredNotifications(List.of(new Notification(notificationId, "bpn"))); bpnInvestigationJobCache.store(jobId, bpnInvestigationJob); final ResponseNotificationContent resultNo = ResponseNotificationContent.builder().result("No").hops(0).build(); final EdcNotificationHeader header1 = EdcNotificationHeader.builder() diff --git a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java index 08438d293f..e160dd91c0 100644 --- a/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java +++ b/irs-edc-client/src/main/java/org/eclipse/tractusx/irs/edc/client/model/notification/ResponseNotificationContent.java @@ -39,7 +39,7 @@ public class ResponseNotificationContent implements NotificationContent { private final String result; private Integer hops; - private String parentBpn; + private String bpn; /** * Incrementing hops value diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java index 9641d1e37c..a03c47bdd6 100644 --- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java +++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Notification.java @@ -26,5 +26,5 @@ /** * Response notification body containing notificationId and parent bpn */ -public record Notification(String notificationId, String bpn) { +public record Notification(String notificationId, String childBpn) { } From 5ebc0c9d84b955ab41e27b549d98bb363e5dd4f9 Mon Sep 17 00:00:00 2001 From: ds-alexander-bulgakov Date: Thu, 16 Nov 2023 13:33:13 +0100 Subject: [PATCH 43/54] feat(impl):[279] adjusted and added tavern test for http code 206 --- .../api-tests/irs-api-tests.tavern.yaml | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/local/testing/api-tests/irs-api-tests.tavern.yaml b/local/testing/api-tests/irs-api-tests.tavern.yaml index d8127916c8..0b3c7ce37d 100644 --- a/local/testing/api-tests/irs-api-tests.tavern.yaml +++ b/local/testing/api-tests/irs-api-tests.tavern.yaml @@ -607,6 +607,58 @@ stages: --- +test_name: Make sure job with status RUNNING is responsed with http code 206 + +strict: + - headers:off + - json:off + +stages: + - name: create a job and check for success + request: + url: "{tavern.env_vars.IRS_HOST}/irs/jobs" + json: + key: + globalAssetId: "{tavern.env_vars.GLOBAL_ASSET_ID_AS_BUILT}" + bpn: "{tavern.env_vars.BPN_AS_BUILT}" + collectAspects: true + depth: 2 + aspects: + - SerialPart + direction: "downward" + method: POST + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 201 + headers: + content-type: application/json + save: + json: + job_id: id + + - name: verify running job is responsed with http code 206 + request: + url: "{tavern.env_vars.IRS_HOST}/irs/jobs/{job_id}" + params: + returnUncompletedJob: true + method: GET + headers: + content-type: application/json + $ext: + function: local.testing.api-tests.tavern_helpers:create_bearer_token + response: + status_code: 206 + json: + job: + state: RUNNING + + +--- + + test_name: Make sure job with submodels process with status COMPLETED with asPlanned-id strict: @@ -1275,7 +1327,7 @@ stages: $ext: function: local.testing.api-tests.tavern_helpers:create_bearer_token response: - status_code: 200 + status_code: 206 json: job: state: RUNNING From 871d0a61d74f7179dfcf867e04eb4036bafdc864 Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 16 Nov 2023 14:28:07 +0100 Subject: [PATCH 44/54] feat(impl):[TRI-201] cucumber --- .github/workflows/integration-test-DEV.yaml | 6 +++--- .github/workflows/integration-test-DIL.yaml | 2 +- .github/workflows/integration-test-INT.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/integration-test-DEV.yaml b/.github/workflows/integration-test-DEV.yaml index 689a647229..8fb3a551c2 100644 --- a/.github/workflows/integration-test-DEV.yaml +++ b/.github/workflows/integration-test-DEV.yaml @@ -23,9 +23,9 @@ jobs: trigger-integration-test: uses: ./.github/workflows/xray-cucumber-integration.yaml secrets: - keycloakTokenUrl: ${{ secrets.KEYCLOAK_OAUTH2_CLIENT_TOKEN_URI }} - clientId: ${{ secrets.KEYCLOAK_OAUTH2_CLIENT_ID }} - clientSecret: ${{ secrets.KEYCLOAK_OAUTH2_CLIENT_SECRET }} + oauth2TokenUrl: ${{ secrets.OAUTH2_CLIENT_TOKEN_URI }} + clientId: ${{ secrets.OAUTH2_CLIENT_ID }} + clientSecret: ${{ secrets.OAUTH2_CLIENT_SECRET }} jiraUser: ${{ secrets.ORG_IRS_JIRA_USERNAME }} jiraPassword: ${{ secrets.ORG_IRS_JIRA_PASSWORD }} with: diff --git a/.github/workflows/integration-test-DIL.yaml b/.github/workflows/integration-test-DIL.yaml index 30edcc77a2..501a816659 100644 --- a/.github/workflows/integration-test-DIL.yaml +++ b/.github/workflows/integration-test-DIL.yaml @@ -12,7 +12,7 @@ jobs: trigger-integration-test: uses: ./.github/workflows/xray-cucumber-integration.yaml secrets: - keycloakTokenUrl: ${{ secrets.KEYCLOAK_OAUTH2_CLIENT_TOKEN_URI }} + oauth2TokenUrl: ${{ secrets.OAUTH2_CLIENT_TOKEN_URI }} clientId: ${{ secrets.IRS_OAUTH2_CLIENT_ID_DIL }} clientSecret: ${{ secrets.IRS_OAUTH2_CLIENT_SECRET_DIL }} jiraUser: ${{ secrets.ORG_IRS_JIRA_USERNAME }} diff --git a/.github/workflows/integration-test-INT.yaml b/.github/workflows/integration-test-INT.yaml index 140bd54d00..bbe00c2634 100644 --- a/.github/workflows/integration-test-INT.yaml +++ b/.github/workflows/integration-test-INT.yaml @@ -7,7 +7,7 @@ jobs: trigger-integration-test: uses: ./.github/workflows/xray-cucumber-integration.yaml secrets: - keycloakTokenUrl: ${{ secrets.KEYCLOAK_OAUTH2_CLIENT_TOKEN_URI }} + oauth2TokenUrl: ${{ secrets.OAUTH2_CLIENT_TOKEN_URI }} clientId: ${{ secrets.ORG_IRS_OAUTH2_CLIENT_ID_INT }} clientSecret: ${{ secrets.ORG_IRS_OAUTH2_CLIENT_SECRET_INT }} jiraUser: ${{ secrets.ORG_IRS_JIRA_USERNAME }} From 8465ee8beb2f575eb791298546a347d13658ea6d Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 16 Nov 2023 14:31:16 +0100 Subject: [PATCH 45/54] feat(impl):[TRI-201] cucumber --- .github/workflows/xray-cucumber.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/xray-cucumber.yaml b/.github/workflows/xray-cucumber.yaml index 633e90f482..3b73158595 100644 --- a/.github/workflows/xray-cucumber.yaml +++ b/.github/workflows/xray-cucumber.yaml @@ -31,9 +31,9 @@ jobs: trigger-integration-test: uses: ./.github/workflows/xray-cucumber-integration.yaml secrets: - keycloakTokenUrl: ${{ secrets.KEYCLOAK_OAUTH2_CLIENT_TOKEN_URI }} - clientId: ${{ secrets.KEYCLOAK_OAUTH2_CLIENT_ID }} - clientSecret: ${{ secrets.KEYCLOAK_OAUTH2_CLIENT_SECRET }} + oauth2TokenUrl: ${{ secrets.OAUTH2_CLIENT_TOKEN_URI }} + clientId: ${{ secrets.OAUTH2_CLIENT_ID }} + clientSecret: ${{ secrets.OAUTH2_CLIENT_SECRET }} jiraUser: ${{ secrets.ORG_IRS_JIRA_USERNAME }} jiraPassword: ${{ secrets.ORG_IRS_JIRA_PASSWORD }} with: From 3a85574fd42fef7d7277d305aa8caf024130ea8b Mon Sep 17 00:00:00 2001 From: "Krzysztof Massalski (Extern)" Date: Thu, 16 Nov 2023 14:33:15 +0100 Subject: [PATCH 46/54] feat(impl):[TRI-201] cucumber --- docs/src/docs/security/security-assessment.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/docs/security/security-assessment.md b/docs/src/docs/security/security-assessment.md index a2bd28e658..cd83d1f730 100644 --- a/docs/src/docs/security/security-assessment.md +++ b/docs/src/docs/security/security-assessment.md @@ -13,7 +13,7 @@ System_Ext(EDC, "EDC") System_Ext(EDC-DS, "EDC Discovery Service") System_Ext(DF, "Discovery Finder") System_Ext(DTR, "Digital Twin Registry") -System_Ext(KC, "Keycloak") +System_Ext(OAuth2, "OAuth2") System_Ext(BPDM, "BPDM") System_Ext(SH, "Semantic Hub") @@ -46,7 +46,7 @@ Rel(IRS-App, EDC, "https, access token") Rel(IRS-App, EDC-DS, "Find decentral DTs, https, access token") Rel(IRS-App, DF, "Get EDC Discovery Service URL, https, access token") Rel(IRS-App, DTR, "https, access token") -Rel(IRS-App, KC, "https, clientID, clientSecret, Get tokens to access DTR") +Rel(IRS-App, OAuth2, "https, clientID, clientSecret, Get tokens to access DTR") Rel(IRS-App, BPDM, "https, access token, Get BPN") Rel(IRS-App, SH, "Get schemas to validate response from EDC, https, access token") From a995dc8f60cb6397cd0783f1c8d05a83065fff71 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Thu, 16 Nov 2023 16:31:53 +0100 Subject: [PATCH 47/54] feat(git):[#000] Updated git message check, added documentation --- CONTRIBUTING.md | 7 +++++-- local/development/commit-msg | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 19695b7258..54ed82c748 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,10 +64,13 @@ For more information on the tool and how to acquire the token, check https://git ### Commit messages The commit messages have to match a pattern in the form of: -``< type >(optional scope):[] < description >`` +``< type >(scope):[] < description >`` +where type is: `build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test` +and ticket id is optional Example: -``chore(api):[TRI-123] some text`` +``chore(api):[#123] some text`` +``feat(api): some text`` Detailed pattern can be found here: [commit-msg](local/development/commit-msg) diff --git a/local/development/commit-msg b/local/development/commit-msg index c254f038d5..59c99f5526 100644 --- a/local/development/commit-msg +++ b/local/development/commit-msg @@ -16,7 +16,7 @@ fi url="$(git remote get-url origin | sed 's/\.git/#commit-messages/')" # check semantic versioning scheme -if ! echo "$commitTitle" | grep -qE '^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)\([a-z0-9/-]+\)\:\[[#0-9]+\].*$'; then +if ! echo "$commitTitle" | grep -qE '^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)\([a-z0-9/-]+\)\:\[#[0-9]+\].*$'; then echo "Your commit title did not follow semantic versioning: $commitTitle" echo "Please see $url" exit 1 From 366cd1d6b0bbab69e18fb8b3481b1b89491532a3 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Thu, 16 Nov 2023 16:32:32 +0100 Subject: [PATCH 48/54] feat(git):[#000] corrected documentation --- CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54ed82c748..5124a66867 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,8 +65,7 @@ For more information on the tool and how to acquire the token, check https://git ### Commit messages The commit messages have to match a pattern in the form of: ``< type >(scope):[] < description >`` -where type is: `build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test` -and ticket id is optional +where type is: `build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test` Example: ``chore(api):[#123] some text`` From 7d64dd2249580f0ca46ecd4a12b195e66cce46d5 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Fri, 17 Nov 2023 13:17:46 +0100 Subject: [PATCH 49/54] chore(irs-api):[#000] chron value change for tests --- charts/irs-helm/values.yaml | 2 +- irs-api/src/main/resources/application.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/irs-helm/values.yaml b/charts/irs-helm/values.yaml index 573713e871..5359c66889 100644 --- a/charts/irs-helm/values.yaml +++ b/charts/irs-helm/values.yaml @@ -203,7 +203,7 @@ edc: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: PT24H # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache + cacheTTL: 86400000 # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache discovery: oAuthClientId: portal # ID of the OAuth2 client registration to use, see config spring.security.oauth2.client diff --git a/irs-api/src/main/resources/application.yml b/irs-api/src/main/resources/application.yml index cc5bf4150f..4b6bbe70eb 100644 --- a/irs-api/src/main/resources/application.yml +++ b/irs-api/src/main/resources/application.yml @@ -173,7 +173,7 @@ irs-edc-client: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: PT24H # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache + cacheTTL: 86400000 # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache digitalTwinRegistry: type: ${DIGITALTWINREGISTRY_TYPE:decentral} # The type of DTR. This can be either "central" or "decentral". If "decentral", descriptorEndpoint, shellLookupEndpoint and oAuthClientId is not required. From c5f9d7a17a00079f668d521818a6976407591130 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Fri, 17 Nov 2023 14:19:09 +0100 Subject: [PATCH 50/54] chore(irs-api):[#000] changed cache value to string and back to iso format --- charts/irs-helm/templates/configmap-spring-app-config.yaml | 2 +- charts/irs-helm/values.yaml | 2 +- irs-api/src/main/resources/application.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/charts/irs-helm/templates/configmap-spring-app-config.yaml b/charts/irs-helm/templates/configmap-spring-app-config.yaml index fbc0d8b35f..5c56bec786 100644 --- a/charts/irs-helm/templates/configmap-spring-app-config.yaml +++ b/charts/irs-helm/templates/configmap-spring-app-config.yaml @@ -115,7 +115,7 @@ data: rightOperand: {{ .rightOperand | quote }} {{- end }} connectorEndpointService: - cacheTTL: {{ .Values.edc.connectorEndpointService.cacheTTL | int64 }} + cacheTTL: {{ .Values.edc.connectorEndpointService.cacheTTL | quote }} ess: localBpn: {{ tpl (.Values.bpn | default "") . | quote }} localEdcEndpoint: {{ tpl (.Values.edc.provider.host | default "") . | quote }} diff --git a/charts/irs-helm/values.yaml b/charts/irs-helm/values.yaml index 5359c66889..573713e871 100644 --- a/charts/irs-helm/values.yaml +++ b/charts/irs-helm/values.yaml @@ -203,7 +203,7 @@ edc: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: 86400000 # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache + cacheTTL: PT24H # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache discovery: oAuthClientId: portal # ID of the OAuth2 client registration to use, see config spring.security.oauth2.client diff --git a/irs-api/src/main/resources/application.yml b/irs-api/src/main/resources/application.yml index 4b6bbe70eb..cc5bf4150f 100644 --- a/irs-api/src/main/resources/application.yml +++ b/irs-api/src/main/resources/application.yml @@ -173,7 +173,7 @@ irs-edc-client: operator: "eq" rightOperand: "active" connectorEndpointService: - cacheTTL: 86400000 # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache + cacheTTL: PT24H # Time to live for ConnectorEndpointService for fetchConnectorEndpoints method cache digitalTwinRegistry: type: ${DIGITALTWINREGISTRY_TYPE:decentral} # The type of DTR. This can be either "central" or "decentral". If "decentral", descriptorEndpoint, shellLookupEndpoint and oAuthClientId is not required. From d65f3678c310e2be0f57f4aba95fa9fd34d55537 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Fri, 17 Nov 2023 14:32:08 +0100 Subject: [PATCH 51/54] chore(irs-api):[#000] fixed CONTRIBUTING.md file --- CONTRIBUTING.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fc76d99c9d..6e35594c8a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,7 +69,6 @@ where type is: `build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test` Example: ``chore(api):[#123] some text`` -``feat(api): some text`` Detailed pattern can be found here: [commit-msg](local/development/commit-msg) From e334121fb13d7ca58b601d3798742b20f095a108 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Fri, 17 Nov 2023 14:40:55 +0100 Subject: [PATCH 52/54] chore(irs-api):fixed CONTRIBUTING.md file --- local/development/commit-msg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local/development/commit-msg b/local/development/commit-msg index 59c99f5526..b12c4a838e 100644 --- a/local/development/commit-msg +++ b/local/development/commit-msg @@ -16,7 +16,7 @@ fi url="$(git remote get-url origin | sed 's/\.git/#commit-messages/')" # check semantic versioning scheme -if ! echo "$commitTitle" | grep -qE '^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)\([a-z0-9/-]+\)\:\[#[0-9]+\].*$'; then +if ! echo "$commitTitle" | grep -qE '^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)\([a-z0-9/-]+\)\:(\[#[0-9]+\])?.*$'; then echo "Your commit title did not follow semantic versioning: $commitTitle" echo "Please see $url" exit 1 From 1e9ed380ffd983f2993f161d198662c100fded51 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Fri, 17 Nov 2023 14:43:14 +0100 Subject: [PATCH 53/54] chore(irs-api):fixed CONTRIBUTING.md file --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6e35594c8a..74a2048915 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,6 +69,7 @@ where type is: `build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test` Example: ``chore(api):[#123] some text`` +``chore(api): some text`` Detailed pattern can be found here: [commit-msg](local/development/commit-msg) From 2911aa2b8a6bf25f00f16a15270778d4ce6441f0 Mon Sep 17 00:00:00 2001 From: Pawel Sosnowski Date: Fri, 17 Nov 2023 16:06:29 +0100 Subject: [PATCH 54/54] chore(irs-api):[#210] Added documentation for cache in edc endpoint service --- docs/src/docs/administration/configuration.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/src/docs/administration/configuration.adoc b/docs/src/docs/administration/configuration.adoc index 41af8b1142..b556b525e1 100644 --- a/docs/src/docs/administration/configuration.adoc +++ b/docs/src/docs/administration/configuration.adoc @@ -74,6 +74,10 @@ The hostname where Grafana will be made available. The EDC consumer controlplane endpoint URL for data management, including the protocol. If left empty, this defaults to the internal endpoint of the controlplane provided by the irs-edc-consumer Helm chart. +==== +When IRS calls EDC Discovery Service to fetch endpoints for BPNL's there is a cache mechanism between them, to improve performance. +This parameter define how long cache is maintained before it is cleared. Data is in ISO 8601. + === Semantic Model Provisioning The IRS can retrieve semantic models in two ways: