Skip to content

Commit

Permalink
feat: add private properties to policy definition entity (#3576)
Browse files Browse the repository at this point in the history
* feat: add private properties to policy definition entity

* feat: add private properties to policy definition entity - Add unit tests

* feat: add private properties to policy definition entity - Add unit tests

* feat: add private properties to policy definition entity - Add unit tests

* feat: add private properties to policy definition entity

* fix for component tests fails

* review comments, add test for complex types

* checkstyle and endtoend tests

* endtoend tests
  • Loading branch information
suh-rao authored Nov 28, 2023
1 parent 3f9aec4 commit 9bde3e9
Show file tree
Hide file tree
Showing 15 changed files with 462 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
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;

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)
Expand All @@ -53,6 +55,9 @@ public class PolicyDefinitionApiExtension implements ServiceExtension {
@Inject
private JsonObjectValidatorRegistry validatorRegistry;

@Inject
private TypeManager typeManager;

@Override
public String name() {
return NAME;
Expand All @@ -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());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -29,11 +30,13 @@

public class JsonObjectFromPolicyDefinitionTransformer extends AbstractJsonLdTransformer<PolicyDefinition, JsonObject> {

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
Expand All @@ -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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<JsonObject, PolicyDefinition> {

Expand All @@ -35,13 +36,22 @@ public JsonObjectToPolicyDefinitionTransformer() {
public @Nullable PolicyDefinition transform(@NotNull JsonObject input, @NotNull TransformerContext context) {
var builder = PolicyDefinition.Builder.newInstance();
builder.id(nodeId(input));
visitProperties(input, (key, value) -> transformProperty(key, value, builder, context));
visitProperties(input, (key, value) -> transformProperties(key, value, builder, context));
return builder.build();
}

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);
private void transformProperties(String key, JsonValue jsonValue, PolicyDefinition.Builder builder, TransformerContext context) {
switch (key) {
case EDC_POLICY_DEFINITION_POLICY ->
transformArrayOrObject(jsonValue, Policy.class, builder::policy, context);
case EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES -> {
var props = jsonValue.asJsonArray().getJsonObject(0);
visitProperties(props, (k, val) -> transformProperties(k, val, builder, context));
}
default -> {
builder.privateProperty(key, transformGenericProperty(jsonValue, context));
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@
package org.eclipse.edc.connector.api.management.policy.transform;

import jakarta.json.Json;
import jakarta.json.JsonBuilderFactory;
import jakarta.json.JsonObject;
import org.eclipse.edc.connector.policy.spi.PolicyDefinition;
import org.eclipse.edc.policy.model.Policy;
import org.eclipse.edc.transform.spi.TransformerContext;
import org.junit.jupiter.api.Test;

import java.util.Map;

import static java.util.Collections.emptyMap;
import static org.assertj.core.api.Assertions.assertThat;
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;
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;
Expand All @@ -35,9 +40,13 @@

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);


private final JsonBuilderFactory jsonFactory = Json.createBuilderFactory(Map.of());


@Test
void types() {
assertThat(transformer.getInputType()).isEqualTo(PolicyDefinition.class);
Expand All @@ -60,4 +69,63 @@ void transform() {
verify(context).transform(policy, JsonObject.class);
}

@Test
void transform_withPrivateProperties_simpleTypes() {
var policy = Policy.Builder.newInstance().build();
var input = PolicyDefinition.Builder.newInstance().id("definitionId").policy(policy).privateProperty("some-key", "some-value").build();
var policyJson = Json.createObjectBuilder().build();
when(context.transform(any(), eq(JsonObject.class))).thenReturn(policyJson);

var result = transformer.transform(input, context);

assertThat(result).isNotNull();
assertThat(result.getString(ID)).isEqualTo("definitionId");
assertThat(result.getString(TYPE)).isEqualTo(EDC_POLICY_DEFINITION_TYPE);
assertThat(result.getJsonObject(EDC_POLICY_DEFINITION_POLICY)).isSameAs(policyJson);

assertThat(result.getJsonObject(EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES).getJsonString("some-key").getString()).isEqualTo("some-value");
verify(context).transform(policy, JsonObject.class);
}


@Test
void transform_withPrivateProperties_complexTypes() {
var policy = Policy.Builder.newInstance().build();
var input = PolicyDefinition
.Builder.newInstance()
.id("definitionId")
.policy(policy)
.privateProperty("root", Map.of("key1", "value1", "nested1", Map.of("key2", "value2", "key3", Map.of("theKey", "theValue, this is what we're looking for"))))
.build();
var policyJson = Json.createObjectBuilder().build();
when(context.transform(any(), eq(JsonObject.class))).thenReturn(policyJson);

var result = transformer.transform(input, context);

assertThat(result).isNotNull();
assertThat(result.getString(ID)).isEqualTo("definitionId");
assertThat(result.getString(TYPE)).isEqualTo(EDC_POLICY_DEFINITION_TYPE);
assertThat(result.getJsonObject(EDC_POLICY_DEFINITION_POLICY)).isSameAs(policyJson);

assertThat(result.getJsonObject(EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES)
.getJsonObject("root")
.getJsonString("key1")
.getString())
.isEqualTo("value1");
assertThat(result.getJsonObject(EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES)
.getJsonObject("root")
.getJsonObject("nested1")
.getJsonString("key2")
.getString())
.isEqualTo("value2");
assertThat(result.getJsonObject(EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES)
.getJsonObject("root")
.getJsonObject("nested1")
.getJsonObject("key3")
.getJsonString("theKey")
.getString())
.isEqualTo("theValue, this is what we're looking for");

verify(context).transform(policy, JsonObject.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,27 @@

package org.eclipse.edc.connector.api.management.policy.transform;

import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonObjectBuilder;
import org.eclipse.edc.connector.policy.spi.PolicyDefinition;
import org.eclipse.edc.jsonld.TitaniumJsonLd;
import org.eclipse.edc.policy.model.Policy;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.transform.spi.TransformerContext;
import org.junit.jupiter.api.Test;

import static jakarta.json.Json.createArrayBuilder;
import static jakarta.json.Json.createObjectBuilder;
import static org.assertj.core.api.Assertions.assertThat;
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;
import static org.eclipse.edc.connector.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;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB;
import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE;
import static org.eclipse.edc.spi.CoreConstants.EDC_PREFIX;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
Expand All @@ -36,6 +45,7 @@ class JsonObjectToPolicyDefinitionTransformerTest {

private final JsonObjectToPolicyDefinitionTransformer transformer = new JsonObjectToPolicyDefinitionTransformer();
private final TransformerContext context = mock(TransformerContext.class);
private final TitaniumJsonLd jsonLd = new TitaniumJsonLd(mock(Monitor.class));

@Test
void types() {
Expand All @@ -45,10 +55,10 @@ void types() {

@Test
void transform() {
var policyJson = Json.createObjectBuilder().build();
var policyJson = createObjectBuilder().build();
var policy = Policy.Builder.newInstance().build();
when(context.transform(any(), eq(Policy.class))).thenReturn(policy);
var json = Json.createObjectBuilder()
var json = createObjectBuilder()
.add(ID, "definitionId")
.add(TYPE, EDC_POLICY_DEFINITION_TYPE)
.add(EDC_POLICY_DEFINITION_POLICY, policyJson)
Expand All @@ -62,4 +72,44 @@ void transform() {
verify(context).transform(policyJson, Policy.class);
}

@Test
void transform_withPrivateProperties() {
when(context.transform(any(), eq(Object.class))).thenReturn("test-val");
var policyJson = createObjectBuilder().build();
var policy = Policy.Builder.newInstance().build();
when(context.transform(any(), eq(Policy.class))).thenReturn(policy);
var json = createObjectBuilder()
.add(CONTEXT, createContextBuilder().addNull(EDC_PREFIX).build())
.add(ID, "definitionId")
.add(TYPE, EDC_POLICY_DEFINITION_TYPE)
.add(EDC_POLICY_DEFINITION_POLICY, policyJson)
.add(EDC_POLICY_DEFINITION_PRIVATE_PROPERTIES,
createArrayBuilder()
.add(createObjectBuilder()
.add("test-prop", "test-val")
.build())
.build())
.build();
var jsonObj = expand(json);
var result = transformer.transform(jsonObj, context);

assertThat(result).isNotNull();
assertThat(result.getId()).isEqualTo("definitionId");
assertThat(result.getPolicy()).isSameAs(policy);
verify(context).transform(policyJson, Policy.class);
assertThat(result.getPrivateProperties())
.hasSize(1)
.containsEntry(EDC_NAMESPACE + "test-prop", "test-val");
}

private JsonObject expand(JsonObject jsonObject) {
return jsonLd.expand(jsonObject).orElseThrow(f -> new AssertionError(f.getFailureDetail()));
}

private JsonObjectBuilder createContextBuilder() {
return createObjectBuilder()
.add(VOCAB, EDC_NAMESPACE)
.add(EDC_PREFIX, EDC_NAMESPACE);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ entity edc_policydefinitions {
target: string
type: string
extensible_properties: string <<json>>
private_properties: string <<json>>
}
@enduml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* Contributors:
* ZF Friedrichshafen AG - Initial API and Implementation
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - improvements
* SAP SE - add private properties to contract definition
*
*/

Expand Down Expand Up @@ -57,6 +58,9 @@ public class SqlPolicyDefinitionStore extends AbstractSqlStore implements Policy
private final TypeReference<Map<String, Object>> extensiblePropertiesType = new TypeReference<>() {
};

private static final TypeReference<Map<String, Object>> PRIVATE_PROPERTIES_TYPE = new TypeReference<>() {
};

public SqlPolicyDefinitionStore(DataSourceRegistry dataSourceRegistry, String dataSourceName, TransactionContext transactionContext,
ObjectMapper objectMapper, SqlPolicyStoreStatements sqlPolicyStoreStatements, QueryExecutor queryExecutor) {
super(dataSourceRegistry, dataSourceName, transactionContext, objectMapper, queryExecutor);
Expand Down Expand Up @@ -149,7 +153,8 @@ private void insert(PolicyDefinition def) {
policy.getAssignee(),
policy.getTarget(),
toJson(policy.getType(), policyType),
def.getCreatedAt());
def.getCreatedAt(),
toJson(def.getPrivateProperties()));
} catch (Exception e) {
throw new EdcPersistenceException(e.getMessage(), e);
}
Expand All @@ -171,6 +176,7 @@ private void updateInternal(PolicyDefinition def) {
policy.getAssignee(),
policy.getTarget(),
toJson(policy.getType(), policyType),
toJson(def.getPrivateProperties()),
id);
} catch (Exception e) {
throw new EdcPersistenceException(e.getMessage(), e);
Expand All @@ -195,6 +201,7 @@ private PolicyDefinition mapResultSet(ResultSet resultSet) throws SQLException {
.id(resultSet.getString(statements.getPolicyIdColumn()))
.policy(policy)
.createdAt(resultSet.getLong(statements.getCreatedAtColumn()))
.privateProperties(fromJson(resultSet.getString(statements.getPrivatePropertiesColumn()), PRIVATE_PROPERTIES_TYPE))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public String getInsertTemplate() {
.column(getTargetColumn())
.column(getTypeColumn())
.column(getCreatedAtColumn())
.jsonColumn(getPrivatePropertiesColumn())
.insertInto(getPolicyTable());
}

Expand All @@ -55,6 +56,7 @@ public String getUpdateTemplate() {
.column(getAssigneeColumn())
.column(getTargetColumn())
.column(getTypeColumn())
.jsonColumn(getPrivatePropertiesColumn())
.update(getPolicyTable(), getPolicyIdColumn());

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,9 @@ default String getCreatedAtColumn() {
return "created_at";
}

default String getPrivatePropertiesColumn() {
return "private_properties";
}

SqlQueryStatement createQuery(QuerySpec querySpec);
}
Loading

0 comments on commit 9bde3e9

Please sign in to comment.