Skip to content

Commit

Permalink
feat: updates policy compliant with TX-EDC 0.7.x (#330)
Browse files Browse the repository at this point in the history
* feat: updates policy compliant with TX-EDC 0.7.x

* chore: tests fix
  • Loading branch information
wolf4ood authored May 27, 2024
1 parent 8412a32 commit 5f6c3be
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 233 deletions.
15 changes: 9 additions & 6 deletions edc-policy-playground/fixtures/policies/bpn.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
{
"@context": {},
"@type": "PolicyDefinitionRequest",
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
"https://w3id.org/tractusx/edc/v0.0.1",
{
"@vocab": "https://w3id.org/edc/v0.0.1/ns/"
}
],
"@type": "PolicyDefinition",
"@id": "{{POLICY_ID}}",
"policy": {
"@type": "Set",
"@context": "http://www.w3.org/ns/odrl.jsonld",
"permission": [
{
"action": "use",
"constraint": [
{
"leftOperand": {
"@value": "BusinessPartnerNumber"
},
"leftOperand": "BusinessPartnerNumber",
"operator": "eq",
"rightOperand": "<bpnNumber>"
}
Expand Down
15 changes: 9 additions & 6 deletions edc-policy-playground/fixtures/policies/bpnGroup.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
{
"@context": {
"tx": "https://w3id.org/tractusx/v0.0.1/ns/"
},
"@type": "PolicyDefinitionRequest",
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
"https://w3id.org/tractusx/edc/v0.0.1",
{
"@vocab": "https://w3id.org/edc/v0.0.1/ns/"
}
],
"@type": "PolicyDefinition",
"@id": "{{POLICY_ID}}",
"policy": {
"@type": "Set",
"@context": "http://www.w3.org/ns/odrl.jsonld",
"permission": [
{
"action": "use",
"constraint": [
{
"leftOperand": "tx:BusinessPartnerGroup",
"leftOperand": "BusinessPartnerGroup",
"operator": "isPartOf",
"rightOperand": "<group>"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
-->

<mat-toolbar color="primary" class="header">
<span>EDC Policy Playouground</span>
<span>TractusX-EDC Policy Playouground</span>
</mat-toolbar>
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@

<div class="flex flex-col">
<div class="flex flex-row gap-x-1">
<mat-form-field appearance="outline" class="w-2/5">
<mat-label>Left Operand (prefix)</mat-label>
<input matInput [(ngModel)]="constraint.leftOperand.prefix" [disabled]="disabled" />
</mat-form-field>
<mat-form-field appearance="outline" class="w-3/5">
<mat-label>Left Operand (value)</mat-label>
<input matInput [(ngModel)]="constraint.leftOperand.value" [disabled]="disabled" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,6 @@
<mat-icon>content_copy</mat-icon>
</button>
</div>
<div class="flex justify-right">
<mat-form-field appearance="outline">
<mat-label>Output format</mat-label>
<mat-select [ngModel]="currentFormat" (ngModelChange)="onOutputFormatChange($event)">
<mat-option *ngFor="let format of outputFormats" [value]="format">
{{ format }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="flex flex-row policy-split-container">
<div class="policy-card-container w-3/5">
<app-policy-builder (policyChange)="onConfigChange($event)" [policyConfig]="policyConfig"></app-policy-builder>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,6 @@ export class PolicyEditorComponent {
this.updateJsonText(cfg, this.currentFormat);
}

onOutputFormatChange(format: OutputKind) {
this.updateJsonText(this.policyConfig, format);
}

updateJsonText(cfg: PolicyConfiguration, format: OutputKind) {
const ld = this.formatService.toJsonLd(cfg, format);
this.text = this.formatService.formatPolicy(ld);
Expand Down
63 changes: 43 additions & 20 deletions edc-policy-playground/src/app/models/policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ export class LogicalConstraint implements Constraint {
return cloned;
}

prefixes(): string[] {
const prefixes = this.constraints.flatMap(c => c.prefixes());
return ['odrl', ...prefixes];
get_prefixes(): string[] {
return this.constraints.flatMap(c => c.get_prefixes());
}

get_contexts(): string[] {
return this.constraints.flatMap(c => c.get_contexts());
}

toString() {
Expand All @@ -66,20 +69,14 @@ export class LogicalConstraint implements Constraint {
}

export class LeftOperand {
prefix?: string;
value: string;

constructor(value: string, prefix?: string) {
constructor(value: string) {
this.value = value;
this.prefix = prefix;
}

toString(withPrefix: boolean = true) {
if (withPrefix && this.prefix != null) {
return `${this.prefix}:${this.value}`;
} else {
return `${this.value}`;
}
toString() {
return `${this.value}`;
}
}

Expand All @@ -88,7 +85,9 @@ export class AtomicConstraint implements Constraint {
operator: Operator;
rightOperand?: string | number | Value;
kind: ValueKind;

contexts: string[] = [];
prefixes: string[] = [];
label?: string;
constructor();
constructor(leftOperand: LeftOperand);
constructor(leftOperand: LeftOperand, operator: Operator, rightOperator: RightOperand);
Expand All @@ -104,21 +103,44 @@ export class AtomicConstraint implements Constraint {
this.leftOperand = leftOperand != null ? leftOperand : new LeftOperand('');
this.rightOperand = rightOperand;
}

clone(): AtomicConstraint {
const cloned = new AtomicConstraint();
cloned.kind = this.kind;
cloned.leftOperand = this.leftOperand;
cloned.operator = this.operator;
cloned.rightOperand = this.rightOperand;
cloned.contexts = this.contexts;
cloned.label = this.label;
cloned.prefixes = this.prefixes;
return cloned;
}

prefixes(): string[] {
if (this.leftOperand.prefix) {
return [this.leftOperand.prefix];
} else {
return [];
}
get_prefixes(): string[] {
return this.prefixes;
}

get_contexts(): string[] {
return this.contexts;
}

get_label(): string {
return this.label != null ? this.label : this.leftOperand.value;
}

with_context(ctx: string): AtomicConstraint {
this.contexts.push(ctx);
return this;
}

with_prefix(prefix: string): AtomicConstraint {
this.prefixes.push(prefix);
return this;
}

with_label(label: string): AtomicConstraint {
this.label = label;
return this;
}

toString() {
Expand Down Expand Up @@ -156,7 +178,8 @@ export enum LogicalOperator {
export interface Constraint {
clone(): Constraint;

prefixes(): string[];
get_prefixes(): string[];
get_contexts(): string[];
}

export enum Action {
Expand Down
67 changes: 45 additions & 22 deletions edc-policy-playground/src/app/services/constraints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,47 @@

import { AtomicConstraint, LeftOperand, LogicalConstraint, Operator, Value, ValueKind } from '../models/policy';

const EDC_PREFIX = 'edc';
const IN_FORCE = 'inForceDate';
const DATE_EXPRESSION = EDC_PREFIX + ':dateExpression';
const DATE_EXPRESSION = 'dateExpression';

const XSD_DATETIME = 'xsd:datetime';
const TX_BASE_CONTEXT = 'https://w3id.org/tractusx/edc/v0.0.1';
const TX_POLICY_CONTEXT = 'https://w3id.org/tractusx/policy/v1.0.0';

const TX_PREFIX = 'tx';
const XSD_PREFIX = 'xsd';
const XSD_DATETIME = XSD_PREFIX + ':datetime';

export const bpnConstraint = () => {
return new AtomicConstraint(new LeftOperand('BusinessPartnerNumber'), Operator.Eq, '<bpnNumber>', ValueKind.String);
return new AtomicConstraint(
new LeftOperand('BusinessPartnerNumber'),
Operator.Eq,
'<bpnNumber>',
ValueKind.String,
).with_context(TX_BASE_CONTEXT);
};

export const bpnGroupConstraint = () => {
return new AtomicConstraint(new LeftOperand('BusinessPartnerGroup', TX_PREFIX), Operator.In, '<group>');
return new AtomicConstraint(new LeftOperand('BusinessPartnerGroup'), Operator.In, '<group>').with_context(
TX_BASE_CONTEXT,
);
};

export const inForceFixedConstraint = () => {
const constraint = new LogicalConstraint();
constraint.constraints.push(
new AtomicConstraint(
new LeftOperand(IN_FORCE, EDC_PREFIX),
new LeftOperand(IN_FORCE),
Operator.Gte,
new Value('2023-01-01T00:00:01Z', XSD_DATETIME),
ValueKind.Value,
),
).with_prefix(XSD_PREFIX),
);
constraint.constraints.push(
new AtomicConstraint(
new LeftOperand(IN_FORCE, EDC_PREFIX),
new LeftOperand(IN_FORCE),
Operator.Lte,
new Value('2024-01-01T00:00:01Z', XSD_DATETIME),
ValueKind.Value,
),
).with_prefix(XSD_PREFIX),
);
return constraint;
};
Expand All @@ -61,15 +69,15 @@ export const inForceDurationConstraint = () => {
const constraint = new LogicalConstraint();
constraint.constraints.push(
new AtomicConstraint(
new LeftOperand(IN_FORCE, EDC_PREFIX),
new LeftOperand(IN_FORCE),
Operator.Gte,
new Value('contractAgreement+0s', DATE_EXPRESSION),
ValueKind.Value,
),
);
constraint.constraints.push(
new AtomicConstraint(
new LeftOperand(IN_FORCE, EDC_PREFIX),
new LeftOperand(IN_FORCE),
Operator.Lte,
new Value('contractAgreement+100d', DATE_EXPRESSION),
ValueKind.Value,
Expand All @@ -78,17 +86,32 @@ export const inForceDurationConstraint = () => {
return constraint;
};

const credentials = [
'Membership',
'Dismantler',
'FrameworkAgreement.pcf',
'FrameworkAgreement.sustainability',
'FrameworkAgreement.quality',
'FrameworkAgreement.traceability',
'FrameworkAgreement.behavioraltwin',
'BPN',
const fremeworkAgreements = [
'Pcf',
'Traceability',
'Quality',
'CircularEconomy',
'DemandCapacity',
'Puris',
'BusinessPartner',
'BehavioralTwin',
];

const frameworkCredentials = fremeworkAgreements.map(frame => {
return { name: 'FrameworkAgreement', value: `${frame}:<version>`, label: frame };
});

const baseCredentials = [
{ name: 'Membership', value: 'active', label: 'Membership' },
{ name: 'Dismantler', value: 'active', label: 'Dismantler' },
];

const credentials = [...baseCredentials, ...frameworkCredentials];

export const credentialsConstraints = () => {
return credentials.map(c => new AtomicConstraint(new LeftOperand(c, TX_PREFIX), Operator.Eq, 'active'));
return credentials.map(c =>
new AtomicConstraint(new LeftOperand(c.name), Operator.Eq, c.value)
.with_context(TX_POLICY_CONTEXT)
.with_label(c.label),
);
};
2 changes: 0 additions & 2 deletions edc-policy-playground/src/app/services/format.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@
import { Injectable } from '@angular/core';
import { OutputKind, PolicyConfiguration } from '../models/policy';
import { PlainFormatter } from './format/plain';
import { PrefixFormatter } from './format/prefix';
import { PolicyService } from './policy.service';

@Injectable({ providedIn: 'root' })
export class FormatService {
formatters: Map<OutputKind, JsonLdFormatter> = new Map();
constructor(public policyService: PolicyService) {
this.formatters.set(OutputKind.Plain, new PlainFormatter(policyService));
this.formatters.set(OutputKind.Prefixed, new PrefixFormatter(policyService));
}

toJsonLd(policyConfig: PolicyConfiguration, format: OutputKind = OutputKind.Prefixed): object {
Expand Down
Loading

0 comments on commit 5f6c3be

Please sign in to comment.