Skip to content

Commit

Permalink
feat(irs-api):[#199] register policy definition for certain bpnls
Browse files Browse the repository at this point in the history
  • Loading branch information
ds-psosnowski committed Mar 5, 2024
1 parent 20face3 commit 8028ac4
Show file tree
Hide file tree
Showing 44 changed files with 4,334 additions and 4,146 deletions.
2 changes: 0 additions & 2 deletions charts/irs-helm/templates/configmap-spring-app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,6 @@ data:
{{- end }}
{{- end }}
apiAllowedBpn: {{ tpl (.Values.bpn | default "") . | quote }}
{{- if .Values.config.content }}
{{- tpl (toYaml .Values.config.content) . | nindent 4 }}
{{- end }}
146 changes: 109 additions & 37 deletions docs/src/api/irs-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,50 @@ paths:
summary: Register a policy that should be accepted in EDC negotiation.
tags:
- Item Relationship Service
put:
description: Updates an existing policy.
operationId: updateAllowedPolicy
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UpdatePolicyRequest'
required: true
responses:
"200":
description: OK
"400":
content:
application/json:
examples:
error:
$ref: '#/components/examples/error-response-400'
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Policy update failed.
"401":
content:
application/json:
examples:
error:
$ref: '#/components/examples/error-response-401'
schema:
$ref: '#/components/schemas/ErrorResponse'
description: No valid authentication credentials.
"403":
content:
application/json:
examples:
error:
$ref: '#/components/examples/error-response-403'
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Authorization refused by server.
security:
- api_key: [ ]
summary: Updates an existing policy.
tags:
- Item Relationship Service
/irs/policies/{policyId}:
delete:
description: Removes a policy that should no longer be accepted in EDC negotiation.
Expand Down Expand Up @@ -919,33 +963,27 @@ paths:
summary: Removes a policy that should no longer be accepted in EDC negotiation.
tags:
- Item Relationship Service
put:
description: Updates an existing policy with new validUntil value.
operationId: updateAllowedPolicy
/irs/policies/{bpns}:
get:
description: Lists the registered policies that should be accepted in EDC negotiation.
operationId: getAllowedPoliciesByBpn
parameters:
- in: path
name: policyId
- name: bpns
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UpdatePolicyRequest'
required: true
type: array
items:
type: string
responses:
"200":
description: OK
"400":
content:
application/json:
examples:
error:
$ref: '#/components/examples/error-response-400'
schema:
$ref: '#/components/schemas/ErrorResponse'
description: Policy update failed.
type: array
items:
$ref: '#/components/schemas/Policy'
description: Returns the policies.
"401":
content:
application/json:
Expand All @@ -965,8 +1003,8 @@ paths:
$ref: '#/components/schemas/ErrorResponse'
description: Authorization refused by server.
security:
- api_key: []
summary: Updates an existing policy with new validUntil value.
- api_key: [ ]
summary: Lists the registered policies that should be accepted in EDC negotiation.
tags:
- Item Relationship Service
components:
Expand Down Expand Up @@ -1714,9 +1752,9 @@ components:
description: Request to add a policy
properties:
payload:
type: object
additionalProperties:
$ref: '#/components/schemas/JsonValue'
type: array
items:
$ref: '#/components/schemas/JsonObject'
example:
payload:
'@context':
Expand All @@ -1736,23 +1774,14 @@ components:
'@id': 'odrl:eq'
'odrl:rightOperand': ID 3.1 Trace
validUntil: '2025-12-12T23:59:59.999Z'
properties:
empty:
type: boolean
valueType:
type: string
enum:
- 'ARRAY'
- 'OBJECT'
- 'STRING'
- 'NUMBER'
- 'TRUE'
- 'FALSE'
- 'NULL'
validUntil:
type: string
format: date-time
description: Timestamp after which the policy will no longer be accepted in negotiations
businessPartnerNumbers:
type: array
items:
type: string
required:
- payload
- validUntil
Expand Down Expand Up @@ -2099,6 +2128,41 @@ components:
items:
$ref: '#/components/schemas/Tombstone'
maxItems: 2147483647
JsonObject:
type: object
additionalProperties: false
properties:
valueType:
type: string
enum:
- 'ARRAY'
- 'OBJECT'
- 'STRING'
- 'NUMBER'
- 'TRUE'
- 'FALSE'
- 'NULL'
empty:
type: boolean
example:
payload:
'@context':
odrl: http://www.w3.org/ns/odrl/2/
'@id': policy-id
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
validUntil: '2025-12-12T23:59:59.999Z'
JsonValue:
type: object
additionalProperties: false
Expand Down Expand Up @@ -2744,6 +2808,14 @@ components:
additionalProperties: false
description: Request to add a policy
properties:
businessPartnerNumbers:
type: array
items:
type: string
policiesIds:
type: array
items:
type: string
validUntil:
type: string
format: date-time
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,22 +98,22 @@ protected SubmodelDescriptor requestSubmodel(final EdcSubmodelFacade submodelFac
log.debug("Using dspEndpoint of subprotocolBody '{}' to get submodel payload", subprotocolBody);
return submodelFacade.getSubmodelPayload(dspEndpoint.get(),
digitalTwinRegistryEndpoint.getProtocolInformation().getHref(),
extractAssetId(subprotocolBody));
extractAssetId(subprotocolBody), bpn);
} else {
log.info("SubprotocolBody does not contain '{}'. Using Discovery Service as fallback.", DSP_ENDPOINT);
final List<String> connectorEndpoints = connectorEndpointsService.fetchConnectorEndpoints(bpn);

return getSubmodel(submodelFacade, digitalTwinRegistryEndpoint, connectorEndpoints);
return getSubmodel(submodelFacade, digitalTwinRegistryEndpoint, connectorEndpoints, bpn);
}
}

