diff --git a/docs/concept/#1108-policy-management-enhancement/#1108-policy-management-enhancement.md b/docs/concept/#1108-policy-management-enhancement/#1108-policy-management-enhancement.md new file mode 100644 index 0000000000..73422d68cc --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/#1108-policy-management-enhancement.md @@ -0,0 +1,650 @@ +# \[Concept\] \[#1108\] Policy management enhancement + +| Key | Value | +|---------------|---------------------------------------------------------------------------| +| Author | @ds-crehm | +| Creation date | 02.07.2024 | +| Ticket Id | [#849](https://github.com/eclipse-tractusx/traceability-foss/issues/1108) | +| State | DRAFT | + +# Table of Contents +1. [Overview](#overview) +2. [Requirements](#requirements) +3. [Concept](#concept) +4. [Additional Details](#additional-details) + + +# Overview +It must be possible for users to change policies used for asset provisioning and notifications in the frontend of Trace-X. + +# Requirements +- [ ] Parts can be republished + - [ ] A policy must be selected (chosen from the existing policies) + - [ ] Part will be synchronized automatically afterwards +- [ ] Policy updates trigger an update and synchronization of all related parts +- [ ] Policies can be set as active for notifications + - [ ] When sending notifications, active policies for the respective BPN are used for contract negotiation +- [ ] Data model is adapted to accommodate contract agreement history + +# Concept + +## When to update policies for parts +A part can be republished with a different policy -> in this case the policy must be updated with the chosen policy and then republished. +For this the policy update process below must be used and then the existing publish-process can be used to republish and synchronize the part. + +When a policy is updated, all parts that used this policy must be updated and republished with the new policy. +In this case, all parts using that policy must be updated. For this Trace-X must iterate through all parts and check if they use the changed policy. +Then the affected parts must have their policies updated. + +## Policy update process for parts +![policy-update.png](policy-update.png) + +1. **policyDefinition + globalAssetId** + +The globalAssetId for which the policy must be changed must be provided. And the new policy that should be used must be provided as well. + +2. **query_registry(globalAssetId)** + +The globalAssetId is used to retrieve the aasIdentifier from the registry: + +GET ***registryURL***/semantics/registry/api/v3/lookup/shells?assetIds=eyJuYW1lIjoiZ2xvYmFsQXNzZXRJZCIsInZhbHVlIjoidXJuOnV1aWQ6NmIyMjk2YmItMjZjMC00ZjM4LThhMjItMDkyMzM4YzM2ZTIyIn0%3D + +Header: "Edc-Bpn" = "***BPN***" + +The assetId attached to the URL is the following **base64-encoded**: + +{"name":"globalAssetId","value":"***globalAssetId***"} + +3. **aasIdentifier** + +The registry returns the aasIdentifier as JSON result like this: +```json +{ + "paging_metadata": {}, + "result": [ + "urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54" + ] +} +``` +The aasIdentifier must be cached for future requests. + +4. **get_shell(aasIdentifier)** + +The aasIdentifier is used to retrieve the shell from the registry: + +GET ***registryURL***/semantics/registry/api/v3/shell-descriptors/dXJuOnV1aWQ6NjM1YTgyNDItNGE4OS00ODgyLThhNmEtM2E3OGIzNDkyZjU0 + +Header: "Edc-Bpn" = "***BPN***" + +The ID attached to the URL is the aasIdentifier **base64-encoded**: urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54 -> dXJuOnV1aWQ6NjM1YTgyNDItNGE4OS00ODgyLThhNmEtM2E3OGIzNDkyZjU0 + +5. **shell** + +The shell is returned as JSON result like this: +```json +{ + "description": [], + "displayName": [], + "globalAssetId": "urn:uuid:6b2296cc-26c0-4f38-8a22-092338c36e22", + "idShort": "a/devVehicleHybrid-9d2ca28d8896407bbdc9a8f65c381cab", + "id": "urn:uuid:7e29e7e6-71a9-4f81-afc9-8b8434da4b0d", + "specificAssetIds": [ + { + "supplementalSemanticIds": [], + "name": "van", + "value": "OMAOYGBDTSRCMYSCX", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + }, + { + "supplementalSemanticIds": [], + "name": "partInstanceId", + "value": "OMAOYGBDTSRCMYSCX", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + }, + { + "supplementalSemanticIds": [], + "name": "manufacturerId", + "value": "BPNL00000003CML1", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + } + ], + "submodelDescriptors": [ + { + "endpoints": [ + { + "interface": "SUBMODEL-3.0", + "protocolInformation": { + "href": "https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:cc3d983e-63f3-46be-8b75-74efe2783d11", + "endpointProtocol": "HTTP", + "endpointProtocolVersion": [ + "1.1" + ], + "subprotocol": "DSP", + "subprotocolBody": "id=urn:uuid:fe4f0797-a650-451b-a17e-09ce79c13892;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net", + "subprotocolBodyEncoding": "plain", + "securityAttributes": [ + { + "type": "NONE", + "key": "NONE", + "value": "NONE" + } + ] + } + } + ], + "idShort": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart", + "id": "urn:uuid:cc3d983e-63f3-46be-8b75-74efe2783d11", + "semanticId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart" + } + ] + }, + "supplementalSemanticId": [], + "description": [], + "displayName": [] + }, + { + "endpoints": [ + { + "interface": "SUBMODEL-3.0", + "protocolInformation": { + "href": "https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:e16f7eaa-21f9-42ef-a38e-32f62a1d5efd", + "endpointProtocol": "HTTP", + "endpointProtocolVersion": [ + "1.1" + ], + "subprotocol": "DSP", + "subprotocolBody": "id=urn:uuid:fe4f0797-a650-451b-a17e-09ce79c13892;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net", + "subprotocolBodyEncoding": "plain", + "securityAttributes": [ + { + "type": "NONE", + "key": "NONE", + "value": "NONE" + } + ] + } + } + ], + "idShort": "urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt", + "id": "urn:uuid:e16f7eaa-21f9-42ef-a38e-32f62a1d5efd", + "semanticId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt" + } + ] + }, + "supplementalSemanticId": [], + "description": [], + "displayName": [] + } + ] +} +``` + +The shell must be cached for future requests. + +6. **get_contractDefinition(shell.subprotocolBodyID)** + +The contractDefinition is retrieved from the EDC using the subprotocolBodyID. +The subprotocolBodyID is taken from the string contained in submodelDescriptors.endpoints.protocolInformation.subprotocolBody. +The ID should be the same for every submodel, so it can be taken from any of them. +In the best case, it should be taken from the submodel of type SerialPart, since that is the default used in every asset. + +POST ***EDC-providerURL***/management/v2/contractdefinitions/request + +JSON body: +```json +{ + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "filterExpression": { + "operandLeft": "assetsSelector.operandRight", + "operator": "=", + "operandRight": "<<>>" + } +} +``` + +7. **contractDefinition** + +The contractDefinition is returned as JSON result like this: +```json +[ + { + "@id": "0f410a5c-b51b-4546-bae2-eacc20483e15", + "@type": "ContractDefinition", + "accessPolicyId": "traceability-core", + "contractPolicyId": "traceability-core", + "assetsSelector": { + "@type": "Criterion", + "operandLeft": "https://w3id.org/edc/v0.0.1/ns/id", + "operator": "=", + "operandRight": "urn:uuid:fe4f0797-a650-451b-a17e-09ce79c13892" + }, + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/", + "edc": "https://w3id.org/edc/v0.0.1/ns/", + "tx": "https://w3id.org/tractusx/v0.0.1/ns/", + "tx-auth": "https://w3id.org/tractusx/auth/", + "cx-policy": "https://w3id.org/catenax/policy/", + "odrl": "http://www.w3.org/ns/odrl/2/" + } + } +] +``` + +Only the accessPolicyId or the contractPolicyId is needed for the next request. +Since both are always identical at the time of writing, it doesn't matter which one is used. +I decided to use the contractPolicyId. + +8. **get_policyDefinition(contractDefinition.contractPolicyId)** + +The policyDefinition is retrieved from the EDC using the contractPolicyId: + +GET ***EDC-providerURL***/management/v2/policydefinitions/***contractPolicyId*** + +9. **policyDefinition** + +The policyDefinition is returned as JSON result like this: +```json +{ + "@id": "traceability-core", + "@type": "PolicyDefinition", + "createdAt": 1719845712993, + "policy": { + "@id": "c71b6886-b0fa-4348-8006-38d669d61dbc", + "@type": "odrl:Set", + "odrl:permission": { + "odrl:action": { + "odrl:type": "use" + }, + "odrl:constraint": { + "odrl:and": [ + { + "odrl:leftOperand": "cx-policy:FrameworkAgreement", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "traceability:1.0" + }, + { + "odrl:leftOperand": "cx-policy:UsagePurpose", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "cx.core.industrycore:1" + } + ] + } + }, + "odrl:prohibition": [], + "odrl:obligation": [] + }, + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/", + "edc": "https://w3id.org/edc/v0.0.1/ns/", + "tx": "https://w3id.org/tractusx/v0.0.1/ns/", + "tx-auth": "https://w3id.org/tractusx/auth/", + "cx-policy": "https://w3id.org/catenax/policy/", + "odrl": "http://www.w3.org/ns/odrl/2/" + } +} +``` + +10. **compare policies** + +The policy retrieved from the last step and the policy initially provided by the user (Step 1) must be compared. + +If the compared policies in step 10 are identical, nothing must be changed and the process can be finalized (**step 11**). +If the compared policies in step 10 are **not** identical, continue with **step 12**. + +12. **create asset** + +A new policy asset must be created in the EDC: + +POST ***EDC-providerURL***/management/v3/assets + +JSON body: +```json +{ + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "<<>>", + "properties": { + "description": "<<>>" + }, + "dataAddress": { + "proxyPath": "true", + "type": "HttpData", + "proxyMethod": "false", + "proxyQueryParams": "false", + "proxyBody": "false", + "baseUrl": "<<>>" + } +} +``` + +The policy description may be omitted as well: + +```json +{ + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "<<>>", + "properties": { + }, + "dataAddress": { + "proxyPath": "true", + "type": "HttpData", + "proxyMethod": "false", + "proxyQueryParams": "false", + "proxyBody": "false", + "baseUrl": "https://traceability-e2e-a.dev.demo.catena-x.net" + } +} +``` + +The baseURL must be taken from the currently used instance and environment configuration. +The ID must be cached for the last two requests. + +13. **create new policyDefinition** + +A new policy with the provided data must be created in the EDC: + +POST ***EDC-providerURL***/management/v2/policydefinitions + +JSON body: +```json +{ + "@context": { + "odrl": "http://www.w3.org/ns/odrl/2/" + }, + "@id": "<<>>", + "policy": { + "@type": "odrl:Set", + "odrl:permission": { + "odrl:action": { + "odrl:type": "use" + }, + "odrl:constraint": { + "odrl:and": [ + { + "odrl:leftOperand": "cx-policy:FrameworkAgreement", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "traceability:1.0" + }, + { + "odrl:leftOperand": "cx-policy:UsagePurpose", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "cx.core.industrycore:1" + } + ] + } + } + } +} +``` + +The newly created policyDefinition must be taken from the provided policyDefinition (step 1). +The ID must be cached for the next request. + +14. **create new contractDefinition(with new assetID+policyDefinitionID)** + +A new contractDefinition must be created in the EDC using the previously created asset and policyDefinition: + +POST ***EDC-providerURL***/management/v2/contractdefinitions + +JSON body: +```json +{ + "@context": { + "edc": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "<<>>", + "accessPolicyId": "<<>>", + "contractPolicyId": "<<>>", + "assetsSelector": { + "operandLeft": "https://w3id.org/edc/v0.0.1/ns/id", + "operator": "=", + "operandRight": "<<>>" + } +} +``` + +15. **update shell(with new subprotocolBodyID)** + +The final step is to update the shell with the newly created asset, which is set to be a contractDefinition that uses the provided policy: + +PUT ***registryURL***/semantics/registry/api/v3/shell-descriptors/dXJuOnV1aWQ6NjM1YTgyNDItNGE4OS00ODgyLThhNmEtM2E3OGIzNDkyZjU0 + +Header: "Edc-Bpn" = "***BPN***" + +JSON body: +```json +{ + "description": [], + "displayName": [], + "globalAssetId": "urn:uuid:6b2296cc-26c0-4f38-8a22-092338c36e22", + "idShort": "a/devVehicleHybrid-7f4198785bb64374b984839201f61cd2", + "id": "urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54", + "specificAssetIds": [ + { + "name": "van", + "value": "OMAOYGBDTSRCMYSCX", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + }, + { + "name": "manufacturerId", + "value": "BPNL00000003CML1", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + }, + { + "name": "partInstanceId", + "value": "OMAOYGBDTSRCMYSCX", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + } + ], + "submodelDescriptors": [ + { + "endpoints": [ + { + "interface": "SUBMODEL-3.0", + "protocolInformation": { + "href": "https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:8e1ecd87-fef6-4351-a2d1-4b916ed2d4da", + "endpointProtocol": "HTTP", + "endpointProtocolVersion": [ + "1.1" + ], + "subprotocol": "DSP", + "subprotocolBody": "id=<<>>;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net", + "subprotocolBodyEncoding": "plain", + "securityAttributes": [ + { + "type": "NONE", + "key": "NONE", + "value": "NONE" + } + ] + } + } + ], + "idShort": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart", + "id": "urn:uuid:8e1ecd87-fef6-4351-a2d1-4b916ed2d4da", + "semanticId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart" + } + ] + }, + "description": [], + "displayName": [] + }, + { + "endpoints": [ + { + "interface": "SUBMODEL-3.0", + "protocolInformation": { + "href": "https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:877c79ef-6279-49f2-9d2b-bcc7e1f5f28e", + "endpointProtocol": "HTTP", + "endpointProtocolVersion": [ + "1.1" + ], + "subprotocol": "DSP", + "subprotocolBody": "id=<<>>;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net", + "subprotocolBodyEncoding": "plain", + "securityAttributes": [ + { + "type": "NONE", + "key": "NONE", + "value": "NONE" + } + ] + } + } + ], + "idShort": "urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt", + "id": "urn:uuid:877c79ef-6279-49f2-9d2b-bcc7e1f5f28e", + "semanticId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt" + } + ] + }, + "description": [], + "displayName": [] + } + ] +} +``` + +The ID attached to the URL is the aasIdentifier **base64-encoded**: urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54 -> dXJuOnV1aWQ6NjM1YTgyNDItNGE4OS00ODgyLThhNmEtM2E3OGIzNDkyZjU0 +The JSON body is the shell taken from **step 5** with the subprotocolBodyID of all submodelDescriptor endpoints replaced with the assetID from **step 12**. +Additionally, all empty instances of "supplementalSemanticId" must be removed for the request to work. + +An Insomnia collection is provided with the respective requests. (policy-update.json) + +## Policies used for notification process +To change the policy used for sending notifications a frontend switch must be possible in the policy management view: +![notification-policies.png](notification-policies.png) +In the backend the contract negotiation already happens with the default policy. +During this step the backend must instead fetch all configured and active (validUntil > currentTime) notification policies for the receiver BPN. +If there are multiple active ones, the contract negotiation will take place with all of them. +When the policy matches, the negotiation is successful. + +## Data model changes +In order to make the contract agreement history transparent for parts, the contractAgreementId field must be changed to an array: +```diff +{ + "id": "urn:uuid:7c7d5aec-b15d-491c-8fbd-c61c6c02c69a", + "idShort": "VehicleHybrid-df9f9360279548a68a5757c3d4513f8e", + "semanticModelId": "OMAZRXWWMSPTQUEKI", + "businessPartner": "BPNL00000003CML1", + "manufacturerName": null, + "nameAtManufacturer": "Vehicle Hybrid", + "manufacturerPartId": "5519583-63", + "owner": "OWN", + "childRelations": [], + "parentRelations": [], + "qualityType": "Ok", + "van": "OMAZRXWWMSPTQUEKI", + "semanticDataModel": "SERIALPART", + "classification": null, + "detailAspectModels": [ + { + "type": "AS_BUILT", + "data": { + "partId": "5519583-63", + "customerPartId": "", + "nameAtCustomer": "", + "manufacturingCountry": "DEU", + "manufacturingDate": "2015-02-04T14:48:54Z" + } + } + ], + "sentQualityAlertIdsInStatusActive": [ + 1, + 2, + 3 + ], + "receivedQualityAlertIdsInStatusActive": [], + "sentQualityInvestigationIdsInStatusActive": [], + "receivedQualityInvestigationIdsInStatusActive": [], + "importState": "PERSISTENT", + "importNote": "Asset created/updated successfully in persistent state.", + "tombstone": null, +--- "contractAgreementId": "15fbb395-6d40-4299-a433-c61954afb8d9" ++++ "contractAgreementId": ["15fbb395-6d40-4299-a433-c61954afb8d9","28cdd395-1234-4321-55aa-c61954afb8d9"] +} +``` + +# Additional Details +Given the dynamic nature of ongoing development, there might be variations between the conceptualization and the current implementation. For the latest status, refer to the documentation. diff --git a/docs/concept/#1108-policy-management-enhancement/notification-policies.png b/docs/concept/#1108-policy-management-enhancement/notification-policies.png new file mode 100644 index 0000000000..738ecabc7c Binary files /dev/null and b/docs/concept/#1108-policy-management-enhancement/notification-policies.png differ diff --git a/docs/concept/#1108-policy-management-enhancement/policy-update.json b/docs/concept/#1108-policy-management-enhancement/policy-update.json new file mode 100644 index 0000000000..ddb1aaf991 --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/policy-update.json @@ -0,0 +1 @@ +{"_type":"export","__export_format":4,"__export_date":"2024-07-08T09:34:20.241Z","__export_source":"insomnia.desktop.app:v2023.5.8","resources":[{"_id":"req_c981967d54b042dbafe208c7b6a50edf","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431136336,"created":1719576341118,"url":"{{ _.registry }}/semantics/registry/api/v3/lookup/shells","name":"1 Query Registry by globalAssetId","description":"","method":"GET","body":{},"parameters":[{"name":"assetIds","value":"{% base64 'encode', 'normal', '{\"name\":\"globalAssetId\",\"value\":\"urn:uuid:6b2296cc-26c0-4f38-8a22-092338c36e22\"}' %}","disabled":false,"id":"pair_f5f3d12fb2224c1d9e577c42128aa3d9"}],"headers":[{"id":"pair_71ae5e562e9c414a82e84220f3c00343","name":"Edc-Bpn","value":"BPNL00000003CNKC","description":""}],"authentication":{},"metaSortKey":-1715858336003,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_98caad3c0c70421dbe34e55e9d8078de","parentId":null,"modified":1720431114465,"created":1720431114465,"name":"Update policies","description":"","scope":"collection","_type":"workspace"},{"_id":"req_608d45c126ee46ce8330f712428f247f","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431138554,"created":1719576341210,"url":"{{ _.registry }}/semantics/registry/api/v3/shell-descriptors/{% base64 'encode', 'normal', 'urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54' %}","name":"2 GetShell by aasIdentifier","description":"","method":"GET","body":{},"parameters":[],"headers":[{"id":"pair_7877c58fd3ae46758cabf9f6cb397818","name":"Edc-Bpn","value":"BPNL00000003CNKC","description":"","disabled":false}],"authentication":{},"metaSortKey":-1715858335953,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_d33ec33d40f0402bb68da9612c7ea90e","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431140687,"created":1719578461432,"url":"{{ _.edc_provider_own }}/management/v2/contractdefinitions/request","name":"3 GetContractDefinition","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"@context\": {\n\t\t\"@vocab\": \"https://w3id.org/edc/v0.0.1/ns/\"\n\t},\n\t\"filterExpression\": {\n\t\t\"operandLeft\": \"assetsSelector.operandRight\",\n\t\t\"operator\": \"=\",\n\t\t\"operandRight\": \"urn:uuid:fe4f0797-a650-451b-a17e-09ce79c13892\"\n\t}\n}"},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335928,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_ddfb26a9ff864867b2a7015cec5741a8","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431142594,"created":1719578623696,"url":"{{ _.edc_provider_own }}/management/v2/policydefinitions/traceability-core","name":"4 GetPolicyDefinition","description":"","method":"GET","body":{"mimeType":"application/json","text":""},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335915.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_0f8c9b91a06041bf9b3066448bc0ced5","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431144604,"created":1688069768394,"url":"{{ _.edc_provider_own }}/management/v3/assets","name":"5 CreateAsset","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"@context\": {\n\t\t\"@vocab\": \"https://w3id.org/edc/v0.0.1/ns/\"\n\t},\n\t\"@id\": \"policy-test-asset\",\n\t\"properties\": {\n\t},\n\t\"dataAddress\": {\n\t\t\"proxyPath\": \"true\",\n\t\t\"type\": \"HttpData\",\n\t\t\"proxyMethod\": \"false\",\n\t\t\"proxyQueryParams\": \"false\",\n\t\t\"proxyBody\": \"false\",\n\t\t\"baseUrl\": \"https://traceability-e2e-a.dev.demo.catena-x.net\"\n\t}\n}"},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335909.25,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_86e748b071974201be2ba737e3b55c93","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431147018,"created":1688067318173,"url":"{{ _.edc_provider_own }}/management/v2/policydefinitions","name":"6 CreatePolicyDefinition","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"@context\": {\n\t\t\"odrl\": \"http://www.w3.org/ns/odrl/2/\"\n\t},\n\t\"@id\": \"policy-test\",\n\t\"policy\": {\n\t\t\"@type\": \"odrl:Set\",\n\t\t\"odrl:permission\": {\n\t\t\t\"odrl:action\": {\n\t\t\t\t\"odrl:type\": \"use\"\n\t\t\t},\n\t\t\t\"odrl:constraint\": {\n\t\t\t\t\"odrl:and\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"odrl:leftOperand\": \"cx-policy:FrameworkAgreement\",\n\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"odrl:rightOperand\": \"traceability:1.0\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"odrl:leftOperand\": \"cx-policy:UsagePurpose\",\n\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"odrl:rightOperand\": \"cx.core.industrycore:1\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n}"},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335906.125,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_62799f6e9bf54e0dbc937e928e3d9682","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431149000,"created":1688111070053,"url":"{{ _.edc_provider_own }}/management/v2/contractdefinitions","name":"7 CreateContractDefinition","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"@context\": {\n\t\t\"edc\": \"https://w3id.org/edc/v0.0.1/ns/\"\n\t},\n\t\"@id\": \"policy-test-contractdefinition\",\n\t\"accessPolicyId\": \"policy-test\",\n\t\"contractPolicyId\": \"policy-test\",\n\t\"assetsSelector\": {\n\t\t\"operandLeft\": \"https://w3id.org/edc/v0.0.1/ns/id\",\n\t\t\"operator\": \"=\",\n\t\t\"operandRight\": \"policy-test-asset\"\n\t}\n}"},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335904.5625,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_b3051df9f2214b7db09cdf06deafd9c5","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431151270,"created":1719579937454,"url":"{{ _.registry }}/semantics/registry/api/v3/shell-descriptors/{% base64 'encode', 'normal', 'urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54' %}","name":"8 Update Shell","description":"","method":"PUT","body":{"mimeType":"application/json","text":"{\n\t\"description\": [],\n\t\"displayName\": [],\n\t\"globalAssetId\": \"urn:uuid:6b2296cc-26c0-4f38-8a22-092338c36e22\",\n\t\"idShort\": \"a/devVehicleHybrid-7f4198785bb64374b984839201f61cd2\",\n\t\"id\": \"urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54\",\n\t\"specificAssetIds\": [\n\t\t{\n\t\t\t\"name\": \"van\",\n\t\t\t\"value\": \"OMAOYGBDTSRCMYSCX\",\n\t\t\t\"externalSubjectId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"BPNL00000003CNKC\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"name\": \"manufacturerId\",\n\t\t\t\"value\": \"BPNL00000003CML1\",\n\t\t\t\"externalSubjectId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"BPNL00000003CNKC\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"name\": \"partInstanceId\",\n\t\t\t\"value\": \"OMAOYGBDTSRCMYSCX\",\n\t\t\t\"externalSubjectId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"BPNL00000003CNKC\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t\"submodelDescriptors\": [\n\t\t{\n\t\t\t\"endpoints\": [\n\t\t\t\t{\n\t\t\t\t\t\"interface\": \"SUBMODEL-3.0\",\n\t\t\t\t\t\"protocolInformation\": {\n\t\t\t\t\t\t\"href\": \"https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:8e1ecd87-fef6-4351-a2d1-4b916ed2d4da\",\n\t\t\t\t\t\t\"endpointProtocol\": \"HTTP\",\n\t\t\t\t\t\t\"endpointProtocolVersion\": [\n\t\t\t\t\t\t\t\"1.1\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"subprotocol\": \"DSP\",\n\t\t\t\t\t\t\"subprotocolBody\": \"id=policy-test-asset;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net\",\n\t\t\t\t\t\t\"subprotocolBodyEncoding\": \"plain\",\n\t\t\t\t\t\t\"securityAttributes\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"NONE\",\n\t\t\t\t\t\t\t\t\"key\": \"NONE\",\n\t\t\t\t\t\t\t\t\"value\": \"NONE\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"idShort\": \"urn:samm:io.catenax.serial_part:3.0.0#SerialPart\",\n\t\t\t\"id\": \"urn:uuid:8e1ecd87-fef6-4351-a2d1-4b916ed2d4da\",\n\t\t\t\"semanticId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"urn:samm:io.catenax.serial_part:3.0.0#SerialPart\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"description\": [],\n\t\t\t\"displayName\": []\n\t\t},\n\t\t{\n\t\t\t\"endpoints\": [\n\t\t\t\t{\n\t\t\t\t\t\"interface\": \"SUBMODEL-3.0\",\n\t\t\t\t\t\"protocolInformation\": {\n\t\t\t\t\t\t\"href\": \"https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:877c79ef-6279-49f2-9d2b-bcc7e1f5f28e\",\n\t\t\t\t\t\t\"endpointProtocol\": \"HTTP\",\n\t\t\t\t\t\t\"endpointProtocolVersion\": [\n\t\t\t\t\t\t\t\"1.1\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"subprotocol\": \"DSP\",\n\t\t\t\t\t\t\"subprotocolBody\": \"id=policy-test-asset;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net\",\n\t\t\t\t\t\t\"subprotocolBodyEncoding\": \"plain\",\n\t\t\t\t\t\t\"securityAttributes\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"NONE\",\n\t\t\t\t\t\t\t\t\"key\": \"NONE\",\n\t\t\t\t\t\t\t\t\"value\": \"NONE\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"idShort\": \"urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt\",\n\t\t\t\"id\": \"urn:uuid:877c79ef-6279-49f2-9d2b-bcc7e1f5f28e\",\n\t\t\t\"semanticId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"description\": [],\n\t\t\t\"displayName\": []\n\t\t}\n\t]\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json","id":"pair_4defbf48f3c64e9da238cb4ef843b43d"},{"name":"Edc-Bpn","value":"BPNL00000003CNKC","id":"pair_10710d07198e47bc8e2b55555a93e649"}],"authentication":{},"metaSortKey":-1715858335903.7812,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_5c484adc4b9ba8982d565e3bcbd5dcbdc4c2e63b","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431114487,"created":1720431114487,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1720431114487,"_type":"environment"},{"_id":"jar_5c484adc4b9ba8982d565e3bcbd5dcbdc4c2e63b","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431114559,"created":1720431114559,"name":"Default Jar","cookies":[],"_type":"cookie_jar"}]} diff --git a/docs/concept/#1108-policy-management-enhancement/policy-update.png b/docs/concept/#1108-policy-management-enhancement/policy-update.png new file mode 100644 index 0000000000..5b67b45518 Binary files /dev/null and b/docs/concept/#1108-policy-management-enhancement/policy-update.png differ diff --git a/docs/concept/#1108-policy-management-enhancement/policy-update.puml b/docs/concept/#1108-policy-management-enhancement/policy-update.puml new file mode 100644 index 0000000000..53e49d1239 --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/policy-update.puml @@ -0,0 +1,44 @@ +@startuml +title + ==Policy update +end title + +autonumber "[00]" + +actor "User" as U order 0 +participant "Trace-X" as TX order 1 +participant "Registry" as R order 2 +participant "EDC" as EDC order 3 + +U -> TX: policyDefinition + globalAssetId +activate TX +TX -> R: query_registry(globalAssetId) +activate R +R --> TX: aasIdentifier +deactivate R +TX -> R: get_shell(aasIdentifier) +activate R +R --> TX: shell +deactivate R +TX -> EDC: get_contractDefinition(shell.subprotocolBodyID) +activate EDC +EDC --> TX: contractDefinition +deactivate EDC +TX -> EDC: get_policyDefinition(contractDefinition.contractPolicyId) +activate EDC +EDC --> TX: policyDefinition +deactivate EDC +TX -> TX: compare policies +alt Policies match +TX --> U: Done without changes +else Policies don't match +TX -> EDC: create asset +TX -> EDC: create new policyDefinition +TX -> EDC: create new contractDefinition(with new assetID+policyDefinitionID) +TX -> R: update_shell(with new subprotocolBodyID) +TX --> U: Done with policy update +deactivate TX +end + + +@enduml