Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add private properties to policy definition entity #3576

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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() {
suh-rao marked this conversation as resolved.
Show resolved Hide resolved
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
Loading