private SubmodelDescriptor getSubmodel(final EdcSubmodelFacade submodelFacade, final Endpoint digitalTwinRegistryEndpoint,
final List<String> connectorEndpoints) throws EdcClientException {
final List<String> connectorEndpoints, final String bpn) throws EdcClientException {
for (final String connectorEndpoint : connectorEndpoints) {
try {
return submodelFacade.getSubmodelPayload(connectorEndpoint,
digitalTwinRegistryEndpoint.getProtocolInformation().getHref(),
extractAssetId(digitalTwinRegistryEndpoint.getProtocolInformation().getSubprotocolBody()));
extractAssetId(digitalTwinRegistryEndpoint.getProtocolInformation().getSubprotocolBody()), bpn);
} catch (EdcClientException e) {
log.info("EdcClientException while accessing digitalTwinRegistryEndpoint '{}'", connectorEndpoint, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public DecentralDigitalTwinRegistryService decentralDigitalTwinRegistryService(
return new DecentralDigitalTwinRegistryService(connectorEndpointsService,
new EndpointDataForConnectorsService((edcConnectorEndpoint, assetType, assetValue) -> {
try {
return facade.getEndpointReferenceForAsset(edcConnectorEndpoint, assetType, assetValue);
return facade.getEndpointReferenceForAsset(edcConnectorEndpoint, assetType, assetValue, null);
} catch (EdcClientException e) {
throw new EdcRetrieverException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public void receiveNotification(
final EdcNotification<NotificationContent> edcRequest = edcRequest(notificationId, originalNotificationId,
senderEdc, senderBpn, recipientBpn, notificationContent);

final var response = edcSubmodelFacade.sendNotification(recipientUrl, "ess-response-asset", edcRequest);
final var response = edcSubmodelFacade.sendNotification(recipientUrl, "ess-response-asset", edcRequest, recipientBpn);
if (!response.deliveredSuccessfully()) {
throw new EdcClientException(
"EDC Provider did not accept message with notificationId " + notificationId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void sendEdcNotification(final EdcNotification<InvestigationNotificationC
originalNotificationId, essLocalEdcEndpoint, localBpn, recipientBpn, notificationContent);

final var response = edcSubmodelFacade.sendNotification(connectorEndpoint, "ess-response-asset",
responseNotification);
responseNotification, bpn);
if (!response.deliveredSuccessfully()) {
throw new EdcClientException(
"EDC Provider did not accept message with notificationId " + notificationId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,10 @@ private String sendEdcNotification(final String bpn, final String url, final Lis
final EdcNotificationResponse response;
if (isRecursiveMockAsset || isNotMockAsset) {
log.debug("Sending recursive notification");
response = edcSubmodelFacade.sendNotification(url, "notify-request-asset-recursive", notification);
response = edcSubmodelFacade.sendNotification(url, "notify-request-asset-recursive", notification, bpn);
} else {
log.debug("Sending mock recursive notification");
response = edcSubmodelFacade.sendNotification(url, "notify-request-asset", notification);
response = edcSubmodelFacade.sendNotification(url, "notify-request-asset", notification, bpn);
}
if (response.deliveredSuccessfully()) {
log.info("Successfully sent notification with id '{}' to EDC endpoint '{}'.", notificationId, url);
Expand Down
4 changes: 1 addition & 3 deletions irs-api/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,4 @@ ess:
url: "${IRS_URL:}" # IRS Url to connect with
discovery:
mockEdcResult: { } # Mocked BPN Investigation results
mockRecursiveEdcAsset: # Mocked BPN Recursive Investigation results

apiAllowedBpn: ${API_ALLOWED_BPN:BPNL00000001CRHK} # BPN value that is allowed to access IRS API
mockRecursiveEdcAsset: # Mocked BPN Recursive Investigation results
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public Optional<byte[]> getBlob(final String sourceBlobName) {
return Optional.ofNullable(store.get(sourceBlobName));
}

@Override
public Map<String, byte[]> getAllBlobs() {
return store;
}

@Override
public Collection<byte[]> findBlobByPrefix(final String prefix) {
return store.entrySet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void setUp() {
@Test
void shouldUseDspEndpointIfPresent() throws EdcClientException {
// Arrange
when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenReturn(new SubmodelDescriptor("cid", "test"));
when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenReturn(new SubmodelDescriptor("cid", "test"));
final Endpoint endpoint = Endpoint.builder()
.protocolInformation(ProtocolInformation.builder()
.href("http://dataplane.test/123")
Expand All @@ -77,17 +77,17 @@ void shouldUseDspEndpointIfPresent() throws EdcClientException {

// Assert
assertThat(submodel).isEqualTo("test");
verify(submodelFacade, times(1)).getSubmodelPayload("http://edc.test", "http://dataplane.test/123", "123");
verify(submodelFacade, times(1)).getSubmodelPayload("http://edc.test", "http://dataplane.test/123", "123", "BPN123");
}

@Test
void shouldUseDiscoveryFinderIfDspEndpointNotPresent() throws EdcClientException {
// Arrange
final String connector1 = "http://edc.test1";
final String connector2 = "http://edc.test2";
when(submodelFacade.getSubmodelPayload(eq(connector1), any(), any())).thenThrow(
when(submodelFacade.getSubmodelPayload(eq(connector1), any(), any(), any())).thenThrow(
new EdcClientException("test"));
when(submodelFacade.getSubmodelPayload(eq(connector2), any(), any())).thenReturn(new SubmodelDescriptor("cid", "test"));
when(submodelFacade.getSubmodelPayload(eq(connector2), any(), any(), any())).thenReturn(new SubmodelDescriptor("cid", "test"));
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of(connector1, connector2));
final String dataplaneUrl = "http://dataplane.test/123";
final Endpoint endpoint = Endpoint.builder()
Expand All @@ -104,8 +104,8 @@ void shouldUseDiscoveryFinderIfDspEndpointNotPresent() throws EdcClientException

// Assert
assertThat(submodel).isEqualTo("test");
verify(submodelFacade, times(1)).getSubmodelPayload(connector1, dataplaneUrl, "123");
verify(submodelFacade, times(1)).getSubmodelPayload(connector2, dataplaneUrl, "123");
verify(submodelFacade, times(1)).getSubmodelPayload(connector1, dataplaneUrl, "123", "BPN123");
verify(submodelFacade, times(1)).getSubmodelPayload(connector2, dataplaneUrl, "123", "BPN123");
verify(connectorEndpointsService, times(1)).fetchConnectorEndpoints(bpn);
}

Expand All @@ -114,7 +114,7 @@ void shouldThrowGenericEdcClientExceptionIfAllEndpointsThrowExceptions() throws
// Arrange
final String connector1 = "http://edc.test1";
final String connector2 = "http://edc.test2";
when(submodelFacade.getSubmodelPayload(any(), any(), any())).thenThrow(new EdcClientException("test"));
when(submodelFacade.getSubmodelPayload(any(), any(), any(), any())).thenThrow(new EdcClientException("test"));
when(connectorEndpointsService.fetchConnectorEndpoints(any())).thenReturn(List.of(connector1, connector2));
final String dataplaneUrl = "http://dataplane.test/123";
final Endpoint endpoint = Endpoint.builder()
Expand All @@ -131,8 +131,8 @@ void shouldThrowGenericEdcClientExceptionIfAllEndpointsThrowExceptions() throws
bpn));

// Assert
verify(submodelFacade, times(1)).getSubmodelPayload(connector1, dataplaneUrl, "123");
verify(submodelFacade, times(1)).getSubmodelPayload(connector2, dataplaneUrl, "123");
verify(submodelFacade, times(1)).getSubmodelPayload(connector1, dataplaneUrl, "123", "BPN123");
verify(submodelFacade, times(1)).getSubmodelPayload(connector2, dataplaneUrl, "123", "BPN123");
verify(connectorEndpointsService, times(1)).fetchConnectorEndpoints(bpn);
}
}
Loading

0 comments on commit 8028ac4

Please sign in to comment.