[Concept] Improvement of Policy Store API
Opened this issue · 3 comments
As team
I want concept how to improve the policy store api to avoid certain problems
so that we could provide a proper and suitable policy handling over the policy store api
Link
Hints / Details
- Create policy with policyId
- Add policyId to BPNLs []
- Define default policy
- Removal of policy from BPNL
- Deletion of policy from BPNL[]
Acceptance Criteria
- Concept covers (https://github.com/catenax-ng/tx-item-relationship-service/blob/main/docs/concept/TEMPLATE_Concept.md)
- API creating a unique policy object with a unique id
- Adding and modifying the validUnit of a policy object
- Policy Object is unique in the application and only id-reference is stored for BPNLs
- Adding policies to BPNLs
- Removing policies from BPNLs
- Delete policies and remove them from all BPNLs
- Handling of default policy
- Validation of all input parameters like policyId or BPNL
- policyId uses UUID4 format to be validated
- GET all policy uses pagination
Out of Scope
- ...
Hints
This is a proposal to be revised
Create a policy
=>
CREATED
{
"policyId": "policy1",
"bpnls": [ <list of bpnls> ]
}
validation: if any validation error occurs nothing should be created and validation errors should be returned
- bpnls are mandatory -> 400
- bpnls must be valid -> 400
- validUntil is mandatory -> 400
- validUntil must be valid- > 400
- validUntil must be in future -> 400
- payload is mandatory -> 400
- payload must contain policyId -> 400
- policyId must conform to pattern ???to be defined???? -> 400
- payload must be schema conform -> 400
- policy with this policyId already exists -> 409, CONFLICT
other error responses return status and list of error messages
Updating a policy
Update a policy completely
PUT will remove the policy with the given ID from all not specified BPNLs (because PUT is defined as REPLACE).
PUT /irs/policies/policy1
{
"bpnls": ["BPNL1234567890AB", "BPNL1234567890AB"],
"validUntil": "2025-12-12T23:59:59.999Z",
"payload": {
"@context": {
"odrl": "http://www.w3.org/ns/odrl/2/"
},
"@id": "policy1",
"@type": "PolicyDefinitionRequestDto",
"policy": {
"@type": "Policy",
"odrl:permission": [
{
"odrl:action": "USE",
"odrl:constraint": {
"odrl:and": [
{
"odrl:leftOperand": "Membership",
"odrl:operator": {
"@id": "odrl:eq"
},
"odrl:rightOperand": "active"
},
{
"odrl:leftOperand": "PURPOSE",
"odrl:operator": {
"@id": "odrl:eq"
},
"odrl:rightOperand": "ID 3.1 Trace"
}
]
}
}
]
}
}
}
validation: if any validation error occurs nothing should be created and validation errors should be returned
- bpnls are mandatory -> 400
- bpnls must be valid -> 400
- validUntil is mandatory -> 400
- validUntil must be valid -> 400
- validUntil must be in future -> 400
- payload is mandatory -> 400
- payload must contain policyId -> 400
- policyId must conform to pattern ???to be defined????
- payload must be schema conform -> 400
- policyId in path does not match policyId in given payload -> 400
other error responses return status and list of error messages
Update a policies' validUntil
PATCH /irs/policies/<policyId>
with body
{
validUntil: "<new validUntil>"
}
validation:
- validUntil is mandatory -> 400
- validUntil must be valid -> 400
- validUntil must be in future -> 400
- policy with ID must exist -> 404, NOT FOUND
other error responses return status and list of error messages
Getting information about policies
Get all policies
as currently implemented:
GET /irs/policies
=>
{
"BPNL1234567890EE": [
<list of policies as full JSON>
],
"BPNL1234567890FF": [
<list of policies as full JSON>
],
...
}
Get policies for BPNLs
as currently implemented:
GET /irs/policies?businessPartnerNumbers=BPNL1234567890EE&businessPartnerNumbers=BPNL1234567890FF
=>
{
"BPNL1234567890EE": [
<list of policies as full JSON>
],
"BPNL1234567890FF": [
<list of policies as full JSON>
]
}
Get policy by policyId
GET /irs/policies/policy1
{
"bpnls": ["BPNL1234567890AB", "BPNL1234567890AB"],
"validUntil": "2025-12-12T23:59:59.999Z",
"payload": {
"@context": {
"odrl": "http://www.w3.org/ns/odrl/2/"
},
"@id": "policy1",
"@type": "PolicyDefinitionRequestDto",
"policy": {
"@type": "Policy",
"odrl:permission": [
{
"odrl:action": "USE",
"odrl:constraint": {
"odrl:and": [
{
"odrl:leftOperand": "Membership",
"odrl:operator": {
"@id": "odrl:eq"
},
"odrl:rightOperand": "active"
},
{
"odrl:leftOperand": "PURPOSE",
"odrl:operator": {
"@id": "odrl:eq"
},
"odrl:rightOperand": "ID 3.1 Trace"
}
]
}
}
]
}
}
}
when policy does not exist -> 404
Get the validUntil of a policy
GET /irs/policies/<policyId>?fields=validUntil
=>
OK
{
validUntil: "<valid until date>"
}
validation:
- when fields contains unsupported fields -> 400
- when policy does not exist -> 404
Get the payload of a policy
GET /irs/policies/<policyId>?fields=payload
=>
OK
{
payload: <the policy payload>
}
validation:
- when fields contains unsupported fields -> 400
- when policy does not exist -> 404
Get BPNL - policy associations
Get the BPNLs for a policy
GET /irs/policies/<policyId>?fields=bpnls
=>
OK
{
bpnls: [ <list of BPNLs> ]
}
validation:
- when fields contains unsupported fields -> 400
- when policy does not exist -> 404
Get the policyIds for a BPNL
GET /irs/bpnls/<BPNL>?fields=policyIds
=>
OK
{
policyIds: [ <list of policyIds> ]
}
validation:
- when fields contains unsupported fields -> 400
- when BPNL is invalid -> 400
- when BPNL not found -> 404 ????
- when policy does not exist -> 404
Update BPNL - policy associations
Remove policy from BPNL
Remove policy from BPNL
DELETE /irs/policies/<thePolicyId>/bpnl/<theBPNL>
disadvantages:
- only 1:1 delete
- requires another endpoint for adding BPNL to a polidy
advantage:
- easy error handling
validation:
- when policy does not exist -> 404
- when BPNL is invalid -> 400
- when BPNL not found -> 404 ????
the following PATCH requests would be more flexible:
Associate policyIds to a BPNL
PATCH /irs/bpnls/<BPNL>
body for automatic addition / removal:
{
policyIds: [ <list of policyIds> ]
}
body for for defined addition / removal:
{
policyIdsToAdd: [ <list of policyIds> ],
policyIdsToRemove: [ <list of policyIds> ]
}
validation:
- when BPNL is invalid -> 400
- when BPNL does not exist -> 404 ????
- when neither policyIds nor policyIdsToAdd nor policyIdsToRemove is given -> 400
- when both policyIds and one of policyIdsToAdd or policyIdsToRemove is given -> 400
- when policyIds do not conform to pattern ????? -> 400
in both cases response:
{
policyIdsAdded: [ <list of policyIds> ],
policyIdsRemoved: [ <list of policyIds> ],
errors: [ ... ]
}
Associate BPNLs to a policy
PATCH /irs/policies/<policyId>
body for automatic addition / removal:
{
bpnls: [ <list of BPNLs> ]
}
body for for defined addition / removal:
{
bpnlsToAdd: [ <list of BPNLs> ],
bpnlsToRemove: [ <list of BPNLs> ]
}
validation:
- when policy does not exist -> 404
- when some BPNLs are invalid -> 400
- when some BPNLs do not exist -> 404 ????
- when neither bpnls nor bpnlsToAdd nor bpnlsToRemove is given -> 400
- when both bpnls and one of bpnlsToAdd or bpnlsToRemove is given -> 400
in both cases response:
{
bpnlsAdded: [ <list of policyIds> ],
bpnlsRemoved: [ <list of policyIds> ],
errors: [...]
}
Delete a policy
Deletes policy from all BPNLs
DELETE /irs/policies/<thePolicyId>
validation:
- policy does not exist -> 404
response:
OK
{
bpnlsRemoved: [ <list of policyIds> ]
}
Default policies
Create a default policy
Same as "Create a policy" but
with dedicated URL POST /irs/default-policies/default-policy-1
and without attribute "bpnls".
Update a default policy completely
Same as "Update a policy completely" but
with dedicated URL PUT /irs/default-policies/default-policy-1
and without attribute "bpnls".
Update a default policies' validUntil
Same as "Update a policies' validUntil" but
with dedicated URL PATCH /irs/default-policies/default-policy-1
.
Delete a default policy
Same as "Delete a policy" but
with dedicated URL DELETE /irs/default-policies/default-policy-1
.
todo:
- review / discussion
- review against REST API guide https://confluence.doubleslash.de/confluence/pages/viewpage.action?pageId=151729611
for comparison:
- current swagger on DEV: https://irs.dev.demo.catena-x.net/api/swagger-ui/index.html
- PolicyStoryController: https://github.com/catenax-ng/tx-item-relationship-service/blob/main/irs-policy-store/src/main/java/org/eclipse/tractusx/irs/policystore/controllers/PolicyStoreController.java
design goals:
- simplify error handling as much as possible
- use restful urls
- consistency
- remove ambiguity
- make API mostly self-explanatory (using standard structures, good naming of resources, params, attributs,...)
- validation before writes
- allow to update single fields
- allow to specify associations in a dedicated way
- do not allow n:m association updates in one request (use multiple requests instead e.g. multiple 1:m update requests)
@mkanal "Policy Object is unique in the application and only id-reference is stored for BPNLs" would a lot more than just API change, it involves changes to the underlying data storage or even a change of technology to relational DB. While it might have been good to think about this earlier I am not sure whether it is good to change this now.