From 269f5458dd0e69a1adbc8b47cb27cd7097dcf2d5 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Fri, 5 Jul 2024 12:46:16 +0200 Subject: [PATCH 01/13] feat(policy-api):[#750] cleanup --- .../irs/policystore/common/DateUtils.java | 47 +++++++++++ .../services/PolicyPagingService.java | 61 ++++++++++---- .../irs/policystore/common/DateUtilsTest.java | 67 +++++++++++++++ .../services/PolicyPagingServiceTest.java | 81 +++++++++++++++++++ 4 files changed, 242 insertions(+), 14 deletions(-) create mode 100644 irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java create mode 100644 irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/common/DateUtilsTest.java diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java new file mode 100644 index 000000000..bc2035751 --- /dev/null +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java @@ -0,0 +1,47 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +package org.eclipse.tractusx.irs.policystore.common; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +/** + * Date utilities. + */ +public class DateUtils { + + public static boolean isDateBefore(final OffsetDateTime dateTime, final String referenceDateString) { + return dateTime.isBefore(toOffsetDateTimeAtStartOfDay(referenceDateString)); + } + + public static boolean isDateAfter(final OffsetDateTime dateTime, final String referenceDateString) { + return dateTime.isAfter(toOffsetDateTimeAtEndOfDay(referenceDateString)); + } + + public static OffsetDateTime toOffsetDateTimeAtStartOfDay(final String dateString) { + return LocalDate.parse(dateString).atStartOfDay().atOffset(ZoneOffset.UTC); + } + + public static OffsetDateTime toOffsetDateTimeAtEndOfDay(final String dateString) { + return LocalDate.parse(dateString).atTime(LocalTime.MAX).atOffset(ZoneOffset.UTC); + } +} diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingService.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingService.java index fa7d89a4d..f11ce3fce 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingService.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingService.java @@ -24,9 +24,14 @@ import static org.eclipse.tractusx.irs.policystore.common.CommonConstants.PROPERTY_CREATED_ON; import static org.eclipse.tractusx.irs.policystore.common.CommonConstants.PROPERTY_POLICY_ID; import static org.eclipse.tractusx.irs.policystore.common.CommonConstants.PROPERTY_VALID_UNTIL; +import static org.eclipse.tractusx.irs.policystore.common.DateUtils.isDateAfter; +import static org.eclipse.tractusx.irs.policystore.common.DateUtils.isDateBefore; +import static org.eclipse.tractusx.irs.policystore.models.SearchCriteria.Operation.AFTER_LOCAL_DATE; +import static org.eclipse.tractusx.irs.policystore.models.SearchCriteria.Operation.BEFORE_LOCAL_DATE; import static org.eclipse.tractusx.irs.policystore.models.SearchCriteria.Operation.EQUALS; import static org.eclipse.tractusx.irs.policystore.models.SearchCriteria.Operation.STARTS_WITH; +import java.time.OffsetDateTime; import java.util.Comparator; import java.util.List; import java.util.Map; @@ -178,6 +183,7 @@ public Sort.Direction getSortDirection(final Pageable pageable, final String fie */ private static class PolicyFilterBuilder { + public static final String MSG_PROPERTY_ONLY_SUPPORTS_THE_FOLLOWING_OPERATIONS = "The property '%s' only supports the following operations: %s"; private final List> searchCriteriaList; /* package */ PolicyFilterBuilder(final List> searchCriteriaList) { @@ -195,24 +201,18 @@ private static class PolicyFilterBuilder { } private Predicate getPolicyPredicate(final SearchCriteria searchCriteria) { - if (PROPERTY_BPN.equalsIgnoreCase(searchCriteria.getProperty())) { return getBpnFilter(searchCriteria); } else if (PROPERTY_POLICY_ID.equalsIgnoreCase(searchCriteria.getProperty())) { return getPolicyIdFilter(searchCriteria); } else if (PROPERTY_ACTION.equalsIgnoreCase(searchCriteria.getProperty())) { return getActionFilter(searchCriteria); + } else if (PROPERTY_CREATED_ON.equalsIgnoreCase(searchCriteria.getProperty())) { + return getCreatedOnFilter(searchCriteria); + } else if (PROPERTY_VALID_UNTIL.equalsIgnoreCase(searchCriteria.getProperty())) { + return getValidUntilFilter(searchCriteria); } else { - final String notYetImplementedMessage = "Filtering by '%s' has not been implemented yet"; - if (PROPERTY_CREATED_ON.equalsIgnoreCase(searchCriteria.getProperty())) { - // TODO (mfischer): #750: implement createdOn filter incl. test - throw new IllegalArgumentException(notYetImplementedMessage.formatted(PROPERTY_CREATED_ON)); - } else if (PROPERTY_VALID_UNTIL.equalsIgnoreCase(searchCriteria.getProperty())) { - // TODO (mfischer): #750: implement validUntil filter incl. test - throw new IllegalArgumentException(notYetImplementedMessage.formatted(PROPERTY_VALID_UNTIL)); - } else { - throw new IllegalArgumentException("Not supported"); - } + throw new IllegalArgumentException("Not supported"); } } @@ -222,7 +222,7 @@ private Predicate getPolicyIdFilter(final SearchCriteria searc case STARTS_WITH -> p -> StringUtils.startsWithIgnoreCase(p.policy().getPolicyId(), (String) searchCriteria.getValue()); default -> throw new IllegalArgumentException( - "The property 'policyId' only supports the following operations: %s".formatted( + MSG_PROPERTY_ONLY_SUPPORTS_THE_FOLLOWING_OPERATIONS.formatted(searchCriteria.getProperty(), List.of(EQUALS, STARTS_WITH))); }; } @@ -232,7 +232,7 @@ private Predicate getBpnFilter(final SearchCriteria searchCrit case EQUALS -> p -> p.bpn().equalsIgnoreCase((String) searchCriteria.getValue()); case STARTS_WITH -> p -> StringUtils.startsWithIgnoreCase(p.bpn(), (String) searchCriteria.getValue()); default -> throw new IllegalArgumentException( - "The property 'BPN' only supports the following operations: %s".formatted( + MSG_PROPERTY_ONLY_SUPPORTS_THE_FOLLOWING_OPERATIONS.formatted(searchCriteria.getProperty(), List.of(EQUALS, STARTS_WITH))); }; } @@ -253,9 +253,42 @@ private Predicate getActionFilter(final SearchCriteria searchC }; } else { throw new IllegalArgumentException( - "The property 'action' only supports the following operations: %s".formatted(List.of(EQUALS))); + MSG_PROPERTY_ONLY_SUPPORTS_THE_FOLLOWING_OPERATIONS.formatted(searchCriteria.getProperty(), + List.of(EQUALS))); } } + + private Predicate getCreatedOnFilter(final SearchCriteria searchCriteria) { + return switch (searchCriteria.getOperation()) { + case BEFORE_LOCAL_DATE -> p -> { + final OffsetDateTime createdOn = p.policy().getCreatedOn(); + return isDateBefore(createdOn, searchCriteria.getValue().toString()); + }; + case AFTER_LOCAL_DATE -> p -> { + final OffsetDateTime createdOn = p.policy().getCreatedOn(); + return isDateAfter(createdOn, searchCriteria.getValue().toString()); + }; + default -> throw new IllegalArgumentException( + MSG_PROPERTY_ONLY_SUPPORTS_THE_FOLLOWING_OPERATIONS.formatted(searchCriteria.getProperty(), + List.of(BEFORE_LOCAL_DATE, AFTER_LOCAL_DATE))); + }; + } + + private Predicate getValidUntilFilter(final SearchCriteria searchCriteria) { + return switch (searchCriteria.getOperation()) { + case BEFORE_LOCAL_DATE -> p -> { + final OffsetDateTime createdOn = p.policy().getValidUntil(); + return isDateBefore(createdOn, searchCriteria.getValue().toString()); + }; + case AFTER_LOCAL_DATE -> p -> { + final OffsetDateTime createdOn = p.policy().getValidUntil(); + return isDateAfter(createdOn, searchCriteria.getValue().toString()); + }; + default -> throw new IllegalArgumentException( + MSG_PROPERTY_ONLY_SUPPORTS_THE_FOLLOWING_OPERATIONS.formatted(searchCriteria.getProperty(), + List.of(BEFORE_LOCAL_DATE, AFTER_LOCAL_DATE))); + }; + } } } diff --git a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/common/DateUtilsTest.java b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/common/DateUtilsTest.java new file mode 100644 index 000000000..a1032c03e --- /dev/null +++ b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/common/DateUtilsTest.java @@ -0,0 +1,67 @@ +/******************************************************************************** + * Copyright (c) 2022,2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +package org.eclipse.tractusx.irs.policystore.common; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class DateUtilsTest { + + @ParameterizedTest + @MethodSource("provideDatesForIsDateBefore") + void testIsDateBefore(final OffsetDateTime dateTime, final String referenceDateString, final boolean expected) { + assertThat(DateUtils.isDateBefore(dateTime, referenceDateString)).isEqualTo(expected); + } + + static Stream provideDatesForIsDateBefore() { + final OffsetDateTime referenceDateTime = LocalDate.parse("2024-07-05").atStartOfDay().atOffset(ZoneOffset.UTC); + return Stream.of( // + Arguments.of(referenceDateTime, "2024-07-04", false), + Arguments.of(referenceDateTime, "2024-07-05", false), + Arguments.of(referenceDateTime, "2024-07-06", true)); + } + + @ParameterizedTest + @MethodSource("provideDatesForIsDateAfter") + void testIsDateAfter(final OffsetDateTime dateTime, final String dateString, final boolean expected) { + assertThat(DateUtils.isDateAfter(dateTime, dateString)).isEqualTo(expected); + } + + static Stream provideDatesForIsDateAfter() { + final OffsetDateTime referenceDateTime = LocalDate.parse("2023-07-05") + .atTime(LocalTime.MAX) + .atOffset(ZoneOffset.UTC); + + return Stream.of( // + Arguments.of(referenceDateTime, "2023-07-04", true), + Arguments.of(referenceDateTime, "2023-07-05", false), + Arguments.of(referenceDateTime, "2023-07-06", false)); + } + +} \ No newline at end of file diff --git a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingServiceTest.java b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingServiceTest.java index 1d003ed0d..7aec745ab 100644 --- a/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingServiceTest.java +++ b/irs-policy-store/src/test/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingServiceTest.java @@ -25,7 +25,10 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.tractusx.irs.policystore.common.CommonConstants.PROPERTY_ACTION; import static org.eclipse.tractusx.irs.policystore.common.CommonConstants.PROPERTY_BPN; +import static org.eclipse.tractusx.irs.policystore.common.CommonConstants.PROPERTY_CREATED_ON; import static org.eclipse.tractusx.irs.policystore.common.CommonConstants.PROPERTY_POLICY_ID; +import static org.eclipse.tractusx.irs.policystore.common.CommonConstants.PROPERTY_VALID_UNTIL; +import static org.eclipse.tractusx.irs.policystore.models.SearchCriteria.Operation.AFTER_LOCAL_DATE; import static org.eclipse.tractusx.irs.policystore.models.SearchCriteria.Operation.BEFORE_LOCAL_DATE; import static org.eclipse.tractusx.irs.policystore.models.SearchCriteria.Operation.EQUALS; import static org.eclipse.tractusx.irs.policystore.models.SearchCriteria.Operation.STARTS_WITH; @@ -40,6 +43,7 @@ import org.eclipse.tractusx.irs.edc.client.policy.Permission; import org.eclipse.tractusx.irs.edc.client.policy.Policy; import org.eclipse.tractusx.irs.edc.client.policy.PolicyType; +import org.eclipse.tractusx.irs.policystore.common.DateUtils; import org.eclipse.tractusx.irs.policystore.models.PolicyWithBpn; import org.eclipse.tractusx.irs.policystore.models.SearchCriteria; import org.junit.jupiter.api.BeforeEach; @@ -142,6 +146,43 @@ public void whenSortedByBpnDescAndPolicyIdAsc() { // BPN1 "policy-1", "policy-4"); } + + @Nested + class SortByDateTests { + + final Map> policiesMap = Map.of( // + "BPN2", Arrays.asList( // + createPolicy("policy-3", "2025-04-12", "2029-11-08"), // + createPolicy("policy-5", "2024-09-01", "2030-03-25"), // + createPolicy("policy-2", "2024-09-01", "2027-02-15") // + ), "BPN1", Arrays.asList( // + createPolicy("policy-4", "2022-12-31", "2026-08-05"), // + createPolicy("policy-1", "2023-03-15", "2028-07-10") // + )); + + @Test + public void whenSortedByCreatedOnAscAndValidUntilAsc() { + + final Page result = testee.getPolicies(policiesMap, PageRequest.of(0, 10, + Sort.by(PROPERTY_CREATED_ON).ascending().and(Sort.by(PROPERTY_VALID_UNTIL).ascending())), + NO_SEARCH_CRITERIA); + + assertThat(result.getContent().stream().map(p -> p.policy().getPolicyId()).toList()).containsExactly( + "policy-4", "policy-1", "policy-2", "policy-5", "policy-3"); + } + + @Test + public void whenSortedByCreatedOnAscAndValidUntilDesc() { + + final Page result = testee.getPolicies(policiesMap, PageRequest.of(0, 10, + Sort.by(PROPERTY_CREATED_ON).ascending().and(Sort.by(PROPERTY_VALID_UNTIL).descending())), + NO_SEARCH_CRITERIA); + + assertThat(result.getContent().stream().map(p -> p.policy().getPolicyId()).toList()).containsExactly( + "policy-4", "policy-1", "policy-5", "policy-2", "policy-3"); + } + } + } @Nested @@ -297,6 +338,32 @@ public void filterByMultiple_shouldNarrowDown() { assertThat(policies).containsExactlyInAnyOrder("[bpn=BPN1,policyId=policy-2]"); } + @Nested + class FilterByDateTests { + + final Map> policiesMap = Map.of( // + "BPN2", Arrays.asList( // + createPolicy("policy-3", "2025-04-12", "2029-11-08"), // + createPolicy("policy-5", "2024-09-01", "2030-03-25"), // + createPolicy("policy-2", "2024-09-01", "2027-02-15") // + ), "BPN1", Arrays.asList( // + createPolicy("policy-4", "2022-12-31", "2026-08-05"), // + createPolicy("policy-1", "2023-03-15", "2028-07-10") // + )); + + @Test + public void whenFilteredByCreatedOnAndValidUntil() { + + final Page result = testee.getPolicies(policiesMap, PageRequest.of(0, 10, + Sort.by(PROPERTY_CREATED_ON).ascending().and(Sort.by(PROPERTY_VALID_UNTIL).ascending())), + List.of(new SearchCriteria<>(PROPERTY_CREATED_ON, BEFORE_LOCAL_DATE, "2024-09-01"), + new SearchCriteria<>(PROPERTY_VALID_UNTIL, AFTER_LOCAL_DATE, "2026-08-04"))); + + assertThat(result.getContent().stream().map(p -> p.policy().getPolicyId()).toList()).containsExactly( + "policy-4", "policy-1"); + } + + } } private Policy createPolicy(final String policyId, final PolicyType firstPermissionAction) { @@ -308,11 +375,25 @@ private Policy createPolicy(final String policyId, final PolicyType firstPermiss .build(); } + private Policy createPolicy(final String policyId, final String createdOnString, final String validUntilString) { + return Policy.builder() + .policyId(policyId) + .createdOn(DateUtils.toOffsetDateTimeAtStartOfDay(createdOnString)) + .validUntil(DateUtils.toOffsetDateTimeAtEndOfDay(validUntilString)) + .permissions(createPermissions()) + .build(); + } + private List createPermissions(final PolicyType firstPermissionAction) { return List.of(new Permission(firstPermissionAction, createConstraints()), new Permission(PolicyType.ACCESS, createConstraints())); } + private List createPermissions() { + return List.of(new Permission(PolicyType.USE, createConstraints()), + new Permission(PolicyType.ACCESS, createConstraints())); + } + private Constraints createConstraints() { return new Constraints(emptyList(), List.of(ConstraintConstants.ACTIVE_MEMBERSHIP, ConstraintConstants.FRAMEWORK_AGREEMENT_TRACEABILITY_ACTIVE, ConstraintConstants.PURPOSE_ID_3_1_TRACE)); From 7c01debf8a87a51b2bb856ed5edcb00826e33a02 Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Tue, 9 Jul 2024 11:30:48 +0200 Subject: [PATCH 02/13] chore(documentation):[#750] update insomnia request collection added: - page parameter - size parameter - search by policyId --- .../IRS_Request_Collection.json | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/local/testing/request-collection/IRS_Request_Collection.json b/local/testing/request-collection/IRS_Request_Collection.json index d53689864..345b9327a 100644 --- a/local/testing/request-collection/IRS_Request_Collection.json +++ b/local/testing/request-collection/IRS_Request_Collection.json @@ -94,6 +94,27 @@ "value": "BPNL1234567890XX", "description": "", "disabled": false + }, + { + "id": "pair_05398fd8c0f048b996b9f9af94fcc8ba", + "name": "search", + "value": "policyId,STARTS_WITH,policy4", + "description": "", + "disabled": true + }, + { + "id": "pair_88cfa390e59c456493e70736b32d529d", + "name": "page", + "value": "1", + "description": "", + "disabled": false + }, + { + "id": "pair_05e508de308f4f25993a39aebb5c462e", + "name": "size", + "value": "10", + "description": "", + "disabled": false } ], "headers": [], From de905617f24ff46cbcee6528a8d6f61f2c4a4e0d Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Fri, 12 Jul 2024 14:00:13 +0200 Subject: [PATCH 03/13] feat(policy-store-api):[#750] make utility class final and private constructor --- .../eclipse/tractusx/irs/policystore/common/DateUtils.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java index bc2035751..6665d74e8 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java @@ -27,7 +27,11 @@ /** * Date utilities. */ -public class DateUtils { +public final class DateUtils { + + private DateUtils() { + // private constructor (utility class) + } public static boolean isDateBefore(final OffsetDateTime dateTime, final String referenceDateString) { return dateTime.isBefore(toOffsetDateTimeAtStartOfDay(referenceDateString)); From 5360c495397927fa9776a28ba8eedbfec6e1eb0f Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Fri, 12 Jul 2024 14:02:56 +0200 Subject: [PATCH 04/13] feat(policy-store-api):[#750] update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aadcf2980..f7c06da1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ _**For better traceability add the corresponding GitHub issue number in each cha ### Added +- Added filtering by "createdOn", "validUntil" to paging endpoint for Policy Store API: `GET /irs/policies/paged`. #750 + ### Fixed - Access and Usage Policy Validation flow correction. #757 From f7b5b95d38988546b15db1dd9b24badd22a4cf0e Mon Sep 17 00:00:00 2001 From: Matthias Fischer Date: Mon, 15 Jul 2024 12:05:13 +0200 Subject: [PATCH 05/13] chore(pmd):[#750] ignore false positive --- .../irs/policystore/services/PolicyPagingService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingService.java b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingService.java index 791677e67..3f46dd833 100644 --- a/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingService.java +++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/services/PolicyPagingService.java @@ -58,7 +58,9 @@ */ @Service @Slf4j -@SuppressWarnings({ "PMD.TooManyStaticImports" }) +@SuppressWarnings({ "PMD.TooManyStaticImports", + "PMD.ExcessiveImports" +}) public class PolicyPagingService { /** From 0e9b5fe500cd7b50657a9f3a66782d578994e69b Mon Sep 17 00:00:00 2001 From: jhartmann Date: Mon, 15 Jul 2024 14:37:36 +0200 Subject: [PATCH 06/13] fix(irs-api):[#538] add deep search for exception cause --- .../irs/IrsWireMockIntegrationTest.java | 2 +- .../tractusx/irs/component/TombstoneTest.java | 7 ++-- irs-models/pom.xml | 5 +++ .../tractusx/irs/component/Tombstone.java | 34 ++++++++++++++----- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java index 477f072e5..67c1efa97 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/IrsWireMockIntegrationTest.java @@ -306,7 +306,7 @@ void shouldCreateDetailedTombstoneForMissmatchPolicy() { final Tombstone actualTombstone = jobForJobId.getTombstones().get(0); assertThat(actualTombstone.getProcessingError().getRootCauses()).hasSize(1); assertThat(actualTombstone.getProcessingError().getRootCauses().get(0)).contains( - "Asset could not be negotiated for providerWithSuffix 'https://test.edc.io/api/v1/dsp', BPN 'BPNL00000000TEST', catalogItem"); + "UsagePolicyPermissionException: Policies [default-policy] did not match with policy from BPNL00000000TEST."); } @Test diff --git a/irs-api/src/test/java/org/eclipse/tractusx/irs/component/TombstoneTest.java b/irs-api/src/test/java/org/eclipse/tractusx/irs/component/TombstoneTest.java index bded98dae..0d9b0ef72 100644 --- a/irs-api/src/test/java/org/eclipse/tractusx/irs/component/TombstoneTest.java +++ b/irs-api/src/test/java/org/eclipse/tractusx/irs/component/TombstoneTest.java @@ -84,7 +84,7 @@ void shouldUseSuppressedExceptionWhenPresent() { // assert assertThat(from.getProcessingError().getErrorDetail()).isEqualTo(exception.getMessage()); - assertThat(from.getProcessingError().getRootCauses()).contains(suppressedExceptionMessage); + assertThat(from.getProcessingError().getRootCauses()).contains("Exception: " + suppressedExceptionMessage); } @Test @@ -93,7 +93,8 @@ void shouldUseDeepSuppressedExceptionWhenPresent() { final Exception exception = new Exception("Exception occurred."); final Exception rootCause = new Exception("Wrapper exception to the root cause"); - rootCause.addSuppressed(new Exception("Root cause of the exception")); + final String suppressedRootCause = "Root cause of the exception"; + rootCause.addSuppressed(new Exception(suppressedRootCause)); final Exception suppressedWrapperException = new Exception( "Suppressed Exception which was added through Futures.", rootCause); @@ -107,7 +108,7 @@ void shouldUseDeepSuppressedExceptionWhenPresent() { // assert assertThat(from.getProcessingError().getErrorDetail()).isEqualTo(exception.getMessage()); - assertThat(from.getProcessingError().getRootCauses()).contains("Root cause of the exception"); + assertThat(from.getProcessingError().getRootCauses()).contains("Exception: " + suppressedRootCause); } @Test diff --git a/irs-models/pom.xml b/irs-models/pom.xml index 7c8585f3d..f0f290709 100644 --- a/irs-models/pom.xml +++ b/irs-models/pom.xml @@ -95,6 +95,11 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java index 632485c3e..933c682eb 100644 --- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java +++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java @@ -28,12 +28,12 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.stream.Stream; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; import lombok.extern.jackson.Jacksonized; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.eclipse.tractusx.irs.component.enums.NodeType; import org.eclipse.tractusx.irs.component.enums.ProcessStep; @@ -88,8 +88,8 @@ public static Tombstone from(final String catenaXId, final String endpointURL, f public static Tombstone from(final String globalAssetId, final String endpointURL, final Throwable exception, final Throwable[] suppressed, final int retryCount, final ProcessStep processStep) { - final ProcessingError processingError = - withProcessingError(processStep, retryCount, exception.getMessage(), suppressed); + final ProcessingError processingError = withProcessingError(processStep, retryCount, exception.getMessage(), + suppressed); return Tombstone.builder() .endpointURL(endpointURL) .catenaXId(globalAssetId) @@ -99,7 +99,7 @@ public static Tombstone from(final String globalAssetId, final String endpointUR private static ProcessingError withProcessingError(final ProcessStep processStep, final int retryCount, final String message, final Throwable... suppressed) { - final List rootCauses = Arrays.stream(suppressed).flatMap(Tombstone::getErrorMessages).toList(); + final List rootCauses = Arrays.stream(suppressed).map(Tombstone::getRootErrorMessages).toList(); return ProcessingError.builder() .withProcessStep(processStep) @@ -110,12 +110,30 @@ private static ProcessingError withProcessingError(final ProcessStep processStep .build(); } - private static Stream getErrorMessages(final Throwable throwable) { + /** + * Search for the root cause or suppressed exception as long as there is a cause or suppressed exception. + * Stop after a depth of 10 to prevent endless loop. + * + * @param throwable the exception with a nested or suppressed exception + * @return the root cause, eiter suppressed or nested + */ + private static String getRootErrorMessages(final Throwable throwable) { final Throwable cause = throwable.getCause(); - if (cause != null && hasSuppressedExceptions(cause)) { - return Arrays.stream(throwable.getCause().getSuppressed()).map(Throwable::getMessage); + + if (cause != null) { + Throwable rootCause = cause; + int depth = 0; + while (rootCause.getCause() != null || hasSuppressedExceptions(rootCause) || depth > 10) { + if (hasSuppressedExceptions(rootCause)) { + rootCause = rootCause.getSuppressed()[0]; + } else { + rootCause = rootCause.getCause(); + } + depth++; + } + return ExceptionUtils.getRootCauseMessage(rootCause); } - return Stream.of(throwable.getMessage()); + return ExceptionUtils.getRootCauseMessage(throwable); } private static ProcessingError withProcessingError(final ProcessStep processStep, final int retryCount, From b1c0f79dcde25fc39a659d3cf0e3eaa59c2bea68 Mon Sep 17 00:00:00 2001 From: jhartmann Date: Mon, 15 Jul 2024 14:42:30 +0200 Subject: [PATCH 07/13] fix(irs-api):[#538] fix checkstyle --- .../java/org/eclipse/tractusx/irs/component/Tombstone.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java index 933c682eb..de8058c21 100644 --- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java +++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java @@ -123,7 +123,8 @@ private static String getRootErrorMessages(final Throwable throwable) { if (cause != null) { Throwable rootCause = cause; int depth = 0; - while (rootCause.getCause() != null || hasSuppressedExceptions(rootCause) || depth > 10) { + final int maxDepth = 10; + while (rootCause.getCause() != null || hasSuppressedExceptions(rootCause) || depth > maxDepth) { if (hasSuppressedExceptions(rootCause)) { rootCause = rootCause.getSuppressed()[0]; } else { From baefb8ce5be91cc11d4b4def0712041aefc050a3 Mon Sep 17 00:00:00 2001 From: jhartmann Date: Mon, 15 Jul 2024 15:21:36 +0200 Subject: [PATCH 08/13] fix(irs-api):[#538] fix logical error in termination condition --- .../main/java/org/eclipse/tractusx/irs/component/Tombstone.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java index de8058c21..be9451229 100644 --- a/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java +++ b/irs-models/src/main/java/org/eclipse/tractusx/irs/component/Tombstone.java @@ -124,7 +124,7 @@ private static String getRootErrorMessages(final Throwable throwable) { Throwable rootCause = cause; int depth = 0; final int maxDepth = 10; - while (rootCause.getCause() != null || hasSuppressedExceptions(rootCause) || depth > maxDepth) { + while ((rootCause.getCause() != null || hasSuppressedExceptions(rootCause)) && depth < maxDepth) { if (hasSuppressedExceptions(rootCause)) { rootCause = rootCause.getSuppressed()[0]; } else { From 1221f51b8a1d51db4a9b56e16d0831eddab86202 Mon Sep 17 00:00:00 2001 From: jhartmann Date: Mon, 15 Jul 2024 15:31:19 +0200 Subject: [PATCH 09/13] chore(docs): update COMPATIBILITY_MATRIX --- COMPATIBILITY_MATRIX.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/COMPATIBILITY_MATRIX.md b/COMPATIBILITY_MATRIX.md index d93a50756..e53fddd02 100644 --- a/COMPATIBILITY_MATRIX.md +++ b/COMPATIBILITY_MATRIX.md @@ -12,7 +12,24 @@ Full changelog of IRS: [changelog](CHANGELOG.md) | Discovery Finder | 0.2.5 | - | REST connection | | Minio | RELEASE.2022-11-11T03-44-20Z | 5.0.1 | | | Helm | 3.9.3 | - | - | -| Kubernetes | 1.29 | - | - | +| Kubernetes | [ 1.28; 1.29; 1.30 ] | - | - | +| [SingleLevelBomAsBuilt](https://github.com/eclipse-tractusx/sldt-semantic-models/tree/main/io.catenax.single_level_bom_as_built) | [ 2.0.0; 3.0.0 ] | - | Model version | +| [SingleLevelBomAsPlanned](https://github.com/eclipse-tractusx/sldt-semantic-models/tree/main/io.catenax.single_level_bom_as_planned) | [ 2.0.0; 3.0.0 ] | - | Model version | +| [SingleLevelBomAsSpecified](https://github.com/eclipse-tractusx/sldt-semantic-models/tree/main/io.catenax.single_level_bom_as_specified) | 2.0.0 | - | Model version | +| [SingleLevelUsageAsBuilt](https://github.com/eclipse-tractusx/sldt-semantic-models/tree/main/io.catenax.single_level_usage_as_built) | 3.0.0 | - | Model version | +| [SingleLevelUsageAsPlanned](https://github.com/eclipse-tractusx/sldt-semantic-models/tree/main/io.catenax.single_level_usage_as_planned) | 2.0.0 | - | Model version | + +## [CATENA-X Release 24.08](https://eclipse-tractusx.github.io/CHANGELOG/) - [5.3.0](https://github.com/eclipse-tractusx/item-relationship-service/releases/tag/5.3.0) - 2024-07-15 + +| Dependency | Version | Helm | Comments | +|------------------------------------------------------------------------------------------------------------------------------------------|------------------------------|-------|-----------------| +| EDC | 0.7.1 | 0.7.1 | | +| Semantics Hub | 0.3.1 | 0.2.1 | REST connection | +| DTR | 0.4.1 | 0.4.9 | REST connection | +| Discovery Finder | 0.2.5 | - | REST connection | +| Minio | RELEASE.2022-11-11T03-44-20Z | 5.0.1 | | +| Helm | 3.9.3 | - | - | +| Kubernetes | [ 1.28; 1.29; 1.30 ] | - | - | | [SingleLevelBomAsBuilt](https://github.com/eclipse-tractusx/sldt-semantic-models/tree/main/io.catenax.single_level_bom_as_built) | [ 2.0.0; 3.0.0 ] | - | Model version | | [SingleLevelBomAsPlanned](https://github.com/eclipse-tractusx/sldt-semantic-models/tree/main/io.catenax.single_level_bom_as_planned) | [ 2.0.0; 3.0.0 ] | - | Model version | | [SingleLevelBomAsSpecified](https://github.com/eclipse-tractusx/sldt-semantic-models/tree/main/io.catenax.single_level_bom_as_specified) | 2.0.0 | - | Model version | From 1645062ee3d938fc4483849a150fcf3344054b61 Mon Sep 17 00:00:00 2001 From: jhartmann Date: Mon, 15 Jul 2024 15:31:35 +0200 Subject: [PATCH 10/13] chore(testing): add python DEPENDENCIES --- local/testing/testdata/DEPENDENCIES | 1 + local/testing/testdata/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 local/testing/testdata/DEPENDENCIES diff --git a/local/testing/testdata/DEPENDENCIES b/local/testing/testdata/DEPENDENCIES new file mode 100644 index 000000000..517965c60 --- /dev/null +++ b/local/testing/testdata/DEPENDENCIES @@ -0,0 +1 @@ +pypi/pypi/-/requests/2.32.3, Apache-2.0 AND MIT AND Apache-2.0, approved, #14884 diff --git a/local/testing/testdata/requirements.txt b/local/testing/testdata/requirements.txt index 0227f3c31..ef487e06e 100644 --- a/local/testing/testdata/requirements.txt +++ b/local/testing/testdata/requirements.txt @@ -1 +1 @@ -requests~=2.31.0 \ No newline at end of file +requests==2.32.3 \ No newline at end of file From cac0bcb7a808982afd04d0141d552434864472f4 Mon Sep 17 00:00:00 2001 From: ds-jhartmann <57985712+ds-jhartmann@users.noreply.github.com> Date: Mon, 15 Jul 2024 13:46:24 +0000 Subject: [PATCH 11/13] chore(dependencies): Update irs-registry-client to 2.1.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 09c9a6434..e538ef8de 100644 --- a/pom.xml +++ b/pom.xml @@ -75,7 +75,7 @@ - 2.1.6 + 2.1.7 3.1.12 From b1886529b26735f5e6b64bc9477ce03ef5785091 Mon Sep 17 00:00:00 2001 From: jhartmann Date: Mon, 15 Jul 2024 15:48:45 +0200 Subject: [PATCH 12/13] fix(deps): update DEPENDENCIES --- DEPENDENCIES | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index 8e4dd99b2..37c41ce96 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -306,12 +306,12 @@ maven/mavencentral/org.eclipse.tractusx.edc/core-spi/0.6.0, Apache-2.0, approved maven/mavencentral/org.eclipse.tractusx.edc/edr-api/0.6.0, Apache-2.0, approved, automotive.tractusx maven/mavencentral/org.eclipse.tractusx.edc/edr-spi/0.6.0, Apache-2.0, approved, automotive.tractusx maven/mavencentral/org.eclipse.tractusx.irs/irs-api/0.0.2-SNAPSHOT, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx.irs/irs-common/2.1.6, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx.irs/irs-edc-client/2.1.6, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx.irs/irs-models/2.1.6, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.irs/irs-common/2.1.7, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.irs/irs-edc-client/2.1.7, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.irs/irs-models/2.1.7, Apache-2.0, approved, automotive.tractusx maven/mavencentral/org.eclipse.tractusx.irs/irs-policy-store/0.0.2-SNAPSHOT, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx.irs/irs-registry-client/2.1.6, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.eclipse.tractusx.irs/irs-testing/2.1.6, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.irs/irs-registry-client/2.1.7, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.irs/irs-testing/2.1.7, Apache-2.0, approved, automotive.tractusx maven/mavencentral/org.glassfish/jakarta.json/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp maven/mavencentral/org.hamcrest/hamcrest-core/2.2, BSD-3-Clause, approved, clearlydefined maven/mavencentral/org.hamcrest/hamcrest/2.2, BSD-3-Clause, approved, clearlydefined From fb1ac309d34e903f4ccb9ae017db3005d25ab2cc Mon Sep 17 00:00:00 2001 From: ds-jhartmann <57985712+ds-jhartmann@users.noreply.github.com> Date: Mon, 15 Jul 2024 13:56:32 +0000 Subject: [PATCH 13/13] chore(docs): updated docs and Helm chart for IRS release 5.3.0 --- CHANGELOG.md | 5 ++++- charts/item-relationship-service/CHANGELOG.md | 6 ++++++ charts/item-relationship-service/Chart.yaml | 4 ++-- docs/src/api/irs-api.yaml | 2 +- .../main/java/org/eclipse/tractusx/irs/IrsApplication.java | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b6ef142c..0769fa81a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ _**For better traceability add the corresponding GitHub issue number in each cha ## [Unreleased] +## [5.3.0] - 2024-07-15 + ### Added - Added filtering by "createdOn", "validUntil" to paging endpoint for Policy Store API: `GET /irs/policies/paged`. #750 @@ -728,7 +730,8 @@ _**For better traceability add the corresponding GitHub issue number in each cha - **Select Aspects you need** You are able to select the needed aspects for which you want to collect the correct endpoint information. -[Unreleased]: https://github.com/eclipse-tractusx/item-relationship-service/compare/5.2.0...HEAD +[Unreleased]: https://github.com/eclipse-tractusx/item-relationship-service/compare/5.3.0...HEAD +[5.3.0]: https://github.com/eclipse-tractusx/item-relationship-service/compare/5.2.0...5.3.0 [5.2.0]: https://github.com/eclipse-tractusx/item-relationship-service/compare/5.1.4...5.2.0 [5.1.4]: https://github.com/eclipse-tractusx/item-relationship-service/compare/5.1.3...5.1.4 [5.1.3]: https://github.com/eclipse-tractusx/item-relationship-service/compare/5.1.2...5.1.3 diff --git a/charts/item-relationship-service/CHANGELOG.md b/charts/item-relationship-service/CHANGELOG.md index d86f90b94..dff52eed8 100644 --- a/charts/item-relationship-service/CHANGELOG.md +++ b/charts/item-relationship-service/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [7.3.0] - 2024-07-15 + +### Changed + +- Update IRS version to 5.3.0 + ## [7.2.1] - 2024-07-10 - Update bitnami/common to 2.x.x diff --git a/charts/item-relationship-service/Chart.yaml b/charts/item-relationship-service/Chart.yaml index 562b85296..d82e7828d 100644 --- a/charts/item-relationship-service/Chart.yaml +++ b/charts/item-relationship-service/Chart.yaml @@ -35,12 +35,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 7.2.1 +version: 7.3.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "5.2.0" +appVersion: "5.3.0" dependencies: - name: common repository: https://charts.bitnami.com/bitnami diff --git a/docs/src/api/irs-api.yaml b/docs/src/api/irs-api.yaml index b29772ab2..fadd254c3 100644 --- a/docs/src/api/irs-api.yaml +++ b/docs/src/api/irs-api.yaml @@ -3,7 +3,7 @@ info: description: The API of the Item Relationship Service (IRS) for retrieving item graphs along the value chain of CATENA-X partners. title: IRS API - version: 5.2.0 + version: 5.3.0 servers: - url: http://localhost:8080 security: diff --git a/irs-api/src/main/java/org/eclipse/tractusx/irs/IrsApplication.java b/irs-api/src/main/java/org/eclipse/tractusx/irs/IrsApplication.java index 339e6673a..7d923d384 100644 --- a/irs-api/src/main/java/org/eclipse/tractusx/irs/IrsApplication.java +++ b/irs-api/src/main/java/org/eclipse/tractusx/irs/IrsApplication.java @@ -59,7 +59,7 @@ public class IrsApplication { /** * The IRS API version. */ - public static final String API_VERSION = "5.2.0"; + public static final String API_VERSION = "5.3.0"; /** * The URL prefix for IRS API URLs.