diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/PolicyDefinitionApiExtension.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/PolicyDefinitionApiExtension.java index 1f3d228dd1e..3bc4295a441 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/PolicyDefinitionApiExtension.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/PolicyDefinitionApiExtension.java @@ -24,6 +24,7 @@ import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; import org.eclipse.edc.web.spi.WebService; @@ -31,6 +32,7 @@ import java.util.Map; import static org.eclipse.edc.connector.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE; +import static org.eclipse.edc.spi.CoreConstants.JSON_LD; @Extension(value = PolicyDefinitionApiExtension.NAME) @@ -53,6 +55,9 @@ public class PolicyDefinitionApiExtension implements ServiceExtension { @Inject private JsonObjectValidatorRegistry validatorRegistry; + @Inject + private TypeManager typeManager; + @Override public String name() { return NAME; @@ -62,7 +67,8 @@ public String name() { public void initialize(ServiceExtensionContext context) { var jsonBuilderFactory = Json.createBuilderFactory(Map.of()); transformerRegistry.register(new JsonObjectToPolicyDefinitionTransformer()); - transformerRegistry.register(new JsonObjectFromPolicyDefinitionTransformer(jsonBuilderFactory)); + var mapper = typeManager.getMapper(JSON_LD); + transformerRegistry.register(new JsonObjectFromPolicyDefinitionTransformer(jsonBuilderFactory, mapper)); validatorRegistry.register(EDC_POLICY_DEFINITION_TYPE, PolicyDefinitionValidator.instance()); diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectFromPolicyDefinitionTransformer.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectFromPolicyDefinitionTransformer.java index 5a08c5ad894..00a8677eb99 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectFromPolicyDefinitionTransformer.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectFromPolicyDefinitionTransformer.java @@ -14,6 +14,7 @@ package org.eclipse.edc.connector.api.management.policy.transform; +import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.json.JsonBuilderFactory; import jakarta.json.JsonObject; import org.eclipse.edc.connector.policy.spi.PolicyDefinition; @@ -29,11 +30,13 @@ public class JsonObjectFromPolicyDefinitionTransformer extends AbstractJsonLdTransformer { + private final ObjectMapper mapper; private final JsonBuilderFactory jsonFactory; - public JsonObjectFromPolicyDefinitionTransformer(JsonBuilderFactory jsonFactory) { + public JsonObjectFromPolicyDefinitionTransformer(JsonBuilderFactory jsonFactory, ObjectMapper jsonLdMapper) { super(PolicyDefinition.class, JsonObject.class); this.jsonFactory = jsonFactory; + this.mapper = jsonLdMapper; } @Override @@ -46,6 +49,11 @@ public JsonObjectFromPolicyDefinitionTransformer(JsonBuilderFactory jsonFactory) var policy = context.transform(input.getPolicy(), JsonObject.class); objectBuilder.add(EDC_POLICY_DEFINITION_POLICY, policy); + if (!input.getPrivateProperties().isEmpty()) { + var privatePropBuilder = jsonFactory.createObjectBuilder(); + transformProperties(input.getPrivateProperties(), privatePropBuilder, mapper, context); + objectBuilder.add(PolicyDefinition.EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES, privatePropBuilder); + } return objectBuilder.build(); } diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectToPolicyDefinitionTransformer.java b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectToPolicyDefinitionTransformer.java index 7c4c6d22a81..815e4fb8304 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectToPolicyDefinitionTransformer.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/main/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectToPolicyDefinitionTransformer.java @@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable; import static org.eclipse.edc.connector.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_POLICY; +import static org.eclipse.edc.connector.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES; public class JsonObjectToPolicyDefinitionTransformer extends AbstractJsonLdTransformer { @@ -42,6 +43,11 @@ public JsonObjectToPolicyDefinitionTransformer() { private void transformProperty(String key, JsonValue value, PolicyDefinition.Builder builder, TransformerContext context) { if (key.equals(EDC_POLICY_DEFINITION_POLICY)) { transformArrayOrObject(value, Policy.class, builder::policy, context); + } else if (key.equals(EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES)) { + var props = value.asJsonArray().getJsonObject(0); + visitProperties(props, (k, val) -> transformProperty(k, val, builder, context)); + } else { + builder.privateProperty(key, value); } } } diff --git a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectFromPolicyDefinitionTransformerTest.java b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectFromPolicyDefinitionTransformerTest.java index 4d9351b6bb5..a05d32b2304 100644 --- a/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectFromPolicyDefinitionTransformerTest.java +++ b/extensions/control-plane/api/management-api/policy-definition-api/src/test/java/org/eclipse/edc/connector/api/management/policy/transform/JsonObjectFromPolicyDefinitionTransformerTest.java @@ -27,6 +27,7 @@ import static org.eclipse.edc.connector.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.jsonld.util.JacksonJsonLd.createObjectMapper; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -35,7 +36,7 @@ class JsonObjectFromPolicyDefinitionTransformerTest { - private final JsonObjectFromPolicyDefinitionTransformer transformer = new JsonObjectFromPolicyDefinitionTransformer(Json.createBuilderFactory(emptyMap())); + private final JsonObjectFromPolicyDefinitionTransformer transformer = new JsonObjectFromPolicyDefinitionTransformer(Json.createBuilderFactory(emptyMap()), createObjectMapper()); private final TransformerContext context = mock(TransformerContext.class); @Test 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 130df29eb5d..539137d840a 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 @@ -23,5 +23,6 @@ entity edc_policydefinitions { target: string type: string extensible_properties: string <> + private_properties: string <> } @enduml \ No newline at end of file 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 92e16957fe0..d4ef81277d7 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 @@ -27,6 +27,7 @@ CREATE TABLE IF NOT EXISTS edc_policydefinitions assignee VARCHAR, target VARCHAR, policy_type VARCHAR NOT NULL, + private_properties JSON, PRIMARY KEY (policy_id) ); diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/store/sql/policydefinition/store/schema/BaseSqlDialectStatements.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/store/sql/policydefinition/store/schema/BaseSqlDialectStatements.java index 74970ac7e21..2911781bde2 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/store/sql/policydefinition/store/schema/BaseSqlDialectStatements.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/store/sql/policydefinition/store/schema/BaseSqlDialectStatements.java @@ -40,6 +40,7 @@ public String getInsertTemplate() { .column(getTargetColumn()) .column(getTypeColumn()) .column(getCreatedAtColumn()) + .jsonColumn(getPrivatePropertiesColumn()) .insertInto(getPolicyTable()); } @@ -55,6 +56,7 @@ public String getUpdateTemplate() { .column(getAssigneeColumn()) .column(getTargetColumn()) .column(getTypeColumn()) + .jsonColumn(getPrivatePropertiesColumn()) .update(getPolicyTable(), getPolicyIdColumn()); } diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/store/sql/policydefinition/store/schema/SqlPolicyStoreStatements.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/store/sql/policydefinition/store/schema/SqlPolicyStoreStatements.java index cf78ada26a4..5daf02a2fd9 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/store/sql/policydefinition/store/schema/SqlPolicyStoreStatements.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/store/sql/policydefinition/store/schema/SqlPolicyStoreStatements.java @@ -94,5 +94,9 @@ default String getCreatedAtColumn() { return "created_at"; } + default String getPrivatePropertiesColumn() { + return "private_properties"; + } + SqlQueryStatement createQuery(QuerySpec querySpec); } diff --git a/spi/control-plane/policy-spi/src/main/java/org/eclipse/edc/connector/policy/spi/PolicyDefinition.java b/spi/control-plane/policy-spi/src/main/java/org/eclipse/edc/connector/policy/spi/PolicyDefinition.java index 7a0ca7f8387..6e220736690 100644 --- a/spi/control-plane/policy-spi/src/main/java/org/eclipse/edc/connector/policy/spi/PolicyDefinition.java +++ b/spi/control-plane/policy-spi/src/main/java/org/eclipse/edc/connector/policy/spi/PolicyDefinition.java @@ -19,7 +19,10 @@ import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; import org.eclipse.edc.policy.model.Policy; import org.eclipse.edc.spi.entity.Entity; +import org.jetbrains.annotations.NotNull; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -39,7 +42,9 @@ public class PolicyDefinition extends Entity { public static final String EDC_POLICY_DEFINITION_TYPE = EDC_NAMESPACE + "PolicyDefinition"; public static final String EDC_POLICY_DEFINITION_POLICY = EDC_NAMESPACE + "policy"; + public static final String EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES = EDC_NAMESPACE + "privateProperties"; private Policy policy; + private final Map privateProperties = new HashMap<>(); private PolicyDefinition() { } @@ -50,7 +55,7 @@ public Policy getPolicy() { @Override public int hashCode() { - return Objects.hash(Objects.hash(id), policy.hashCode()); + return Objects.hash(Objects.hash(id), policy.hashCode(), privateProperties); } @Override @@ -69,6 +74,15 @@ public String getUid() { return id; } + @NotNull + public Map getPrivateProperties() { + return privateProperties; + } + + public Object getPrivateProperty(String key) { + return privateProperties.get(key); + } + @JsonPOJOBuilder(withPrefix = "") public static final class Builder extends Entity.Builder { @@ -86,6 +100,17 @@ public Builder policy(Policy policy) { return this; } + public Builder privateProperty(String key, Object value) { + entity.privateProperties.put(key, value); + return this; + } + + public Builder privateProperties(Map privateProperties) { + Objects.requireNonNull(privateProperties); + entity.privateProperties.putAll(privateProperties); + return this; + } + @Override public Builder self() { return this;