Skip to content

Commit

Permalink
feat: adds new terms definition in json-ld context (#4459)
Browse files Browse the repository at this point in the history
feat: adds new terms definition in context for policy validation and evaluation plan
  • Loading branch information
wolf4ood authored Sep 6, 2024
1 parent 005bbb2 commit a5b4752
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@
"SuspendTransfer": "edc:SuspendTransfer",
"Secret": "edc:Secret",
"EndpointDataReferenceEntry": "edc:EndpointDataReferenceEntry",
"PolicyValidationResult": "edc:PolicyValidationResult",
"PolicyEvaluationPlanRequest": "edc:PolicyEvaluationPlanRequest",
"PolicyEvaluationPlan": "edc:PolicyEvaluationPlan",
"PermissionStep": "edc:PermissionStep",
"ProhibitionStep": "edc:ProhibitionStep",
"DutyStep": "edc:DutyStep",
"OrConstraintStep": "edc:OrConstraintStep",
"AndConstraintStep": "edc:AndConstraintStep",
"XoneConstraintStep": "edc:XoneConstraintStep",
"AtomicConstraintStep": "edc:AtomicConstraintStep",
"properties": {
"@id": "edc:properties",
"@context": {
Expand Down Expand Up @@ -111,6 +121,54 @@
"transferProcessId": "edc:transferProcessId",
"contractNegotiationId": "edc:contractNegotiationId",
"agreementId": "edc:agreementId",
"inForceDate": "edc:inForceDate"
"inForceDate": "edc:inForceDate",
"isValid": "edc:isValid",
"errors": {
"@id": "edc:errors",
"@container": "@set"
},
"policyScope": "edc:policyScope",
"preValidators": {
"@id": "edc:preValidators",
"@container": "@set"
},
"postValidators": {
"@id": "edc:postValidators",
"@container": "@set"
},
"permissionSteps": {
"@id": "edc:permissionSteps",
"@container": "@set"
},
"prohibitionSteps": {
"@id": "edc:prohibitionSteps",
"@container": "@set"
},
"obligationSteps": {
"@id": "edc:obligationSteps",
"@container": "@set"
},
"constraintSteps": {
"@id": "edc:constraintSteps",
"@container": "@set"
},
"filteringReasons": {
"@id": "edc:filteringReasons",
"@container": "@set"
},
"isFiltered": "edc:isFiltered",
"functionName": "edc:functionName",
"functionParams": {
"@id": "edc:functionParams",
"@container": "@set"
},
"dutySteps": {
"@id": "edc:dutySteps",
"@container": "@set"
},
"ruleFunctions": {
"@id": "edc:ruleFunctions",
"@container": "@set"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
import org.eclipse.edc.connector.controlplane.api.management.contractnegotiation.model.NegotiationState;
import org.eclipse.edc.connector.controlplane.api.management.policy.model.PolicyEvaluationPlanRequest;
import org.eclipse.edc.connector.controlplane.api.management.policy.model.PolicyValidationResult;
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.model.SuspendTransfer;
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.model.TerminateTransfer;
import org.eclipse.edc.connector.controlplane.api.management.transferprocess.model.TransferState;
Expand Down Expand Up @@ -54,8 +57,11 @@
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -69,9 +75,11 @@
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createContractAgreement;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createContractNegotiation;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createEdrEntry;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createPolicyEvaluationPlan;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.createTransferProcess;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.inForceDatePermission;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.policyDefinitionObject;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.policyEvaluationPlanRequest;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.querySpecObject;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.secretObject;
import static org.eclipse.edc.connector.api.management.jsonld.serde.TestFunctions.suspendTransferObject;
Expand Down Expand Up @@ -208,6 +216,62 @@ void ser_TransferState() {

}

@Test
void ser_PolicyValidationResult() {
var result = new PolicyValidationResult(false, List.of("error1", "error2"));
var compactResult = serialize(result);

assertThat(compactResult).isNotNull();
assertThat(compactResult.getString(TYPE)).isEqualTo("PolicyValidationResult");
assertThat(compactResult.getBoolean("isValid")).isEqualTo(false);
assertThat(compactResult.getJsonArray("errors")).contains(Json.createValue("error1"), Json.createValue("error2"));

}

@Test
void ser_PolicyEvaluationPlan() {
var plan = createPolicyEvaluationPlan();
var compactResult = serialize(plan);

assertThat(compactResult).isNotNull();
assertThat(compactResult.getString(TYPE)).isEqualTo("PolicyEvaluationPlan");
assertThat(compactResult.getJsonArray("preValidators")).hasSize(1);
assertThat(compactResult.getJsonArray("postValidators")).hasSize(1);


BiFunction<String, String, Consumer<JsonValue>> ruleAsser = (ruleType, multiplicityType) -> (ruleValue) -> {
var rule = ruleValue.asJsonObject();
assertThat(rule.getString(TYPE)).isEqualTo(ruleType);
assertThat(rule.getJsonArray("ruleFunctions")).hasSize(0);
assertThat(rule.getJsonArray("constraintSteps")).hasSize(1);

var constraint = rule.getJsonArray("constraintSteps").get(0).asJsonObject();
assertThat(constraint.getString(TYPE)).isEqualTo(multiplicityType);
assertThat(constraint.getJsonArray("constraintSteps")).hasSize(2)
.allSatisfy(value -> {
var atomicConstraint = value.asJsonObject();
assertThat(atomicConstraint.getString(TYPE)).isEqualTo("AtomicConstraintStep");
assertThat(atomicConstraint.getJsonArray("filteringReasons")).hasSize(1);
assertThat(atomicConstraint.getBoolean("isFiltered")).isTrue();
assertThat(atomicConstraint.getString("functionName")).isEqualTo("AtomicConstraintFunction");
assertThat(atomicConstraint.getJsonArray("functionParams")).hasSize(3);
});
};

assertThat(compactResult.getJsonArray("permissionSteps")).hasSize(1)
.first()
.satisfies(ruleAsser.apply("PermissionStep", "OrConstraintStep"));

assertThat(compactResult.getJsonArray("prohibitionSteps")).hasSize(1)
.first()
.satisfies(ruleAsser.apply("ProhibitionStep", "AndConstraintStep"));

assertThat(compactResult.getJsonArray("obligationSteps")).hasSize(1)
.first()
.satisfies(ruleAsser.apply("DutyStep", "XoneConstraintStep"));

}

@Test
void de_ContractRequest() {
var inputObject = contractRequestObject();
Expand Down Expand Up @@ -293,6 +357,16 @@ void de_PolicyDefinition_withInForceDate() {

}

@Test
void de_PolicyEvaluationPlanRequest() {
var inputObject = policyEvaluationPlanRequest();
var terminateTransfer = deserialize(inputObject, PolicyEvaluationPlanRequest.class);

assertThat(terminateTransfer).isNotNull();
assertThat(terminateTransfer.policyScope()).isEqualTo(inputObject.getString("policyScope"));

}

/**
* Tests for entities that supports transformation from/to JsonObject
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,21 @@
import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiation;
import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess;
import org.eclipse.edc.edr.spi.types.EndpointDataReferenceEntry;
import org.eclipse.edc.policy.engine.spi.AtomicConstraintFunction;
import org.eclipse.edc.policy.engine.spi.plan.PolicyEvaluationPlan;
import org.eclipse.edc.policy.engine.spi.plan.step.AndConstraintStep;
import org.eclipse.edc.policy.engine.spi.plan.step.AtomicConstraintStep;
import org.eclipse.edc.policy.engine.spi.plan.step.ConstraintStep;
import org.eclipse.edc.policy.engine.spi.plan.step.DutyStep;
import org.eclipse.edc.policy.engine.spi.plan.step.OrConstraintStep;
import org.eclipse.edc.policy.engine.spi.plan.step.PermissionStep;
import org.eclipse.edc.policy.engine.spi.plan.step.ProhibitionStep;
import org.eclipse.edc.policy.engine.spi.plan.step.ValidatorStep;
import org.eclipse.edc.policy.engine.spi.plan.step.XoneConstraintStep;
import org.eclipse.edc.policy.model.AtomicConstraint;
import org.eclipse.edc.policy.model.LiteralExpression;
import org.eclipse.edc.policy.model.Policy;
import org.eclipse.edc.policy.model.Rule;
import org.eclipse.edc.spi.types.domain.DataAddress;
import org.eclipse.edc.spi.types.domain.callback.CallbackAddress;

Expand All @@ -42,10 +56,13 @@
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE;
import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA;
import static org.eclipse.edc.policy.model.Operator.EQ;
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE;
import static org.eclipse.edc.spi.types.domain.callback.CallbackAddress.EVENTS;
import static org.eclipse.edc.spi.types.domain.callback.CallbackAddress.IS_TRANSACTIONAL;
import static org.eclipse.edc.spi.types.domain.callback.CallbackAddress.URI;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class TestFunctions {

Expand Down Expand Up @@ -225,6 +242,30 @@ public static EndpointDataReferenceEntry createEdrEntry() {
.build();
}

public static PolicyEvaluationPlan createPolicyEvaluationPlan() {

var firstConstraint = atomicConstraintStep(atomicConstraint("foo", "bar"));
var secondConstraint = atomicConstraintStep(atomicConstraint("baz", "bar"));

List<ConstraintStep> constraints = List.of(firstConstraint, secondConstraint);

var orConstraintStep = new OrConstraintStep(constraints, mock());
var andConstraintStep = new AndConstraintStep(constraints, mock());
var xoneConstraintStep = new XoneConstraintStep(constraints, mock());

var permission = PermissionStep.Builder.newInstance().constraint(orConstraintStep).rule(mock()).build();
var duty = DutyStep.Builder.newInstance().constraint(xoneConstraintStep).rule(mock()).build();
var prohibition = ProhibitionStep.Builder.newInstance().constraint(andConstraintStep).rule(mock()).build();

return PolicyEvaluationPlan.Builder.newInstance()
.postValidator(new ValidatorStep(mock()))
.prohibition(prohibition)
.permission(permission)
.duty(duty)
.preValidator(new ValidatorStep(mock()))
.build();
}

public static JsonObject policyDefinitionObject() {
return createObjectBuilder()
.add(CONTEXT, createContextBuilder().build())
Expand Down Expand Up @@ -312,4 +353,28 @@ public static JsonObject inForceDatePermission(String operatorStart, Object star
.build())
.build();
}

public static JsonObject policyEvaluationPlanRequest() {
return Json.createObjectBuilder()
.add(CONTEXT, createContextBuilder().build())
.add(TYPE, "PolicyEvaluationPlanRequest")
.add("policyScope", "catalog")
.build();
}

private static AtomicConstraintStep atomicConstraintStep(AtomicConstraint atomicConstraint) {
AtomicConstraintFunction<Rule> function = mock();
when(function.name()).thenReturn("AtomicConstraintFunction");
return new AtomicConstraintStep(atomicConstraint, List.of("filtered constraint"), mock(), function);
}

private static AtomicConstraint atomicConstraint(String key, String value) {
var left = new LiteralExpression(key);
var right = new LiteralExpression(value);
return AtomicConstraint.Builder.newInstance()
.leftExpression(left)
.operator(EQ)
.rightExpression(right)
.build();
}
}

0 comments on commit a5b4752

Please sign in to comment.