Skip to content

Commit

Permalink
feat(policy-api):[eclipse-tractusx#750] cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
dsmf committed Jul 5, 2024
1 parent a3435f5 commit 269f545
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<SearchCriteria<?>> searchCriteriaList;

/* package */ PolicyFilterBuilder(final List<SearchCriteria<?>> searchCriteriaList) {
Expand All @@ -195,24 +201,18 @@ private static class PolicyFilterBuilder {
}

private Predicate<PolicyWithBpn> 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");
}
}

Expand All @@ -222,7 +222,7 @@ private Predicate<PolicyWithBpn> 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)));
};
}
Expand All @@ -232,7 +232,7 @@ private Predicate<PolicyWithBpn> 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)));
};
}
Expand All @@ -253,9 +253,42 @@ private Predicate<PolicyWithBpn> 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<PolicyWithBpn> 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<PolicyWithBpn> 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)));
};
}
}
}

Original file line number Diff line number Diff line change
@@ -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<Arguments> 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<Arguments> 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));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -142,6 +146,43 @@ public void whenSortedByBpnDescAndPolicyIdAsc() {
// BPN1
"policy-1", "policy-4");
}

@Nested
class SortByDateTests {

final Map<String, List<Policy>> 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<PolicyWithBpn> 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<PolicyWithBpn> 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
Expand Down Expand Up @@ -297,6 +338,32 @@ public void filterByMultiple_shouldNarrowDown() {
assertThat(policies).containsExactlyInAnyOrder("[bpn=BPN1,policyId=policy-2]");
}

@Nested
class FilterByDateTests {

final Map<String, List<Policy>> 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<PolicyWithBpn> 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) {
Expand All @@ -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<Permission> createPermissions(final PolicyType firstPermissionAction) {
return List.of(new Permission(firstPermissionAction, createConstraints()),
new Permission(PolicyType.ACCESS, createConstraints()));
}

private List<Permission> 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));
Expand Down

0 comments on commit 269f545

Please sign in to comment.