diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9acf49e329..d4ec5fb4b0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,12 @@ _**For better traceability add the corresponding GitHub issue number in each cha
### Added
- Added endpoint: `GET /irs/policies/{policyId}`. #803
+
+## [5.3.0] - 2024-07-15
+
+### Added
+
+- Added filtering by "createdOn", "validUntil" to paging endpoint for Policy Store API: `GET /irs/policies/paged`. #750
- Added autocomplete endpoint Policy Store API: `GET /irs/policies/attributes/{attribute}`. #750
- Added get and delete functionality for contract definitions eclipse-tractusx/traceability-foss#1190
@@ -728,7 +734,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/COMPATIBILITY_MATRIX.md b/COMPATIBILITY_MATRIX.md
index d93a50756f..e53fddd023 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 |
diff --git a/DEPENDENCIES b/DEPENDENCIES
index 8e4dd99b2c..37c41ce966 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
diff --git a/charts/item-relationship-service/CHANGELOG.md b/charts/item-relationship-service/CHANGELOG.md
index d86f90b940..dff52eed87 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 562b85296a..d82e7828d6 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 24437cfa49..449e57b61e 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 339e6673aa..7d923d3847 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.
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 477f072e5b..67c1efa978 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 bded98daed..0d9b0ef72d 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 7c8585f3d3..f0f2907092 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 632485c3e0..be9451229b 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,31 @@ 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;
+ final int maxDepth = 10;
+ while ((rootCause.getCause() != null || hasSuppressedExceptions(rootCause)) && depth < maxDepth) {
+ 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,
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 0000000000..6665d74e83
--- /dev/null
+++ b/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/common/DateUtils.java
@@ -0,0 +1,51 @@
+/********************************************************************************
+ * 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 final class DateUtils {
+
+ private DateUtils() {
+ // private constructor (utility class)
+ }
+
+ 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 adaabf8bab..de1fdd09e1 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.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.List;
@@ -53,7 +58,9 @@
*/
@Service
@Slf4j
-@SuppressWarnings({ "PMD.TooManyStaticImports" })
+@SuppressWarnings({ "PMD.TooManyStaticImports",
+ "PMD.ExcessiveImports"
+})
public class PolicyPagingService {
/**
@@ -224,6 +231,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) {
@@ -241,24 +249,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");
}
}
@@ -268,7 +270,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)));
};
}
@@ -278,7 +280,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)));
};
}
@@ -299,9 +301,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 0000000000..a1032c03e8
--- /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 1d003ed0d7..7aec745ab5 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));
diff --git a/local/testing/testdata/DEPENDENCIES b/local/testing/testdata/DEPENDENCIES
new file mode 100644
index 0000000000..517965c60f
--- /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 0227f3c31b..ef487e06e0 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
diff --git a/pom.xml b/pom.xml
index 09c9a64342..e538ef8de7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
- 2.1.6
+ 2.1.7
3.1.12