From d846cbd4e9f5c1a457e090e04a04fc87ec2863c8 Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Wed, 22 May 2024 13:50:23 +0200 Subject: [PATCH 01/13] feat(api, spi, storage): add profile to the policy model added profile to the validation added profile to the policy model added profile to the sql storage Signed-off-by: Sascha Isele --- .../validators/MandatoryIdArray.java | 83 +++++++++++++++++++ .../jsonobject/JsonObjectValidatorTest.java | 72 ++++++++++++++++ .../to/JsonObjectToPolicyTransformer.java | 2 + .../policy/v3/PolicyDefinitionApiV3.java | 1 + .../validation/PolicyDefinitionValidator.java | 14 +++- .../PolicyDefinitionValidatorTest.java | 2 + .../policy-definition-store-sql/docs/er.puml | 1 + .../docs/schema.sql | 2 + .../store/SqlPolicyDefinitionStore.java | 5 ++ .../schema/BaseSqlDialectStatements.java | 2 + .../schema/SqlPolicyStoreStatements.java | 4 + .../store/schema/postgres/PolicyMapping.java | 1 + .../postgres/PostgresDialectStatements.java | 4 + .../edc/jsonld/spi/PropertyAndTypeNames.java | 1 + .../org/eclipse/edc/policy/model/Policy.java | 18 +++- 15 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/MandatoryIdArray.java diff --git a/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/MandatoryIdArray.java b/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/MandatoryIdArray.java new file mode 100644 index 00000000000..e72df51128d --- /dev/null +++ b/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/MandatoryIdArray.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2024 ZF Friedrichshafen AG + * + * 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 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - initial implementation + * + */ + +package org.eclipse.edc.validator.jsonobject.validators; + +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonValue; +import org.eclipse.edc.validator.jsonobject.JsonLdPath; +import org.eclipse.edc.validator.spi.ValidationResult; +import org.eclipse.edc.validator.spi.Validator; + +import java.util.Optional; +import java.util.function.Function; + +import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.eclipse.edc.validator.spi.Violation.violation; + +/** + * Verifies that an array is present and the key:value pairs are of type @id:string with optional constraint on min size. + */ +public class MandatoryIdArray implements Validator { + private final JsonLdPath path; + private final Integer min; + + public MandatoryIdArray(JsonLdPath path) { + this(path, null); + } + + public MandatoryIdArray(JsonLdPath path, Integer min) { + this.path = path; + this.min = min; + } + + public static Function> min(Integer min) { + return path -> new MandatoryArray(path, min); + } + + @Override + public ValidationResult validate(JsonObject input) { + ValidationResult sizeResult; + + sizeResult = Optional.ofNullable(input.getJsonArray(path.last())) + .map(this::validateMin) + .orElse(ValidationResult.failure(violation(format("mandatory array '%s' is missing", path), path.toString()))); + + if (sizeResult.failed()) return sizeResult; + + return Optional.ofNullable(input.getJsonArray(path.last())) + .map(this::validateType) + .orElse(ValidationResult.failure(violation(format("mandatory array '%s' is missing", path), path.toString()))); + } + + private ValidationResult validateMin(JsonArray array) { + if (min == null || (array.size() >= min)) { + return ValidationResult.success(); + } + return ValidationResult.failure(violation(format("array '%s' should at least contains '%s' elements", path, min), path.toString())); + } + + private ValidationResult validateType(JsonArray array) { + for (JsonValue value : array) { + var id = value.asJsonObject().getJsonString(ID); + if (id == null || id.getString().isBlank()) { + return ValidationResult.failure(violation(format("contents of array '%s' should be of type string and not blank", path), path.toString())); + } + } + return ValidationResult.success(); + } + +} diff --git a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java index 06c9da29e22..454d6d59399 100644 --- a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java +++ b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java @@ -17,6 +17,7 @@ import jakarta.json.JsonArrayBuilder; import org.eclipse.edc.validator.jsonobject.validators.MandatoryArray; import org.eclipse.edc.validator.jsonobject.validators.MandatoryObject; +import org.eclipse.edc.validator.jsonobject.validators.MandatoryIdArray; import org.eclipse.edc.validator.jsonobject.validators.MandatoryValue; import org.eclipse.edc.validator.jsonobject.validators.OptionalIdNotBlank; import org.eclipse.edc.validator.spi.ValidationFailure; @@ -217,6 +218,77 @@ void shouldFail_whenInputIsNull() { }); } + @Test + void shouldFail_ValidateMandatoryIdArrayMinSize() { + var input = createObjectBuilder() + .add("arrayProperty", createArrayBuilder() + .add(createObjectBuilder().add(ID, "value1")) + .add(createObjectBuilder().add(ID, "value2")) + ); + + var result = JsonObjectValidator.newValidator() + .verify("arrayProperty", MandatoryIdArray.min(3)) + .build() + .validate(input.build()); + + assertThat(result).isFailed().satisfies(failure -> { + assertThat(failure.getViolations()).anySatisfy(violation -> { + assertThat(violation.path()).contains("arrayProperty"); + }); + }); + } + + @Test + void shouldFail_ValidateMandatoryIdArrayNoValue() { + var input = createObjectBuilder(); + + var result = JsonObjectValidator.newValidator() + .verify("arrayProperty", MandatoryIdArray::new) + .build() + .validate(input.build()); + + assertThat(result).isFailed().satisfies(failure -> { + assertThat(failure.getViolations()).anySatisfy(violation -> { + assertThat(violation.path()).contains("arrayProperty"); + }); + }); + } + + @Test + void shouldFail_ValidateMandatoryIdArrayWrongType() { + var input = createObjectBuilder() + .add("arrayProperty", createArrayBuilder() + .add(createObjectBuilder().add("subProperty", createObjectBuilder())) + ); + + var result = JsonObjectValidator.newValidator() + .verify("arrayProperty", MandatoryIdArray::new) + .build() + .validate(input.build()); + + assertThat(result).isFailed().satisfies(failure -> { + assertThat(failure.getViolations()).anySatisfy(violation -> { + assertThat(violation.path()).contains("arrayProperty"); + }); + }); + } + + @Test + void shouldSucceed_ValidateMandatoryIdArray() { + var input = createObjectBuilder() + .add("arrayProperty", createArrayBuilder() + .add(createObjectBuilder().add(ID, "value1")) + .add(createObjectBuilder().add(ID, "value2")) + ); + + var result = JsonObjectValidator.newValidator() + .verify("arrayProperty", MandatoryIdArray::new) + .build() + .validate(input.build()); + + assertThat(result).isSucceeded(); + } + private JsonArrayBuilder value(String value) { return createArrayBuilder().add(createObjectBuilder().add(VALUE, value)); } diff --git a/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java b/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java index 3a6343de06e..c52b02b4b3b 100644 --- a/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java +++ b/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java @@ -37,6 +37,7 @@ import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_TYPE_AGREEMENT; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_TYPE_OFFER; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_TYPE_SET; +import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PROFILE_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PROHIBITION_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_TARGET_ATTRIBUTE; @@ -91,6 +92,7 @@ public JsonObjectToPolicyTransformer(ParticipantIdMapper participantIdMapper) { case ODRL_TARGET_ATTRIBUTE -> v -> builder.target(transformString(v, context)); case ODRL_ASSIGNER_ATTRIBUTE -> v -> builder.assigner(participantIdMapper.fromIri(transformString(v, context))); case ODRL_ASSIGNEE_ATTRIBUTE -> v -> builder.assignee(participantIdMapper.fromIri(transformString(v, context))); + case ODRL_PROFILE_ATTRIBUTE -> v -> builder.profiles(transformArray(v, String.class, context)); default -> v -> builder.extensibleProperty(key, transformGenericProperty(v, context)); }); diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v3/PolicyDefinitionApiV3.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v3/PolicyDefinitionApiV3.java index 1d2f588ce4c..9e0de101307 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v3/PolicyDefinitionApiV3.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v3/PolicyDefinitionApiV3.java @@ -119,6 +119,7 @@ record PolicyDefinitionInputSchema( "@context": "http://www.w3.org/ns/odrl.jsonld", "@type": "Set", "uid": "http://example.com/policy:1010", + "profile": "http://example.com/odrl:profile:02", "permission": [{ "target": "http://example.com/asset:9898.movie", "action": "display", diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidator.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidator.java index 7120906d99e..8dca7042562 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidator.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidator.java @@ -17,6 +17,7 @@ import jakarta.json.JsonObject; import org.eclipse.edc.validator.jsonobject.JsonLdPath; import org.eclipse.edc.validator.jsonobject.JsonObjectValidator; +import org.eclipse.edc.validator.jsonobject.validators.MandatoryIdArray; import org.eclipse.edc.validator.jsonobject.validators.MandatoryObject; import org.eclipse.edc.validator.jsonobject.validators.MandatoryValue; import org.eclipse.edc.validator.jsonobject.validators.OptionalIdNotBlank; @@ -41,6 +42,7 @@ import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_OR_CONSTRAINT_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PERMISSION_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_TYPE_SET; +import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PROFILE_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PROHIBITION_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_REMEDY_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_RIGHT_OPERAND_ATTRIBUTE; @@ -62,7 +64,8 @@ public static JsonObjectValidator.Builder instance(JsonObjectValidator.Builder b .verify(path -> new TypeIs(path, ODRL_POLICY_TYPE_SET)) .verifyArrayItem(ODRL_PERMISSION_ATTRIBUTE, PermissionValidator::instance) .verifyArrayItem(ODRL_OBLIGATION_ATTRIBUTE, DutyValidator::instance) - .verifyArrayItem(ODRL_PROHIBITION_ATTRIBUTE, ProhibitionValidator::instance); + .verifyArrayItem(ODRL_PROHIBITION_ATTRIBUTE, ProhibitionValidator::instance) + .verifyArrayItem(ODRL_PROFILE_ATTRIBUTE, ProfileValidator::instance); } } @@ -102,6 +105,14 @@ public static JsonObjectValidator.Builder instance(JsonObjectValidator.Builder b } + private static class ProfileValidator { + public static JsonObjectValidator.Builder instance(JsonObjectValidator.Builder builder) { + + return builder + .verify(MandatoryIdArray.min(1)); + } + } + private static class ConsequenceValidator { public static JsonObjectValidator.Builder instance(JsonObjectValidator.Builder builder) { @@ -120,7 +131,6 @@ public ValidationResult validate(JsonObject input) { .map(it -> ValidationResult.success()) .orElse(ValidationResult.failure(violation(format("%s is mandatory but missing or null", path.append(ODRL_ACTION_ATTRIBUTE)), ODRL_ACTION_ATTRIBUTE))); } - } private record ConstraintValidator(JsonLdPath path) implements Validator { diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidatorTest.java b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidatorTest.java index 8ffec6ef2e0..d4c02018fbc 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidatorTest.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidatorTest.java @@ -225,4 +225,6 @@ private JsonArrayBuilder createValidConstraint(String left, String operator, Str .add(ODRL_RIGHT_OPERAND_ATTRIBUTE, rightOperand)); } + + } diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/docs/er.puml b/extensions/control-plane/store/sql/policy-definition-store-sql/docs/er.puml index 539137d840a..a2a60a0d42c 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/docs/er.puml +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/docs/er.puml @@ -17,6 +17,7 @@ entity edc_policydefinitions { permissions: string <> prohibitions: string <> duties: string <> + profiles: string <> inherits_from: string assigner: string assignee: string diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/docs/schema.sql b/extensions/control-plane/store/sql/policy-definition-store-sql/docs/schema.sql index d4ef81277d7..291aa2444f4 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/docs/schema.sql +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/docs/schema.sql @@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS edc_policydefinitions permissions JSON, prohibitions JSON, duties JSON, + profiles JSON, extensible_properties JSON, inherits_from VARCHAR, assigner VARCHAR, @@ -34,6 +35,7 @@ CREATE TABLE IF NOT EXISTS edc_policydefinitions COMMENT ON COLUMN edc_policydefinitions.permissions IS 'Java List serialized as JSON'; COMMENT ON COLUMN edc_policydefinitions.prohibitions IS 'Java List serialized as JSON'; COMMENT ON COLUMN edc_policydefinitions.duties IS 'Java List serialized as JSON'; +COMMENT ON COLUMN edc_policydefinitions.profiles IS 'Java List serialized as JSON'; COMMENT ON COLUMN edc_policydefinitions.extensible_properties IS 'Java Map serialized as JSON'; COMMENT ON COLUMN edc_policydefinitions.policy_type IS 'Java PolicyType serialized as JSON'; diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/SqlPolicyDefinitionStore.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/SqlPolicyDefinitionStore.java index 5af8056df5c..80db71dd656 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/SqlPolicyDefinitionStore.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/SqlPolicyDefinitionStore.java @@ -53,6 +53,8 @@ public class SqlPolicyDefinitionStore extends AbstractSqlStore implements Policy }; private final TypeReference> dutyListType = new TypeReference<>() { }; + private final TypeReference> profileListType = new TypeReference<>() { + }; private final TypeReference policyType = new TypeReference<>() { }; private final TypeReference> extensiblePropertiesType = new TypeReference<>() { @@ -147,6 +149,7 @@ private void insert(PolicyDefinition def) { toJson(policy.getPermissions(), permissionListType), toJson(policy.getProhibitions(), prohibitionListType), toJson(policy.getObligations(), dutyListType), + toJson(policy.getProfiles(), profileListType), toJson(policy.getExtensibleProperties()), policy.getInheritsFrom(), policy.getAssigner(), @@ -170,6 +173,7 @@ private void updateInternal(PolicyDefinition def) { toJson(policy.getPermissions(), permissionListType), toJson(policy.getProhibitions(), prohibitionListType), toJson(policy.getObligations(), dutyListType), + toJson(policy.getProfiles(), profileListType), toJson(policy.getExtensibleProperties()), policy.getInheritsFrom(), policy.getAssigner(), @@ -189,6 +193,7 @@ private PolicyDefinition mapResultSet(ResultSet resultSet) throws SQLException { .permissions(fromJson(resultSet.getString(statements.getPermissionsColumn()), permissionListType)) .prohibitions(fromJson(resultSet.getString(statements.getProhibitionsColumn()), prohibitionListType)) .duties(fromJson(resultSet.getString(statements.getDutiesColumn()), dutyListType)) + .profiles(fromJson(resultSet.getString(statements.getProfilesColumn()), profileListType)) .extensibleProperties(fromJson(resultSet.getString(statements.getExtensiblePropertiesColumn()), extensiblePropertiesType)) .inheritsFrom(resultSet.getString(statements.getInheritsFromColumn())) .assigner(resultSet.getString(statements.getAssignerColumn())) diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/BaseSqlDialectStatements.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/BaseSqlDialectStatements.java index 58ada33571d..e3c147e663a 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/BaseSqlDialectStatements.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/BaseSqlDialectStatements.java @@ -40,6 +40,7 @@ public String getInsertTemplate() { .jsonColumn(getPermissionsColumn()) .jsonColumn(getProhibitionsColumn()) .jsonColumn(getDutiesColumn()) + .jsonColumn(getProfilesColumn()) .jsonColumn(getExtensiblePropertiesColumn()) .column(getInheritsFromColumn()) .column(getAssignerColumn()) @@ -57,6 +58,7 @@ public String getUpdateTemplate() { .jsonColumn(getPermissionsColumn()) .jsonColumn(getProhibitionsColumn()) .jsonColumn(getDutiesColumn()) + .jsonColumn(getProfilesColumn()) .jsonColumn(getExtensiblePropertiesColumn()) .column(getInheritsFromColumn()) .column(getAssignerColumn()) diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/SqlPolicyStoreStatements.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/SqlPolicyStoreStatements.java index 9daad8498ef..7f422d67056 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/SqlPolicyStoreStatements.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/SqlPolicyStoreStatements.java @@ -66,6 +66,10 @@ default String getDutiesColumn() { return "duties"; } + default String getProfilesColumn() { + return "profiles"; + } + default String getExtensiblePropertiesColumn() { return "extensible_properties"; } diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/postgres/PolicyMapping.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/postgres/PolicyMapping.java index e15321bd0f1..15ce1f458d1 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/postgres/PolicyMapping.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/postgres/PolicyMapping.java @@ -23,6 +23,7 @@ public PolicyMapping(SqlPolicyStoreStatements statements) { add("permissions", new JsonFieldTranslator(PostgresDialectStatements.PERMISSIONS_ALIAS)); add("prohibitions", new JsonFieldTranslator(PostgresDialectStatements.PROHIBITIONS_ALIAS)); add("obligations", new JsonFieldTranslator(PostgresDialectStatements.OBLIGATIONS_ALIAS)); + add("profiles", new JsonFieldTranslator(PostgresDialectStatements.PROFILES_ALIES)); add("extensibleProperties", new JsonFieldTranslator(PostgresDialectStatements.EXT_PROPERTIES_ALIAS)); add("inheritsFrom", statements.getInheritsFromColumn()); add("assigner", statements.getAssignerColumn()); diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/postgres/PostgresDialectStatements.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/postgres/PostgresDialectStatements.java index cc8433ff59e..837fa8615c6 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/postgres/PostgresDialectStatements.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/store/schema/postgres/PostgresDialectStatements.java @@ -32,6 +32,7 @@ public class PostgresDialectStatements extends BaseSqlDialectStatements { public static final String PERMISSIONS_ALIAS = "perm"; public static final String OBLIGATIONS_ALIAS = "oblig"; public static final String EXT_PROPERTIES_ALIAS = "extprop"; + public static final String PROFILES_ALIES = "prof"; private static final String PRIVATE_PROPERTIES = "privateProperties."; private static final String SELECT_QUERY = "SELECT * FROM %s"; @@ -55,6 +56,9 @@ public SqlQueryStatement createQuery(QuerySpec querySpec) { } else if (querySpec.containsAnyLeftOperand("policy.obligations")) { var select = getSelectFromJsonArrayTemplate(getSelectTemplate(), getDutiesColumn(), OBLIGATIONS_ALIAS); return new SqlQueryStatement(select, querySpec, new PolicyDefinitionMapping(this), operatorTranslator); + } else if (querySpec.containsAnyLeftOperand("policy.profiles")) { + var select = getSelectFromJsonArrayTemplate(getSelectTemplate(), getProfilesColumn(), PROFILES_ALIES); + return new SqlQueryStatement(select, querySpec, new PolicyDefinitionMapping(this), operatorTranslator); } else if (querySpec.containsAnyLeftOperand("policy.extensibleProperties")) { var select = getSelectFromJsonArrayTemplate(getSelectTemplate(), getExtensiblePropertiesColumn(), EXT_PROPERTIES_ALIAS); return new SqlQueryStatement(select, querySpec, new PolicyDefinitionMapping(this), operatorTranslator); diff --git a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java index 2e01357627a..913aa7283c8 100644 --- a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java +++ b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/PropertyAndTypeNames.java @@ -78,6 +78,7 @@ public interface PropertyAndTypeNames { String ODRL_OR_CONSTRAINT_ATTRIBUTE = ODRL_SCHEMA + "or"; String ODRL_XONE_CONSTRAINT_ATTRIBUTE = ODRL_SCHEMA + "xone"; String ODRL_USE_ACTION_ATTRIBUTE = ODRL_SCHEMA + "use"; + String ODRL_PROFILE_ATTRIBUTE = ODRL_SCHEMA + "profile"; String DSPACE_PROPERTY_PARTICIPANT_ID = DSPACE_SCHEMA + "participantId"; } diff --git a/spi/common/policy-model/src/main/java/org/eclipse/edc/policy/model/Policy.java b/spi/common/policy-model/src/main/java/org/eclipse/edc/policy/model/Policy.java index 1fb5fa7829f..8f9e2a0f373 100644 --- a/spi/common/policy-model/src/main/java/org/eclipse/edc/policy/model/Policy.java +++ b/spi/common/policy-model/src/main/java/org/eclipse/edc/policy/model/Policy.java @@ -36,11 +36,13 @@ public class Policy { private final List permissions = new ArrayList<>(); private final List prohibitions = new ArrayList<>(); private final List obligations = new ArrayList<>(); + private final List profiles = new ArrayList<>(); private final Map extensibleProperties = new HashMap<>(); private String inheritsFrom; private String assigner; private String assignee; private String target; + @JsonProperty("@type") private PolicyType type = PolicyType.SET; @@ -59,6 +61,10 @@ public List getObligations() { return obligations; } + public List getProfiles() { + return profiles; + } + @Nullable public String getInheritsFrom() { return inheritsFrom; @@ -102,7 +108,7 @@ public boolean equals(Object o) { return false; } Policy policy = (Policy) o; - return permissions.equals(policy.permissions) && prohibitions.equals(policy.prohibitions) && obligations.equals(policy.obligations) && extensibleProperties.equals(policy.extensibleProperties) && + return permissions.equals(policy.permissions) && prohibitions.equals(policy.prohibitions) && obligations.equals(policy.obligations) && profiles.equals(policy.profiles) && extensibleProperties.equals(policy.extensibleProperties) && Objects.equals(inheritsFrom, policy.inheritsFrom) && Objects.equals(assigner, policy.assigner) && Objects.equals(assignee, policy.assignee) && Objects.equals(target, policy.target) && type == policy.type; } @@ -123,6 +129,7 @@ public Policy withTarget(String target) { .type(type) .extensibleProperties(extensibleProperties) .target(target) + .profiles(profiles) .build(); } @@ -139,7 +146,8 @@ public Builder toBuilder() { .inheritsFrom(inheritsFrom) .type(type) .extensibleProperties(extensibleProperties) - .target(target); + .target(target) + .profiles(profiles); } public interface Visitor { @@ -178,6 +186,12 @@ public Builder permissions(List permissions) { return this; } + + public Builder profiles(List profiles) { + policy.profiles.addAll(profiles); + return this; + } + public Builder duty(Duty duty) { policy.obligations.add(duty); return this; From a9900b60aecb93c4edfd2eb11839bbc2291abc30 Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Fri, 24 May 2024 12:12:44 +0200 Subject: [PATCH 02/13] feat(api, spi, storage): validator fix and tests Signed-off-by: Sascha Isele --- ...atoryIdArray.java => OptionalIdArray.java} | 24 +++--- .../jsonobject/JsonObjectValidatorTest.java | 10 +-- .../validation/PolicyDefinitionValidator.java | 16 ++-- .../PolicyDefinitionValidatorTest.java | 83 +++++++++++++++++++ 4 files changed, 111 insertions(+), 22 deletions(-) rename core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/{MandatoryIdArray.java => OptionalIdArray.java} (69%) diff --git a/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/MandatoryIdArray.java b/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/OptionalIdArray.java similarity index 69% rename from core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/MandatoryIdArray.java rename to core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/OptionalIdArray.java index e72df51128d..ae67e651686 100644 --- a/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/MandatoryIdArray.java +++ b/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/OptionalIdArray.java @@ -29,23 +29,23 @@ import static org.eclipse.edc.validator.spi.Violation.violation; /** - * Verifies that an array is present and the key:value pairs are of type @id:string with optional constraint on min size. + * Verifies that if an array is present the key:value pairs are of type @id:string with optional constraint on min size. */ -public class MandatoryIdArray implements Validator { +public class OptionalIdArray implements Validator { private final JsonLdPath path; private final Integer min; - public MandatoryIdArray(JsonLdPath path) { + public OptionalIdArray(JsonLdPath path) { this(path, null); } - public MandatoryIdArray(JsonLdPath path, Integer min) { + public OptionalIdArray(JsonLdPath path, Integer min) { this.path = path; this.min = min; } public static Function> min(Integer min) { - return path -> new MandatoryArray(path, min); + return path -> new OptionalIdArray(path, min); } @Override @@ -54,13 +54,13 @@ public ValidationResult validate(JsonObject input) { sizeResult = Optional.ofNullable(input.getJsonArray(path.last())) .map(this::validateMin) - .orElse(ValidationResult.failure(violation(format("mandatory array '%s' is missing", path), path.toString()))); + .orElse(ValidationResult.success()); if (sizeResult.failed()) return sizeResult; return Optional.ofNullable(input.getJsonArray(path.last())) .map(this::validateType) - .orElse(ValidationResult.failure(violation(format("mandatory array '%s' is missing", path), path.toString()))); + .orElse(ValidationResult.success()); } private ValidationResult validateMin(JsonArray array) { @@ -72,9 +72,13 @@ private ValidationResult validateMin(JsonArray array) { private ValidationResult validateType(JsonArray array) { for (JsonValue value : array) { - var id = value.asJsonObject().getJsonString(ID); - if (id == null || id.getString().isBlank()) { - return ValidationResult.failure(violation(format("contents of array '%s' should be of type string and not blank", path), path.toString())); + try { + var id = value.asJsonObject().getJsonString(ID); + if (id == null || id.getString().isBlank() || id.getString().isEmpty()) { + return ValidationResult.failure(violation(format("contents of array '%s' should not be blank or empty", path), path.toString())); + } + } catch (ClassCastException e) { + return ValidationResult.failure(violation(format("contents of array '%s' should be of type string", path), path.toString())); } } return ValidationResult.success(); diff --git a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java index 454d6d59399..e72eb12601f 100644 --- a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java +++ b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java @@ -16,8 +16,8 @@ import jakarta.json.JsonArrayBuilder; import org.eclipse.edc.validator.jsonobject.validators.MandatoryArray; +import org.eclipse.edc.validator.jsonobject.validators.OptionalIdArray; import org.eclipse.edc.validator.jsonobject.validators.MandatoryObject; -import org.eclipse.edc.validator.jsonobject.validators.MandatoryIdArray; import org.eclipse.edc.validator.jsonobject.validators.MandatoryValue; import org.eclipse.edc.validator.jsonobject.validators.OptionalIdNotBlank; import org.eclipse.edc.validator.spi.ValidationFailure; @@ -227,7 +227,7 @@ void shouldFail_ValidateMandatoryIdArrayMinSize() { ); var result = JsonObjectValidator.newValidator() - .verify("arrayProperty", MandatoryIdArray.min(3)) + .verify("arrayProperty", OptionalIdArray.min(3)) .build() .validate(input.build()); @@ -243,7 +243,7 @@ void shouldFail_ValidateMandatoryIdArrayNoValue() { var input = createObjectBuilder(); var result = JsonObjectValidator.newValidator() - .verify("arrayProperty", MandatoryIdArray::new) + .verify("arrayProperty", OptionalIdArray::new) .build() .validate(input.build()); @@ -262,7 +262,7 @@ void shouldFail_ValidateMandatoryIdArrayWrongType() { ); var result = JsonObjectValidator.newValidator() - .verify("arrayProperty", MandatoryIdArray::new) + .verify("arrayProperty", OptionalIdArray::new) .build() .validate(input.build()); @@ -282,7 +282,7 @@ void shouldSucceed_ValidateMandatoryIdArray() { ); var result = JsonObjectValidator.newValidator() - .verify("arrayProperty", MandatoryIdArray::new) + .verify("arrayProperty", OptionalIdArray::new) .build() .validate(input.build()); diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidator.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidator.java index 8dca7042562..28af76118c3 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidator.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidator.java @@ -17,9 +17,9 @@ import jakarta.json.JsonObject; import org.eclipse.edc.validator.jsonobject.JsonLdPath; import org.eclipse.edc.validator.jsonobject.JsonObjectValidator; -import org.eclipse.edc.validator.jsonobject.validators.MandatoryIdArray; import org.eclipse.edc.validator.jsonobject.validators.MandatoryObject; import org.eclipse.edc.validator.jsonobject.validators.MandatoryValue; +import org.eclipse.edc.validator.jsonobject.validators.OptionalIdArray; import org.eclipse.edc.validator.jsonobject.validators.OptionalIdNotBlank; import org.eclipse.edc.validator.jsonobject.validators.TypeIs; import org.eclipse.edc.validator.spi.ValidationResult; @@ -65,7 +65,7 @@ public static JsonObjectValidator.Builder instance(JsonObjectValidator.Builder b .verifyArrayItem(ODRL_PERMISSION_ATTRIBUTE, PermissionValidator::instance) .verifyArrayItem(ODRL_OBLIGATION_ATTRIBUTE, DutyValidator::instance) .verifyArrayItem(ODRL_PROHIBITION_ATTRIBUTE, ProhibitionValidator::instance) - .verifyArrayItem(ODRL_PROFILE_ATTRIBUTE, ProfileValidator::instance); + .verify(ProfileValidator::new); } } @@ -105,11 +105,13 @@ public static JsonObjectValidator.Builder instance(JsonObjectValidator.Builder b } - private static class ProfileValidator { - public static JsonObjectValidator.Builder instance(JsonObjectValidator.Builder builder) { - - return builder - .verify(MandatoryIdArray.min(1)); + private record ProfileValidator(JsonLdPath path) implements Validator { + @Override + public ValidationResult validate(JsonObject input) { + return JsonObjectValidator.newValidator() + .verify(ODRL_PROFILE_ATTRIBUTE, OptionalIdArray.min(1)) + .build() + .validate(input); } } diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidatorTest.java b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidatorTest.java index d4c02018fbc..fe3f6881a1a 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidatorTest.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/validation/PolicyDefinitionValidatorTest.java @@ -36,6 +36,7 @@ import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_OPERATOR_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PERMISSION_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_TYPE_SET; +import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PROFILE_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_RIGHT_OPERAND_ATTRIBUTE; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; @@ -201,6 +202,88 @@ void shouldSucceed_whenLogicalConstraintIsPresent() { assertThat(result).isSucceeded(); } + @Test + void shouldSucceed_whenProfileIsPresent() { + var policy = createObjectBuilder() + .add(TYPE, policySet()) + .add(ODRL_PROFILE_ATTRIBUTE, createArrayBuilder().add(createObjectBuilder().add(ID, "value1"))); + var policyDefinition = createObjectBuilder() + .add(EDC_POLICY_DEFINITION_POLICY, createArrayBuilder().add(policy)) + .build(); + + var result = validator.validate(policyDefinition); + + assertThat(result).isSucceeded(); + } + + @Test + void shouldFail_whenProfileIsWrongType() { + var policy = createObjectBuilder() + .add(TYPE, policySet()) + .add(ODRL_PROFILE_ATTRIBUTE, createArrayBuilder().add(createObjectBuilder().add(ID, createObjectBuilder()))); + var policyDefinition = createObjectBuilder() + .add(EDC_POLICY_DEFINITION_POLICY, createArrayBuilder().add(policy)) + .build(); + + var result = validator.validate(policyDefinition); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .filteredOn(it -> ODRL_PROFILE_ATTRIBUTE.equals(it.path())) + .anySatisfy(violation -> assertThat(violation.message()).contains("type")); + } + + @Test + void shouldFail_whenProfileIsEmptyArray() { + var policy = createObjectBuilder() + .add(TYPE, policySet()) + .add(ODRL_PROFILE_ATTRIBUTE, createArrayBuilder()); + var policyDefinition = createObjectBuilder() + .add(EDC_POLICY_DEFINITION_POLICY, createArrayBuilder().add(policy)) + .build(); + + var result = validator.validate(policyDefinition); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .filteredOn(it -> ODRL_PROFILE_ATTRIBUTE.equals(it.path())) + .anySatisfy(violation -> assertThat(violation.message()).contains("elements")); + } + + @Test + void shouldFail_whenProfileIsBlank() { + var policy = createObjectBuilder() + .add(TYPE, policySet()) + .add(ODRL_PROFILE_ATTRIBUTE, createArrayBuilder().add(createObjectBuilder().add(ID, " "))); + var policyDefinition = createObjectBuilder() + .add(EDC_POLICY_DEFINITION_POLICY, createArrayBuilder().add(policy)) + .build(); + + var result = validator.validate(policyDefinition); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .filteredOn(it -> ODRL_PROFILE_ATTRIBUTE.equals(it.path())) + .anySatisfy(violation -> assertThat(violation.message()).contains("blank")); + } + + @Test + void shouldFail_whenProfileIsEmpty() { + var policy = createObjectBuilder() + .add(TYPE, policySet()) + .add(ODRL_PROFILE_ATTRIBUTE, createArrayBuilder().add(createObjectBuilder().add(ID, ""))); + var policyDefinition = createObjectBuilder() + .add(EDC_POLICY_DEFINITION_POLICY, createArrayBuilder().add(policy)) + .build(); + + var result = validator.validate(policyDefinition); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .filteredOn(it -> ODRL_PROFILE_ATTRIBUTE.equals(it.path())) + .anySatisfy(violation -> assertThat(violation.message()).contains("empty")); + } + private JsonArrayBuilder policySet() { return createArrayBuilder().add(ODRL_POLICY_TYPE_SET); } From ebcb0851a0370e9edc0eed332f58cf4e27a5f18a Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Fri, 24 May 2024 12:20:29 +0200 Subject: [PATCH 03/13] feat(api, spi, storage): checkstyle fix Signed-off-by: Sascha Isele --- .../edc/validator/jsonobject/JsonObjectValidatorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java index e72eb12601f..c12dfef6189 100644 --- a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java +++ b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java @@ -16,9 +16,9 @@ import jakarta.json.JsonArrayBuilder; import org.eclipse.edc.validator.jsonobject.validators.MandatoryArray; -import org.eclipse.edc.validator.jsonobject.validators.OptionalIdArray; import org.eclipse.edc.validator.jsonobject.validators.MandatoryObject; import org.eclipse.edc.validator.jsonobject.validators.MandatoryValue; +import org.eclipse.edc.validator.jsonobject.validators.OptionalIdArray; import org.eclipse.edc.validator.jsonobject.validators.OptionalIdNotBlank; import org.eclipse.edc.validator.spi.ValidationFailure; import org.eclipse.edc.validator.spi.Violation; From 0254938656d86d3489b8ae7592e0dbca7464a57a Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Fri, 24 May 2024 12:40:48 +0200 Subject: [PATCH 04/13] feat(api, spi, storage): object validator test fix Signed-off-by: Sascha Isele --- .../jsonobject/JsonObjectValidatorTest.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java index c12dfef6189..60de39d8715 100644 --- a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java +++ b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java @@ -219,7 +219,7 @@ void shouldFail_whenInputIsNull() { } @Test - void shouldFail_ValidateMandatoryIdArrayMinSize() { + void shouldFail_ValidateOptionalIdArrayMinSize() { var input = createObjectBuilder() .add("arrayProperty", createArrayBuilder() .add(createObjectBuilder().add(ID, "value1")) @@ -239,7 +239,7 @@ void shouldFail_ValidateMandatoryIdArrayMinSize() { } @Test - void shouldFail_ValidateMandatoryIdArrayNoValue() { + void shouldSucceed_ValidateOptionalIdArrayNoValue() { var input = createObjectBuilder(); var result = JsonObjectValidator.newValidator() @@ -247,15 +247,11 @@ void shouldFail_ValidateMandatoryIdArrayNoValue() { .build() .validate(input.build()); - assertThat(result).isFailed().satisfies(failure -> { - assertThat(failure.getViolations()).anySatisfy(violation -> { - assertThat(violation.path()).contains("arrayProperty"); - }); - }); + assertThat(result).isSucceeded(); } @Test - void shouldFail_ValidateMandatoryIdArrayWrongType() { + void shouldFail_ValidateOptionalIdArrayWrongType() { var input = createObjectBuilder() .add("arrayProperty", createArrayBuilder() .add(createObjectBuilder().add("subProperty", createObjectBuilder())) @@ -274,7 +270,7 @@ void shouldFail_ValidateMandatoryIdArrayWrongType() { } @Test - void shouldSucceed_ValidateMandatoryIdArray() { + void shouldSucceed_ValidateOptionalIdArray() { var input = createObjectBuilder() .add("arrayProperty", createArrayBuilder() .add(createObjectBuilder().add(ID, "value1")) From 067af769c75e680f7e82e87cbae999c04adcb41c Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Thu, 4 Jul 2024 12:06:06 +0200 Subject: [PATCH 05/13] feat(api, spi, storage): transformer for id array Signed-off-by: Sascha Isele --- .../to/JsonObjectToPolicyTransformer.java | 2 +- .../to/JsonObjectToPolicyTransformerTest.java | 35 ++++++++++++ .../AbstractJsonLdTransformer.java | 57 +++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java b/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java index c52b02b4b3b..6b76ff0a3d9 100644 --- a/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java +++ b/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java @@ -92,7 +92,7 @@ public JsonObjectToPolicyTransformer(ParticipantIdMapper participantIdMapper) { case ODRL_TARGET_ATTRIBUTE -> v -> builder.target(transformString(v, context)); case ODRL_ASSIGNER_ATTRIBUTE -> v -> builder.assigner(participantIdMapper.fromIri(transformString(v, context))); case ODRL_ASSIGNEE_ATTRIBUTE -> v -> builder.assignee(participantIdMapper.fromIri(transformString(v, context))); - case ODRL_PROFILE_ATTRIBUTE -> v -> builder.profiles(transformArray(v, String.class, context)); + case ODRL_PROFILE_ATTRIBUTE -> v -> builder.profiles(transformIdStringArray(v, context)); default -> v -> builder.extensibleProperty(key, transformGenericProperty(v, context)); }); diff --git a/core/control-plane/control-plane-transform/src/test/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformerTest.java b/core/control-plane/control-plane-transform/src/test/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformerTest.java index 5cb46997f9d..45fe1c362a7 100644 --- a/core/control-plane/control-plane-transform/src/test/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformerTest.java +++ b/core/control-plane/control-plane-transform/src/test/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformerTest.java @@ -40,7 +40,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VALUE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_ASSIGNEE_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_ASSIGNER_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_OBLIGATION_ATTRIBUTE; @@ -48,6 +50,7 @@ import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_TYPE_AGREEMENT; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_TYPE_OFFER; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_TYPE_SET; +import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PROFILE_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_PROHIBITION_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_TARGET_ATTRIBUTE; import static org.eclipse.edc.policy.model.PolicyType.CONTRACT; @@ -185,6 +188,38 @@ void shouldGetTypeFromContext_whenSet() { assertThat(result.getType()).isEqualTo(CONTRACT); } + @Test + void transform_withProfile() { + + var policy = jsonFactory.createObjectBuilder() + .add(TYPE, ODRL_POLICY_TYPE_SET) + .add(ODRL_PROFILE_ATTRIBUTE, jsonFactory.createObjectBuilder().add(ID, "http://example.com/odrl:profile:01")) + .build(); + + var result = transformer.transform(TestInput.getExpanded(policy), context); + + assertThat(result).isNotNull(); + assertThat(result.getProfiles().get(0)).isEqualTo("http://example.com/odrl:profile:01"); + verify(context, never()).reportProblem(anyString()); + } + + @Test + void transform_withInvalidProfile() { + + var policy = jsonFactory.createObjectBuilder() + .add(TYPE, ODRL_POLICY_TYPE_SET) + .add(ODRL_PROFILE_ATTRIBUTE, jsonFactory.createObjectBuilder().add(VALUE, "http://example.com/odrl:profile:01")) + .build(); + + when(context.problem()).thenReturn(new ProblemBuilder(context)); + + var result = transformer.transform(TestInput.getExpanded(policy), context); + + assertThat(result).isNotNull(); + assertThat(result.getProfiles()).isEmpty(); + verify(context).reportProblem(anyString()); + } + private static class PolicyTypeArguments implements ArgumentsProvider { @Override diff --git a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java index 30959777bc2..2ca76745816 100644 --- a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java +++ b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -39,10 +40,12 @@ import static jakarta.json.JsonValue.ValueType.FALSE; import static jakarta.json.JsonValue.ValueType.NUMBER; import static jakarta.json.JsonValue.ValueType.OBJECT; +import static jakarta.json.JsonValue.ValueType.STRING; import static jakarta.json.JsonValue.ValueType.TRUE; import static java.lang.String.format; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; /** * Base JSON-LD transformer implementation. @@ -280,6 +283,60 @@ protected String transformString(JsonValue value, TransformerContext context) { } } + /** + * Transforms a JsonValue to a list of strings. If the value parameter is not of type JsonString, JsonObject or JsonArray, + * a problem is reported to the context. + * + * @param value the value to transform + * @param context the transformer context + * @return the string list result + */ + @Nullable + protected List transformIdStringArray(JsonValue value, TransformerContext context) { + List result = new ArrayList<>(); + if (value instanceof JsonString) { + result.add(((JsonString) value).getString()); + return result; + } + if (value instanceof JsonObject) { + var object = value.asJsonObject(); + var id = nodeId(object); + if (id == null) { + context.problem() + .unexpectedType() + .expected(ID) + .report(); + return result; + } + result.add(id); + return result; + } + if (value instanceof JsonArray) { + result = value.asJsonArray().stream() + .map(this::nodeId) + .filter(Objects::nonNull) + .collect(toList()); + if (result.isEmpty()) { + context.problem() + .unexpectedType() + .expected(ID) + .report(); + return result; + } + return result; + } + if (value != null) { + context.problem() + .unexpectedType() + .actual(value.getValueType()) + .expected(STRING) + .expected(OBJECT) + .expected(ARRAY) + .report(); + } + return null; + } + /** * Transforms a JsonValue to int. If the value parameter is not of type JsonNumber, JsonObject or JsonArray, a problem is reported to the context. * From 00bb3f9c355fd1ecacaeb739a400e3f641891da6 Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Tue, 9 Jul 2024 09:41:21 +0200 Subject: [PATCH 06/13] feat(api, spi, storage): transformer fix Signed-off-by: Sascha Isele --- .../edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java index 2ca76745816..f1e669580b0 100644 --- a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java +++ b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java @@ -285,7 +285,7 @@ protected String transformString(JsonValue value, TransformerContext context) { /** * Transforms a JsonValue to a list of strings. If the value parameter is not of type JsonString, JsonObject or JsonArray, - * a problem is reported to the context. + * a problem is reported to the context and an empty list is returned. * * @param value the value to transform * @param context the transformer context @@ -334,7 +334,7 @@ protected List transformIdStringArray(JsonValue value, TransformerContex .expected(ARRAY) .report(); } - return null; + return result; } /** From d499bf0c360a1d0f84714d5de344c9e1e9a6b591 Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Tue, 9 Jul 2024 15:59:38 +0200 Subject: [PATCH 07/13] feat(api, spi, storage): api versioning timestamp Signed-off-by: Sascha Isele --- .../src/main/resources/management-api-version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json b/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json index 04da0949518..af26bce658c 100644 --- a/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json +++ b/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json @@ -8,7 +8,7 @@ { "version": "3.1.0-alpha", "urlPath": "/v3.1alpha", - "lastUpdated": "2024-07-09T09:17:00Z", + "lastUpdated": "2024-07-09T15:58:00Z", "maturity": "alpha" } ] From c563e0aa2ee127813703c0ba946d8befc1c307f1 Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Tue, 9 Jul 2024 17:38:56 +0200 Subject: [PATCH 08/13] feat(api, spi, storage): v31alpha package for profile Signed-off-by: Sascha Isele --- .../resources/management-api-version.json | 2 +- .../policy/v3/PolicyDefinitionApiV3.java | 1 - .../v31alpha/PolicyDefinitionApiV31Alpha.java | 171 ++++++++++++++++++ ...PolicyDefinitionApiV31AlphaController.java | 76 ++++++++ ...cyDefinitionApiV31AlphaControllerTest.java | 36 ++++ 5 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31Alpha.java create mode 100644 extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaController.java create mode 100644 extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java diff --git a/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json b/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json index af26bce658c..5ff6dfd239a 100644 --- a/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json +++ b/extensions/common/api/management-api-configuration/src/main/resources/management-api-version.json @@ -8,7 +8,7 @@ { "version": "3.1.0-alpha", "urlPath": "/v3.1alpha", - "lastUpdated": "2024-07-09T15:58:00Z", + "lastUpdated": "2024-07-09T17:23:00Z", "maturity": "alpha" } ] diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v3/PolicyDefinitionApiV3.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v3/PolicyDefinitionApiV3.java index 9e0de101307..1d2f588ce4c 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v3/PolicyDefinitionApiV3.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v3/PolicyDefinitionApiV3.java @@ -119,7 +119,6 @@ record PolicyDefinitionInputSchema( "@context": "http://www.w3.org/ns/odrl.jsonld", "@type": "Set", "uid": "http://example.com/policy:1010", - "profile": "http://example.com/odrl:profile:02", "permission": [{ "target": "http://example.com/asset:9898.movie", "action": "display", diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31Alpha.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31Alpha.java new file mode 100644 index 00000000000..74ded0b91cf --- /dev/null +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31Alpha.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * 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 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.connector.controlplane.api.management.policy.v31alpha; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import org.eclipse.edc.api.management.schema.ManagementApiSchema; +import org.eclipse.edc.api.model.ApiCoreSchema; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; +import static org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; + +@OpenAPIDefinition(info = @Info(version = "v3.1-alpha")) +@Tag(name = "Policy Definition v3.1-alpha") +public interface PolicyDefinitionApiV31Alpha { + + @Operation(description = "Returns all policy definitions according to a query", + requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ApiCoreSchema.QuerySpecSchema.class))), + responses = { + @ApiResponse(responseCode = "200", description = "The policy definitions matching the query", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = PolicyDefinitionOutputSchema.class)))), + @ApiResponse(responseCode = "400", description = "Request was malformed", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) } + ) + JsonArray queryPolicyDefinitionsV3(JsonObject querySpecJson); + + @Operation(description = "Gets a policy definition with the given ID", + responses = { + @ApiResponse(responseCode = "200", description = "The policy definition", + content = @Content(schema = @Schema(implementation = PolicyDefinitionOutputSchema.class))), + @ApiResponse(responseCode = "400", description = "Request was malformed, e.g. id was null", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), + @ApiResponse(responseCode = "404", description = "An policy definition with the given ID does not exist", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) + } + ) + JsonObject getPolicyDefinitionV3(String id); + + @Operation(description = "Creates a new policy definition", + requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = PolicyDefinitionInputSchema.class))), + responses = { + @ApiResponse(responseCode = "200", description = "policy definition was created successfully. Returns the Policy Definition Id and created timestamp", + content = @Content(schema = @Schema(implementation = ApiCoreSchema.IdResponseSchema.class))), + @ApiResponse(responseCode = "400", description = "Request body was malformed", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), + @ApiResponse(responseCode = "409", description = "Could not create policy definition, because a contract definition with that ID already exists", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) } + ) + JsonObject createPolicyDefinitionV3(JsonObject policyDefinition); + + @Operation(description = "Removes a policy definition with the given ID if possible. Deleting a policy definition is " + + "only possible if that policy definition is not yet referenced by a contract definition, in which case an error is returned. " + + "DANGER ZONE: Note that deleting policy definitions can have unexpected results, do this at your own risk!", + responses = { + @ApiResponse(responseCode = "204", description = "Policy definition was deleted successfully"), + @ApiResponse(responseCode = "400", description = "Request was malformed, e.g. id was null", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), + @ApiResponse(responseCode = "404", description = "An policy definition with the given ID does not exist", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), + @ApiResponse(responseCode = "409", description = "The policy definition cannot be deleted, because it is referenced by a contract definition", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) + } + ) + void deletePolicyDefinitionV3(String id); + + @Operation(description = "Updates an existing Policy, If the Policy is not found, an error is reported", + requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = PolicyDefinitionInputSchema.class))), + responses = { + @ApiResponse(responseCode = "204", description = "policy definition was updated successfully."), + @ApiResponse(responseCode = "400", description = "Request body was malformed", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), + @ApiResponse(responseCode = "404", description = "policy definition could not be updated, because it does not exists", + content = @Content(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class))) + } + ) + void updatePolicyDefinitionV3(String id, JsonObject policyDefinition); + + @Schema(name = "PolicyDefinitionInput", example = PolicyDefinitionInputSchema.POLICY_DEFINITION_INPUT_EXAMPLE) + record PolicyDefinitionInputSchema( + @Schema(name = CONTEXT, requiredMode = REQUIRED) + Object context, + @Schema(name = ID) + String id, + @Schema(name = TYPE, example = EDC_POLICY_DEFINITION_TYPE) + String type, + @Schema(requiredMode = REQUIRED) + ManagementApiSchema.PolicySchema policy) { + + // policy example took from https://w3c.github.io/odrl/bp/ + public static final String POLICY_DEFINITION_INPUT_EXAMPLE = """ + { + "@context": { "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, + "@id": "definition-id", + "policy": { + "@context": "http://www.w3.org/ns/odrl.jsonld", + "@type": "Set", + "uid": "http://example.com/policy:1010", + "profile": "http://example.com/odrl:profile:02", + "permission": [{ + "target": "http://example.com/asset:9898.movie", + "action": "display", + "constraint": [{ + "leftOperand": "spatial", + "operator": "eq", + "rightOperand": "https://www.wikidata.org/wiki/Q183", + "comment": "i.e Germany" + }] + }] + } + } + """; + } + + @Schema(name = "PolicyDefinitionOutput", example = PolicyDefinitionOutputSchema.POLICY_DEFINITION_OUTPUT_EXAMPLE) + record PolicyDefinitionOutputSchema( + @Schema(name = ID) + String id, + @Schema(name = TYPE, example = EDC_POLICY_DEFINITION_TYPE) + String type, + ManagementApiSchema.PolicySchema policy) { + + // policy example took from https://w3c.github.io/odrl/bp/ + public static final String POLICY_DEFINITION_OUTPUT_EXAMPLE = """ + { + "@context": { "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, + "@id": "definition-id", + "policy": { + "@context": "http://www.w3.org/ns/odrl.jsonld", + "@type": "Set", + "uid": "http://example.com/policy:1010", + "permission": [{ + "target": "http://example.com/asset:9898.movie", + "action": "display", + "constraint": [{ + "leftOperand": "spatial", + "operator": "eq", + "rightOperand": "https://www.wikidata.org/wiki/Q183", + "comment": "i.e Germany" + }] + }] + }, + "createdAt": 1688465655 + } + """; + } + +} diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaController.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaController.java new file mode 100644 index 00000000000..e20b9a1185e --- /dev/null +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaController.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * 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 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.connector.controlplane.api.management.policy.v31alpha; + +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import org.eclipse.edc.connector.controlplane.api.management.policy.BasePolicyDefinitionApiController; +import org.eclipse.edc.connector.controlplane.services.spi.policydefinition.PolicyDefinitionService; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; + +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; + +@Consumes(APPLICATION_JSON) +@Produces(APPLICATION_JSON) +@Path("/v3.1alpha/policydefinitions") +public class PolicyDefinitionApiV31AlphaController extends BasePolicyDefinitionApiController implements PolicyDefinitionApiV31Alpha { + public PolicyDefinitionApiV31AlphaController(Monitor monitor, TypeTransformerRegistry transformerRegistry, PolicyDefinitionService service, JsonObjectValidatorRegistry validatorRegistry) { + super(monitor, transformerRegistry, service, validatorRegistry); + } + + @POST + @Path("request") + @Override + public JsonArray queryPolicyDefinitionsV3(JsonObject querySpecJson) { + return queryPolicyDefinitions(querySpecJson); + } + + @GET + @Path("{id}") + @Override + public JsonObject getPolicyDefinitionV3(@PathParam("id") String id) { + return getPolicyDefinition(id); + } + + @POST + @Override + public JsonObject createPolicyDefinitionV3(JsonObject request) { + return createPolicyDefinition(request); + } + + @DELETE + @Path("{id}") + @Override + public void deletePolicyDefinitionV3(@PathParam("id") String id) { + deletePolicyDefinition(id); + } + + @PUT + @Path("{id}") + @Override + public void updatePolicyDefinitionV3(@PathParam("id") String id, JsonObject input) { + updatePolicyDefinition(id, input); + } +} diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java new file mode 100644 index 00000000000..93cbd4bba9e --- /dev/null +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * 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 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.connector.controlplane.api.management.policy.v31alpha; + +import io.restassured.specification.RequestSpecification; +import org.eclipse.edc.connector.controlplane.api.management.policy.BasePolicyDefinitionApiControllerTest; + +import static io.restassured.RestAssured.given; + +public class PolicyDefinitionApiV31AlphaControllerTest extends BasePolicyDefinitionApiControllerTest { + + @Override + protected Object controller() { + return new PolicyDefinitionApiV31AlphaController(monitor, transformerRegistry, service, validatorRegistry); + } + + @Override + protected RequestSpecification baseRequest() { + return given() + .baseUri("http://localhost:%d/v3/policydefinitions".formatted(port)) + .port(port); + } + +} From bc22a6d3624b842b42f122494cb06a3f0fc6366c Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Wed, 10 Jul 2024 08:52:59 +0200 Subject: [PATCH 09/13] feat(api, spi, storage): v31alpha test fix Signed-off-by: Sascha Isele --- .../v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java index 93cbd4bba9e..a17d92a25ea 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/controlplane/api/management/policy/v31alpha/PolicyDefinitionApiV31AlphaControllerTest.java @@ -29,7 +29,7 @@ protected Object controller() { @Override protected RequestSpecification baseRequest() { return given() - .baseUri("http://localhost:%d/v3/policydefinitions".formatted(port)) + .baseUri("http://localhost:%d/v3.1alpha/policydefinitions".formatted(port)) .port(port); } From 244d0e308007a05c7ada7aff6c1b5f44011a2521 Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Wed, 10 Jul 2024 09:51:04 +0200 Subject: [PATCH 10/13] feat(api, spi, storage): review suggestions Signed-off-by: Sascha Isele --- .../validators/OptionalIdArray.java | 9 +- .../jsonobject/JsonObjectValidatorTest.java | 129 +++++++++--------- .../to/JsonObjectToPolicyTransformer.java | 12 +- .../AbstractJsonLdTransformer.java | 57 -------- .../spi/testfixtures/TestFunctions.java | 10 ++ .../store/PolicyDefinitionStoreTestBase.java | 30 +++- 6 files changed, 116 insertions(+), 131 deletions(-) diff --git a/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/OptionalIdArray.java b/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/OptionalIdArray.java index ae67e651686..0e69aa10a02 100644 --- a/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/OptionalIdArray.java +++ b/core/common/lib/validator-lib/src/main/java/org/eclipse/edc/validator/jsonobject/validators/OptionalIdArray.java @@ -16,7 +16,6 @@ import jakarta.json.JsonArray; import jakarta.json.JsonObject; -import jakarta.json.JsonValue; import org.eclipse.edc.validator.jsonobject.JsonLdPath; import org.eclipse.edc.validator.spi.ValidationResult; import org.eclipse.edc.validator.spi.Validator; @@ -56,7 +55,9 @@ public ValidationResult validate(JsonObject input) { .map(this::validateMin) .orElse(ValidationResult.success()); - if (sizeResult.failed()) return sizeResult; + if (sizeResult.failed()) { + return sizeResult; + } return Optional.ofNullable(input.getJsonArray(path.last())) .map(this::validateType) @@ -71,10 +72,10 @@ private ValidationResult validateMin(JsonArray array) { } private ValidationResult validateType(JsonArray array) { - for (JsonValue value : array) { + for (var value : array) { try { var id = value.asJsonObject().getJsonString(ID); - if (id == null || id.getString().isBlank() || id.getString().isEmpty()) { + if (id == null || id.getString().isBlank()) { return ValidationResult.failure(violation(format("contents of array '%s' should not be blank or empty", path), path.toString())); } } catch (ClassCastException e) { diff --git a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java index 60de39d8715..aa156079c3b 100644 --- a/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java +++ b/core/common/lib/validator-lib/src/test/java/org/eclipse/edc/validator/jsonobject/JsonObjectValidatorTest.java @@ -22,6 +22,7 @@ import org.eclipse.edc.validator.jsonobject.validators.OptionalIdNotBlank; import org.eclipse.edc.validator.spi.ValidationFailure; import org.eclipse.edc.validator.spi.Violation; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import static jakarta.json.Json.createArrayBuilder; @@ -218,72 +219,76 @@ void shouldFail_whenInputIsNull() { }); } - @Test - void shouldFail_ValidateOptionalIdArrayMinSize() { - var input = createObjectBuilder() - .add("arrayProperty", createArrayBuilder() - .add(createObjectBuilder().add(ID, "value1")) - .add(createObjectBuilder().add(ID, "value2")) - ); - - var result = JsonObjectValidator.newValidator() - .verify("arrayProperty", OptionalIdArray.min(3)) - .build() - .validate(input.build()); - - assertThat(result).isFailed().satisfies(failure -> { - assertThat(failure.getViolations()).anySatisfy(violation -> { - assertThat(violation.path()).contains("arrayProperty"); + @Nested + class TestOptionalIdArray { + @Test + void shouldFail_ValidateOptionalIdArrayMinSize() { + var input = createObjectBuilder() + .add("arrayProperty", createArrayBuilder() + .add(createObjectBuilder().add(ID, "value1")) + .add(createObjectBuilder().add(ID, "value2")) + ); + + var result = JsonObjectValidator.newValidator() + .verify("arrayProperty", OptionalIdArray.min(3)) + .build() + .validate(input.build()); + + assertThat(result).isFailed().satisfies(failure -> { + assertThat(failure.getViolations()).anySatisfy(violation -> { + assertThat(violation.path()).contains("arrayProperty"); + }); }); - }); - } - - @Test - void shouldSucceed_ValidateOptionalIdArrayNoValue() { - var input = createObjectBuilder(); - - var result = JsonObjectValidator.newValidator() - .verify("arrayProperty", OptionalIdArray::new) - .build() - .validate(input.build()); - - assertThat(result).isSucceeded(); - } - - @Test - void shouldFail_ValidateOptionalIdArrayWrongType() { - var input = createObjectBuilder() - .add("arrayProperty", createArrayBuilder() - .add(createObjectBuilder().add("subProperty", createObjectBuilder())) - ); - - var result = JsonObjectValidator.newValidator() - .verify("arrayProperty", OptionalIdArray::new) - .build() - .validate(input.build()); - - assertThat(result).isFailed().satisfies(failure -> { - assertThat(failure.getViolations()).anySatisfy(violation -> { - assertThat(violation.path()).contains("arrayProperty"); + } + + @Test + void shouldSucceed_ValidateOptionalIdArrayNoValue() { + var input = createObjectBuilder(); + + var result = JsonObjectValidator.newValidator() + .verify("arrayProperty", OptionalIdArray::new) + .build() + .validate(input.build()); + + assertThat(result).isSucceeded(); + } + + @Test + void shouldFail_ValidateOptionalIdArrayWrongType() { + var input = createObjectBuilder() + .add("arrayProperty", createArrayBuilder() + .add(createObjectBuilder().add("subProperty", createObjectBuilder())) + ); + + var result = JsonObjectValidator.newValidator() + .verify("arrayProperty", OptionalIdArray::new) + .build() + .validate(input.build()); + + assertThat(result).isFailed().satisfies(failure -> { + assertThat(failure.getViolations()).anySatisfy(violation -> { + assertThat(violation.path()).contains("arrayProperty"); + }); }); - }); + } + + @Test + void shouldSucceed_ValidateOptionalIdArray() { + var input = createObjectBuilder() + .add("arrayProperty", createArrayBuilder() + .add(createObjectBuilder().add(ID, "value1")) + .add(createObjectBuilder().add(ID, "value2")) + ); + + var result = JsonObjectValidator.newValidator() + .verify("arrayProperty", OptionalIdArray::new) + .build() + .validate(input.build()); + + assertThat(result).isSucceeded(); + } } - @Test - void shouldSucceed_ValidateOptionalIdArray() { - var input = createObjectBuilder() - .add("arrayProperty", createArrayBuilder() - .add(createObjectBuilder().add(ID, "value1")) - .add(createObjectBuilder().add(ID, "value2")) - ); - - var result = JsonObjectValidator.newValidator() - .verify("arrayProperty", OptionalIdArray::new) - .build() - .validate(input.build()); - - assertThat(result).isSucceeded(); - } private JsonArrayBuilder value(String value) { return createArrayBuilder().add(createObjectBuilder().add(VALUE, value)); diff --git a/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java b/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java index 6b76ff0a3d9..65b9bcae621 100644 --- a/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java +++ b/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java @@ -16,6 +16,7 @@ import jakarta.json.JsonObject; import jakarta.json.JsonString; +import jakarta.json.JsonValue; import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; import org.eclipse.edc.policy.model.Duty; import org.eclipse.edc.policy.model.Permission; @@ -27,8 +28,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; +import java.util.Objects; import java.util.Optional; +import static java.util.stream.Collectors.toList; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_ASSIGNEE_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_ASSIGNER_ATTRIBUTE; @@ -92,11 +96,17 @@ public JsonObjectToPolicyTransformer(ParticipantIdMapper participantIdMapper) { case ODRL_TARGET_ATTRIBUTE -> v -> builder.target(transformString(v, context)); case ODRL_ASSIGNER_ATTRIBUTE -> v -> builder.assigner(participantIdMapper.fromIri(transformString(v, context))); case ODRL_ASSIGNEE_ATTRIBUTE -> v -> builder.assignee(participantIdMapper.fromIri(transformString(v, context))); - case ODRL_PROFILE_ATTRIBUTE -> v -> builder.profiles(transformIdStringArray(v, context)); + case ODRL_PROFILE_ATTRIBUTE -> v -> builder.profiles(transformProfile(v)); default -> v -> builder.extensibleProperty(key, transformGenericProperty(v, context)); }); return builderResult(builder::build, context); } + List transformProfile(JsonValue value) { + return value.asJsonArray().stream() + .map(this::nodeId) + .filter(Objects::nonNull) + .collect(toList()); + } } diff --git a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java index f1e669580b0..30959777bc2 100644 --- a/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java +++ b/spi/common/json-ld-spi/src/main/java/org/eclipse/edc/jsonld/spi/transformer/AbstractJsonLdTransformer.java @@ -26,7 +26,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -40,12 +39,10 @@ import static jakarta.json.JsonValue.ValueType.FALSE; import static jakarta.json.JsonValue.ValueType.NUMBER; import static jakarta.json.JsonValue.ValueType.OBJECT; -import static jakarta.json.JsonValue.ValueType.STRING; import static jakarta.json.JsonValue.ValueType.TRUE; import static java.lang.String.format; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; /** * Base JSON-LD transformer implementation. @@ -283,60 +280,6 @@ protected String transformString(JsonValue value, TransformerContext context) { } } - /** - * Transforms a JsonValue to a list of strings. If the value parameter is not of type JsonString, JsonObject or JsonArray, - * a problem is reported to the context and an empty list is returned. - * - * @param value the value to transform - * @param context the transformer context - * @return the string list result - */ - @Nullable - protected List transformIdStringArray(JsonValue value, TransformerContext context) { - List result = new ArrayList<>(); - if (value instanceof JsonString) { - result.add(((JsonString) value).getString()); - return result; - } - if (value instanceof JsonObject) { - var object = value.asJsonObject(); - var id = nodeId(object); - if (id == null) { - context.problem() - .unexpectedType() - .expected(ID) - .report(); - return result; - } - result.add(id); - return result; - } - if (value instanceof JsonArray) { - result = value.asJsonArray().stream() - .map(this::nodeId) - .filter(Objects::nonNull) - .collect(toList()); - if (result.isEmpty()) { - context.problem() - .unexpectedType() - .expected(ID) - .report(); - return result; - } - return result; - } - if (value != null) { - context.problem() - .unexpectedType() - .actual(value.getValueType()) - .expected(STRING) - .expected(OBJECT) - .expected(ARRAY) - .report(); - } - return result; - } - /** * Transforms a JsonValue to int. If the value parameter is not of type JsonNumber, JsonObject or JsonArray, a problem is reported to the context. * diff --git a/spi/control-plane/policy-spi/src/testFixtures/java/org/eclipse/edc/connector/controlplane/policy/spi/testfixtures/TestFunctions.java b/spi/control-plane/policy-spi/src/testFixtures/java/org/eclipse/edc/connector/controlplane/policy/spi/testfixtures/TestFunctions.java index 907020b0c38..5ff81b99dae 100644 --- a/spi/control-plane/policy-spi/src/testFixtures/java/org/eclipse/edc/connector/controlplane/policy/spi/testfixtures/TestFunctions.java +++ b/spi/control-plane/policy-spi/src/testFixtures/java/org/eclipse/edc/connector/controlplane/policy/spi/testfixtures/TestFunctions.java @@ -47,6 +47,16 @@ public static PolicyDefinition createPolicy(String id, String target) { .build(); } + public static PolicyDefinition createPolicy(String id, String target, List profiles) { + var policy = createPolicyBuilder(id).profiles(profiles).target(target).build(); + + return PolicyDefinition.Builder.newInstance() + .createdAt(Clock.systemUTC().millis()) + .id(id) + .policy(policy) + .build(); + } + public static PolicyDefinition createPolicy(String id, String target, Map privateProperties) { var policy = createPolicyBuilder(id).target(target).build(); diff --git a/spi/control-plane/policy-spi/src/testFixtures/java/org/eclipse/edc/connector/controlplane/policy/spi/testfixtures/store/PolicyDefinitionStoreTestBase.java b/spi/control-plane/policy-spi/src/testFixtures/java/org/eclipse/edc/connector/controlplane/policy/spi/testfixtures/store/PolicyDefinitionStoreTestBase.java index a1807aa8f48..dbf59ee56f0 100644 --- a/spi/control-plane/policy-spi/src/testFixtures/java/org/eclipse/edc/connector/controlplane/policy/spi/testfixtures/store/PolicyDefinitionStoreTestBase.java +++ b/spi/control-plane/policy-spi/src/testFixtures/java/org/eclipse/edc/connector/controlplane/policy/spi/testfixtures/store/PolicyDefinitionStoreTestBase.java @@ -31,6 +31,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; @@ -49,7 +50,7 @@ public abstract class PolicyDefinitionStoreTestBase { class Create { @Test - @DisplayName("Save a single policy that not exists ") + @DisplayName("Save a single policy that does not exist") void notExisting() { var policy = TestFunctions.createPolicy(getRandomId()); @@ -92,7 +93,7 @@ void alreadyExists() { } @Test - @DisplayName("Save a single policy that not exists ") + @DisplayName("Save a single policy that does not exist") void notExisting_with_privateProperties() { var policy = TestFunctions.createPolicy(getRandomId(), null, Map.of("key1", "value1", "key2", "value2")); @@ -105,6 +106,21 @@ void notExisting_with_privateProperties() { assertThat(policyFromDb.getPrivateProperties().get("key1")).usingRecursiveComparison().isEqualTo("value1"); assertThat(policyFromDb.getPrivateProperties().get("key2")).usingRecursiveComparison().isEqualTo("value2"); } + + @Test + @DisplayName("Save a single policy that does not exist") + void notExisting_with_Profile() { + var policy = TestFunctions.createPolicy(getRandomId(), null, List.of("value1")); + + getPolicyDefinitionStore().create(policy); + + var policyFromDb = getPolicyDefinitionStore().findById(policy.getId()); + assertThat(policy).usingRecursiveComparison().isEqualTo(policyFromDb); + + assertThat(policyFromDb.getPolicy().getProfiles()).hasSize(1); + assertThat(policyFromDb.getPolicy().getProfiles().get(0)).isEqualTo("value1"); + } + } @Nested @@ -121,7 +137,7 @@ void policyDoesNotExist() { } @Test - @DisplayName("Update an Policy that exists, adding a property") + @DisplayName("Update a Policy that exists, adding a property") void policyExists() { var id = getRandomId(); var policy = createPolicyDef(id, "target"); @@ -143,7 +159,7 @@ void policyExists() { } @Test - @DisplayName("Update an Policy that exists, adding a property") + @DisplayName("Update a Policy that exists, adding a property") void policyExists_addProperty() { var id = getRandomId(); var policy = createPolicyDef(id, "target"); @@ -167,7 +183,7 @@ void policyExists_addProperty() { } @Test - @DisplayName("Update an Policy that exists, remove a property") + @DisplayName("Update a Policy that exists, removing a property") void policyExists_removeProperty() { var id = getRandomId(); var policy = createPolicyDef(id, "target"); @@ -190,7 +206,7 @@ void policyExists_removeProperty() { } @Test - @DisplayName("Update an Policy that exists, replace a property") + @DisplayName("Update a Policy that exists, replacing a property") void policyExists_replaceProperty() { var id = getRandomId(); var policy = createPolicyDef(id, "target"); @@ -582,7 +598,7 @@ void whenNoFiltersWithLimitAndOffset() { } @Test - @DisplayName("find all a with property ") + @DisplayName("Find all with a property ") void findAll_with_privateProperties() { var policy1 = TestFunctions.createPolicy(getRandomId(), null, Map.of("key1", "value1", "key2", "value2")); var policy2 = TestFunctions.createPolicy(getRandomId(), null, Map.of("key3", "value3", "key4", "value4")); From 53724d1cb4567aedd5f83bcfe548842a8a2ce2cc Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Wed, 10 Jul 2024 09:56:31 +0200 Subject: [PATCH 11/13] feat(api, spi, storage): dependencies Signed-off-by: Sascha Isele --- DEPENDENCIES | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index 60f71dc5c75..160a60b8f62 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -136,7 +136,7 @@ maven/mavencentral/io.prometheus/simpleclient_tracer_otel/0.16.0, Apache-2.0, ap maven/mavencentral/io.prometheus/simpleclient_tracer_otel_agent/0.16.0, Apache-2.0, approved, clearlydefined maven/mavencentral/io.rest-assured/json-path/5.5.0, Apache-2.0, approved, clearlydefined maven/mavencentral/io.rest-assured/rest-assured-common/5.5.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.rest-assured/rest-assured/5.5.0, Apache-2.0, restricted, clearlydefined +maven/mavencentral/io.rest-assured/rest-assured/5.5.0, Apache-2.0, approved, #15676 maven/mavencentral/io.rest-assured/xml-path/5.5.0, Apache-2.0, approved, clearlydefined maven/mavencentral/io.setl/rdf-urdna/1.1, Apache-2.0, approved, clearlydefined maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.22, Apache-2.0, approved, #5947 @@ -188,6 +188,7 @@ maven/mavencentral/net.bytebuddy/byte-buddy-agent/1.14.15, Apache-2.0, approved, maven/mavencentral/net.bytebuddy/byte-buddy/1.14.1, Apache-2.0 AND BSD-3-Clause, approved, #7163 maven/mavencentral/net.bytebuddy/byte-buddy/1.14.15, Apache-2.0 AND BSD-3-Clause, approved, #7163 maven/mavencentral/net.bytebuddy/byte-buddy/1.14.16, Apache-2.0 AND BSD-3-Clause, approved, #7163 +maven/mavencentral/net.bytebuddy/byte-buddy/1.14.18, Apache-2.0 AND BSD-3-Clause, approved, #7163 maven/mavencentral/net.java.dev.jna/jna/5.13.0, Apache-2.0 AND LGPL-2.1-or-later, approved, #15196 maven/mavencentral/net.javacrumbs.json-unit/json-unit-core/2.36.0, Apache-2.0, approved, clearlydefined maven/mavencentral/net.minidev/accessors-smart/2.4.7, Apache-2.0, approved, #7515 @@ -228,6 +229,7 @@ maven/mavencentral/org.apache.velocity/velocity-engine-scripting/2.3, Apache-2.0 maven/mavencentral/org.apache.xbean/xbean-reflect/3.7, Apache-2.0, approved, clearlydefined maven/mavencentral/org.apiguardian/apiguardian-api/1.1.2, Apache-2.0, approved, clearlydefined maven/mavencentral/org.assertj/assertj-core/3.26.0, Apache-2.0, approved, #14886 +maven/mavencentral/org.assertj/assertj-core/3.26.3, Apache-2.0, approved, #14886 maven/mavencentral/org.awaitility/awaitility/4.2.1, Apache-2.0, approved, #14178 maven/mavencentral/org.bouncycastle/bcpkix-jdk18on/1.72, MIT, approved, #3789 maven/mavencentral/org.bouncycastle/bcpkix-jdk18on/1.78.1, MIT, approved, #14434 From b8efb60859e45b913b23d002cbbfd261973916b3 Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Wed, 10 Jul 2024 10:05:29 +0200 Subject: [PATCH 12/13] feat(api, spi, storage): transformer test fix Signed-off-by: Sascha Isele --- .../to/JsonObjectToPolicyTransformerTest.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/core/control-plane/control-plane-transform/src/test/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformerTest.java b/core/control-plane/control-plane-transform/src/test/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformerTest.java index 45fe1c362a7..b4471a381c0 100644 --- a/core/control-plane/control-plane-transform/src/test/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformerTest.java +++ b/core/control-plane/control-plane-transform/src/test/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformerTest.java @@ -42,7 +42,6 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VALUE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_ASSIGNEE_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_ASSIGNER_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_OBLIGATION_ATTRIBUTE; @@ -203,23 +202,6 @@ void transform_withProfile() { verify(context, never()).reportProblem(anyString()); } - @Test - void transform_withInvalidProfile() { - - var policy = jsonFactory.createObjectBuilder() - .add(TYPE, ODRL_POLICY_TYPE_SET) - .add(ODRL_PROFILE_ATTRIBUTE, jsonFactory.createObjectBuilder().add(VALUE, "http://example.com/odrl:profile:01")) - .build(); - - when(context.problem()).thenReturn(new ProblemBuilder(context)); - - var result = transformer.transform(TestInput.getExpanded(policy), context); - - assertThat(result).isNotNull(); - assertThat(result.getProfiles()).isEmpty(); - verify(context).reportProblem(anyString()); - } - private static class PolicyTypeArguments implements ArgumentsProvider { @Override From b2accb0b7ab04b2e41046bf017460c4c9bc314fb Mon Sep 17 00:00:00 2001 From: Sascha Isele Date: Wed, 10 Jul 2024 12:03:26 +0200 Subject: [PATCH 13/13] feat(api, spi, storage): transformer method visibility Signed-off-by: Sascha Isele --- .../transform/odrl/to/JsonObjectToPolicyTransformer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java b/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java index 65b9bcae621..9c62d5286be 100644 --- a/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java +++ b/core/control-plane/control-plane-transform/src/main/java/org/eclipse/edc/connector/controlplane/transform/odrl/to/JsonObjectToPolicyTransformer.java @@ -103,7 +103,7 @@ public JsonObjectToPolicyTransformer(ParticipantIdMapper participantIdMapper) { return builderResult(builder::build, context); } - List transformProfile(JsonValue value) { + private List transformProfile(JsonValue value) { return value.asJsonArray().stream() .map(this::nodeId) .filter(Objects::nonNull)