Skip to content

Commit

Permalink
Merge pull request #647 from eclipse-tractusx/feature/#616-Outdated-t…
Browse files Browse the repository at this point in the history
…ype-signal-in-catalog-for-AAS-Resources

feat(registry):[#616] Add new filter type for digital twin registry c…
  • Loading branch information
ds-jhartmann authored May 17, 2024
2 parents e4aded1 + 446ec3f commit 5354f73
Show file tree
Hide file tree
Showing 50 changed files with 384 additions and 134 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ _**For better traceability add the corresponding GitHub issue number in each cha

## [Unreleased]

### Fixed

- IRS now searches for Digital Twin Registry contract offers by
type `dct:type`: `https://w3id.org/catenax/taxonomy#DigitalTwinRegistry`
or `edc:type`: `data.core.digitalTwinRegistry`. #616
- Fix missing and malformed properties for EDC policy transformation. #648


## [5.1.2] - 2024-05-13

### Fixed
Expand Down
6 changes: 3 additions & 3 deletions docs/src/api/irs-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ paths:
createdOn: 2024-03-28T03:34:42.9454448Z
validUntil: 2025-12-12T23:59:59.999Z
permissions:
- action: USE
- action: use
constraint:
and:
- leftOperand: Membership
Expand Down Expand Up @@ -1807,7 +1807,7 @@ components:
policy:
'@type': Policy
odrl:permission:
- odrl:action: USE
- odrl:action: use
odrl:constraint:
odrl:and:
- odrl:leftOperand: Membership
Expand Down Expand Up @@ -2200,7 +2200,7 @@ components:
policy:
'@type': Policy
odrl:permission:
- odrl:action: USE
- odrl:action: use
odrl:constraint:
odrl:and:
- odrl:leftOperand: Membership
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ public DecentralDigitalTwinRegistryService decentralDigitalTwinRegistryService(
@Value("${digitalTwinRegistry.lookupShellsTemplate:}") final String lookupShellsTemplate,
final EdcConfiguration edcConfiguration) {

final EdcEndpointReferenceRetriever endpointReferenceRetriever = (edcConnectorEndpoint, assetType, assetValue, bpn) -> {
final EdcEndpointReferenceRetriever endpointReferenceRetriever = (edcConnectorEndpoint, bpn) -> {
try {
return facade.getEndpointReferencesForAsset(edcConnectorEndpoint, assetType, assetValue, bpn);
return facade.getEndpointReferencesForRegistryAsset(edcConnectorEndpoint, bpn);
} catch (EdcClientException e) {
throw new EdcRetrieverException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private void registerPolicy(final String policyId) {
"policy": {
"odrl:permission": [
{
"odrl:action": "USE",
"odrl:action": "use",
"odrl:constraint": {
"@type": "AtomicConstraint",
"odrl:or": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"policy": {
"odrl:permission": [
{
"odrl:action": "USE",
"odrl:action": "use",
"odrl:constraint": {
"odrl:and": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
/**
* Public API facade for EDC domain
*/
@SuppressWarnings({"PMD.ExcessiveImports", "PMD.UseObjectForClearerAPI"})
@SuppressWarnings({ "PMD.ExcessiveImports",
"PMD.UseObjectForClearerAPI"
})
public interface EdcSubmodelClient {

CompletableFuture<SubmodelDescriptor> getSubmodelPayload(String connectorEndpoint, String submodelDataplaneUrl,
Expand All @@ -52,5 +54,8 @@ List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForAsset(Str
List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForAsset(String endpointAddress,
String filterKey, String filterValue, EndpointDataReferenceStatus cachedEndpointDataReference, String bpn)
throws EdcClientException;

List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForRegistryAsset(String endpointAddress,
String bpn) throws EdcClientException;
}

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import static org.eclipse.tractusx.irs.edc.client.configuration.JsonLdConfiguration.NAMESPACE_EDC_ID;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
Expand All @@ -52,6 +53,7 @@
import org.eclipse.tractusx.irs.edc.client.model.notification.EdcNotificationResponse;
import org.eclipse.tractusx.irs.edc.client.model.notification.NotificationContent;
import org.eclipse.tractusx.irs.edc.client.util.Masker;
import org.jetbrains.annotations.NotNull;
import org.springframework.util.StopWatch;

/**
Expand All @@ -65,6 +67,11 @@
})
public class EdcSubmodelClientImpl implements EdcSubmodelClient {

private static final String DT_DCAT_TYPE_ID = "'http://purl.org/dc/terms/type'.'@id'";
private static final String DT_TAXONOMY_REGISTRY = "https://w3id.org/catenax/taxonomy#DigitalTwinRegistry";
private static final String DT_EDC_TYPE = "https://w3id.org/edc/v0.0.1/ns/type";
private static final String DT_DATA_CORE_REGISTRY = "data.core.digitalTwinRegistry";

private final EdcConfiguration config;
private final ContractNegotiationService contractNegotiationService;
private final EdcDataPlaneClient edcDataPlaneClient;
Expand Down Expand Up @@ -99,8 +106,7 @@ private Optional<SubmodelDescriptor> retrieveSubmodelData(final String submodelD
final String payload = edcDataPlaneClient.getData(endpointDataReference, submodelDataplaneUrl);
stopWatchOnEdcTask(stopWatch);

return Optional.of(
new SubmodelDescriptor(endpointDataReference.getContractId(), payload));
return Optional.of(new SubmodelDescriptor(endpointDataReference.getContractId(), payload));
}

return Optional.empty();
Expand Down Expand Up @@ -234,11 +240,17 @@ public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForAs
endpointAddress, filterKey, filterValue));
}

// We need to process each contract offer in parallel
// (see src/docs/arc42/cross-cutting/discovery-DTR--multiple-EDCs-with-multiple-DTRs.puml
// and src/docs/arc42/cross-cutting/discovery-DTR--multiple-EDCs-with-multiple-DTRs--detailed.puml)
return contractOffers.stream().map(contractOffer -> {
return createCompletableFuturesForContractOffers(endpointDataReferenceStatus, bpn, contractOffers,
providerWithSuffix, stopWatch);
}

// We need to process each contract offer in parallel
// (see src/docs/arc42/cross-cutting/discovery-DTR--multiple-EDCs-with-multiple-DTRs.puml
// and src/docs/arc42/cross-cutting/discovery-DTR--multiple-EDCs-with-multiple-DTRs--detailed.puml)
private @NotNull List<CompletableFuture<EndpointDataReference>> createCompletableFuturesForContractOffers(
final EndpointDataReferenceStatus endpointDataReferenceStatus, final String bpn,
final List<CatalogItem> contractOffers, final String providerWithSuffix, final StopWatch stopWatch) {
return contractOffers.stream().map(contractOffer -> {
final NegotiationResponse negotiationResponse;
try {
negotiationResponse = negotiateContract(endpointDataReferenceStatus, contractOffer, providerWithSuffix,
Expand All @@ -262,6 +274,41 @@ public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForAs
}).toList();
}

@Override
public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForRegistryAsset(
final String endpointAddress, final String bpn) throws EdcClientException {
return execute(endpointAddress, () -> getEndpointReferencesForRegistryAsset(endpointAddress,
new EndpointDataReferenceStatus(null, TokenStatus.REQUIRED_NEW), bpn));
}

public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForRegistryAsset(
final String endpointAddress, final EndpointDataReferenceStatus endpointDataReferenceStatus,
final String bpn) throws EdcClientException {
final StopWatch stopWatch = new StopWatch();
stopWatch.start("Get EndpointDataReference task for shell descriptor, endpoint " + endpointAddress);
final String providerWithSuffix = appendSuffix(endpointAddress, config.getControlplane().getProviderSuffix());

// CatalogItem = contract offer
final List<CatalogItem> contractOffers = new ArrayList<>(
catalogFacade.fetchCatalogByFilter(providerWithSuffix, DT_DCAT_TYPE_ID, DT_TAXONOMY_REGISTRY, bpn));

if (contractOffers.isEmpty()) {
final List<CatalogItem> contractOffersDataCore = catalogFacade.fetchCatalogByFilter(providerWithSuffix,
DT_EDC_TYPE, DT_DATA_CORE_REGISTRY, bpn);
contractOffers.addAll(contractOffersDataCore);
}

if (contractOffers.isEmpty()) {
throw new EdcClientException(
"No DigitalTwinRegistry contract offers found for endpointAddress '%s' filterKey '%s', filterValue '%s' or filterKey '%s', filterValue '%s'".formatted(
endpointAddress, DT_DCAT_TYPE_ID, DT_TAXONOMY_REGISTRY, DT_EDC_TYPE,
DT_DATA_CORE_REGISTRY));
}

return createCompletableFuturesForContractOffers(endpointDataReferenceStatus, bpn, contractOffers,
providerWithSuffix, stopWatch);
}

private NegotiationResponse negotiateContract(final EndpointDataReferenceStatus endpointDataReferenceStatus,
final CatalogItem catalogItem, final String providerWithSuffix, final String bpn)
throws EdcClientException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
@SuppressWarnings("PMD.UseObjectForClearerAPI")
public class EdcSubmodelClientLocalStub implements EdcSubmodelClient {

public static final String NOT_IMPLEMENTED = "Not implemented";
private final SubmodelTestdataCreator testdataCreator;

/* package */
Expand Down Expand Up @@ -73,12 +74,18 @@ public CompletableFuture<EdcNotificationResponse> sendNotification(final String
public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForAsset(final String endpointAddress,
final String filterKey, final String filterValue,
final EndpointDataReferenceStatus cachedEndpointDataReference, final String bpn) throws EdcClientException {
throw new EdcClientException("Not implemented");
throw new EdcClientException(NOT_IMPLEMENTED);
}

@Override
public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForAsset(final String endpointAddress,
final String filterKey, final String filterValue, final String bpn) throws EdcClientException {
throw new EdcClientException("Not implemented");
throw new EdcClientException(NOT_IMPLEMENTED);
}

@Override
public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForRegistryAsset(
final String endpointAddress, final String bpn) throws EdcClientException {
throw new EdcClientException(NOT_IMPLEMENTED);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
*/
@Slf4j
@RequiredArgsConstructor
@SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.UseObjectForClearerAPI"})
@SuppressWarnings({ "PMD.AvoidDuplicateLiterals",
"PMD.UseObjectForClearerAPI"
})
public class EdcSubmodelFacade {

private final EdcSubmodelClient client;
Expand Down Expand Up @@ -93,9 +95,9 @@ public EdcNotificationResponse sendNotification(final String submodelEndpointAdd
}
}

public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForAsset(final String endpointAddress,
final String filterKey, final String filterValue, final String bpn) throws EdcClientException {
return client.getEndpointReferencesForAsset(endpointAddress, filterKey, filterValue, bpn);
public List<CompletableFuture<EndpointDataReference>> getEndpointReferencesForRegistryAsset(
final String endpointAddress, final String bpn) throws EdcClientException {
return client.getEndpointReferencesForRegistryAsset(endpointAddress, bpn);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,15 @@ public class EdcAssetService {
private static final String ASSET_CREATION_PROPERTY_DESCRIPTION = "https://w3id.org/edc/v0.0.1/ns/description";
private static final String ASSET_CREATION_PROPERTY_CONTENT_TYPE = "https://w3id.org/edc/v0.0.1/ns/contenttype";
private static final String ASSET_CREATION_PROPERTY_POLICY_ID = "https://w3id.org/edc/v0.0.1/ns/policy-id";
private static final String ASSET_CREATION_PROPERTY_TYPE = "https://w3id.org/edc/v0.0.1/ns/type";
private static final String ASSET_CREATION_PROPERTY_EDC_TYPE = "https://w3id.org/edc/v0.0.1/ns/type";
private static final String ASSET_CREATION_PROPERTY_DATA_CORE_REGISTRY = "data.core.digitalTwinRegistry";
private static final String ASSET_CREATION_PROPERTY_DCAT_TYPE = "http://purl.org/dc/terms/type";
private static final String ASSET_CREATION_PROPERTY_DCAT_REGISTRY = "https://w3id.org/catenax/taxonomy#DigitalTwinRegistry";
private static final String ASSET_CREATION_PROPERTY_COMMON_VERSION_KEY = "https://w3id.org/catenax/ontology/common#version";
private static final String ASSET_CREATION_PROPERTY_COMMON_VERSION_VALUE = "3.0";
private static final String ASSET_CREATION_PROPERTY_NOTIFICATION_TYPE = "https://w3id.org/edc/v0.0.1/ns/notificationtype";
private static final String ASSET_CREATION_PROPERTY_NOTIFICATION_METHOD = "https://w3id.org/edc/v0.0.1/ns/notificationmethod";

public static final String DATA_ADDRESS_TYPE_HTTP_DATA = "HttpData";

private final EdcTransformer edcTransformer;
Expand Down Expand Up @@ -128,7 +134,7 @@ private Asset createNotificationAssetRequest(final String assetName, final Strin
final String assetId = UUID.randomUUID().toString();
final Map<String, Object> properties = Map.of(ASSET_CREATION_PROPERTY_DESCRIPTION, assetName,
ASSET_CREATION_PROPERTY_CONTENT_TYPE, DEFAULT_CONTENT_TYPE, ASSET_CREATION_PROPERTY_POLICY_ID,
DEFAULT_POLICY_ID, ASSET_CREATION_PROPERTY_TYPE, notificationType.getValue(),
DEFAULT_POLICY_ID, ASSET_CREATION_PROPERTY_EDC_TYPE, notificationType.getValue(),
ASSET_CREATION_PROPERTY_NOTIFICATION_TYPE, notificationType.getValue(),
ASSET_CREATION_PROPERTY_NOTIFICATION_METHOD, notificationMethod.getValue());

Expand All @@ -153,7 +159,10 @@ private Asset createNotificationAssetRequest(final String assetName, final Strin

private Asset createDtrAssetRequest(final String assetId, final String baseUrl) {
final Map<String, Object> properties = Map.of(ASSET_CREATION_PROPERTY_DESCRIPTION,
"Digital Twin Registry Asset", ASSET_CREATION_PROPERTY_TYPE, "data.core.digitalTwinRegistry");
"Digital Twin Registry Asset", ASSET_CREATION_PROPERTY_EDC_TYPE,
ASSET_CREATION_PROPERTY_DATA_CORE_REGISTRY, ASSET_CREATION_PROPERTY_COMMON_VERSION_KEY,
ASSET_CREATION_PROPERTY_COMMON_VERSION_VALUE, ASSET_CREATION_PROPERTY_DCAT_TYPE,
Map.of("@id", ASSET_CREATION_PROPERTY_DCAT_REGISTRY));

final DataAddress dataAddress = DataAddress.Builder.newInstance()
.type("DataAddress")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ public class JsonLdConfiguration {
public static final String NAMESPACE_EDC_PARTICIPANT_ID = NAMESPACE_EDC + "participantId";
public static final String NAMESPACE_EDC_ID = NAMESPACE_EDC + "id";
public static final String NAMESPACE_TRACTUSX = "https://w3id.org/tractusx/v0.0.1/ns/";
public static final String NAMESPACE_DCT = "https://purl.org/dc/terms/";
public static final String NAMESPACE_DCT = "http://purl.org/dc/terms/";
public static final String JSON_LD_OBJECT_MAPPER = "jsonLdObjectMapper";
public static final String NAMESPACE_CATENAX_POLICY = "https://w3id.org/catenax/policy/";

@Bean /* package */ TitaniumJsonLd titaniumJsonLd(final Monitor monitor) {
final TitaniumJsonLd titaniumJsonLd = new TitaniumJsonLd(monitor);
Expand All @@ -62,6 +63,7 @@ public class JsonLdConfiguration {
titaniumJsonLd.registerNamespace("edc", NAMESPACE_EDC);
titaniumJsonLd.registerNamespace("dcat", JsonLdConfiguration.NAMESPACE_DCAT);
titaniumJsonLd.registerNamespace("dspace", NAMESPACE_DSPACE);
titaniumJsonLd.registerNamespace("cx-policy", NAMESPACE_CATENAX_POLICY);
return titaniumJsonLd;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class Permission {

@Schema(implementation = PolicyType.class, example = "USE")
@Schema(implementation = PolicyType.class, example = "use")
@JsonAlias({"odrl:action"})
private PolicyType action;
@Schema
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,19 @@
********************************************************************************/
package org.eclipse.tractusx.irs.edc.client.policy;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import com.fasterxml.jackson.annotation.JsonValue;

/**
* A PolicyType object use in Permission
*/
@Getter
@RequiredArgsConstructor
public enum PolicyType {
ACCESS("access"),
USE("use");

ACCESS, USE

@JsonValue
private final String value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.eclipse.tractusx.irs.edc.client.EdcConfiguration;
import org.eclipse.tractusx.irs.edc.client.asset.model.OdrlContext;
import org.eclipse.tractusx.irs.edc.client.contract.model.EdcOperator;
import org.eclipse.tractusx.irs.edc.client.policy.PolicyType;
import org.eclipse.tractusx.irs.edc.client.policy.model.EdcCreatePolicyDefinitionRequest;
import org.eclipse.tractusx.irs.edc.client.policy.model.EdcPolicy;
import org.eclipse.tractusx.irs.edc.client.policy.model.EdcPolicyPermission;
Expand All @@ -54,12 +55,12 @@
@RequiredArgsConstructor
public class EdcPolicyDefinitionService {

private static final String USE_ACTION = "USE";
private static final String POLICY_TYPE = "Policy";
private static final String POLICY_DEFINITION_TYPE = "PolicyDefinitionRequestDto";
private static final String ATOMIC_CONSTRAINT = "AtomicConstraint";
private static final String CONSTRAINT = "Constraint";
private static final String OPERATOR_PREFIX = "odrl:";
private static final String USE_ACTION = PolicyType.USE.getValue();

private final EdcConfiguration config;
private final RestTemplate restTemplate;
Expand Down
Loading

0 comments on commit 5354f73

Please sign in to comment.