Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/publish-context.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ on:
push:
branches: [ main ]
paths:
- 'extensions/common/json-ld/src/main/resources/document/**'
- 'core/common/lib/json-ld-lib/src/main/resources/document/**'
- 'extensions/common/api/management-api-schema-validator/src/main/resources/schema/management/**'

jobs:
Expand All @@ -40,14 +40,14 @@ jobs:
- name: copy contexts into public folder
run: |
mkdir -p public/context
cp extensions/common/json-ld/src/main/resources/document/management-context-v1.jsonld public/context/
cp extensions/common/json-ld/src/main/resources/document/management-context-v2.jsonld public/context/
cp extensions/common/json-ld/src/main/resources/document/dspace-edc-context-v1.jsonld public/context/
cp core/common/lib/json-ld-lib/src/main/resources/document/management-context-v1.jsonld public/context/
cp core/common/lib/json-ld-lib/src/main/resources/document/management-context-v2.jsonld public/context/
cp core/common/lib/json-ld-lib/src/main/resources/document/dspace-edc-context-v1.jsonld public/context/
mkdir -p public/schema
cp -r extensions/common/api/management-api-schema-validator/src/main/resources/schema/management public/schema/
- name: deploy to gh-pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
keep_files: true
keep_files: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2025 Think-it GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Think-it GmbH - initial API and implementation
*
*/

package org.eclipse.edc.jsonld;

import org.eclipse.edc.jsonld.spi.JsonLdContext;
import org.eclipse.edc.spi.result.Result;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.stream.Stream;

import static java.lang.String.format;
import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_CONTEXT_2025_1;
import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_ODRL_PROFILE_2025_1;
import static org.eclipse.edc.jsonld.spi.Namespaces.EDC_DSPACE_CONTEXT;
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT;
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT_V2;

/**
* Manages the hardcoded json-ld documents cached
*/
public class CachedDocumentRegistry {

/**
* Get the cached documents
*
* @return the cached documents
*/
public static Stream<Result<JsonLdContext>> getDocuments() {
return Map.of(
"odrl.jsonld", "http://www.w3.org/ns/odrl.jsonld",
"dspace.jsonld", "https://w3id.org/dspace/2024/1/context.json",
"management-context-v1.jsonld", EDC_CONNECTOR_MANAGEMENT_CONTEXT,
"management-context-v2.jsonld", EDC_CONNECTOR_MANAGEMENT_CONTEXT_V2,
"dspace-edc-context-v1.jsonld", EDC_DSPACE_CONTEXT,
"dspace-v2025-1.jsonld", DSPACE_CONTEXT_2025_1,
"dspace-v2025-1-odrl.jsonld", DSPACE_ODRL_PROFILE_2025_1
).entrySet().stream()
.map(entry -> getResourceUri("document/" + entry.getKey())
.map(uri -> new JsonLdContext(uri, entry.getValue())));
}

static Result<URI> getResourceUri(String name) {
var uri = CachedDocumentRegistry.class.getClassLoader().getResource(name);
if (uri == null) {
return Result.failure(format("Cannot find resource %s", name));
}

try {
return Result.success(uri.toURI());
} catch (URISyntaxException e) {
return Result.failure(format("Cannot read resource %s: %s", name, e.getMessage()));
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2025 Think-it GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Think-it GmbH - initial API and implementation
*
*/

package org.eclipse.edc.jsonld;

import org.eclipse.edc.spi.result.Result;
import org.junit.jupiter.api.Test;

import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat;

class CachedDocumentRegistryTest {

@Test
void shouldGetCachedDocuments() {
var contexts = CachedDocumentRegistry.getDocuments().collect(Result.collector());

assertThat(contexts).isSucceeded();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ public void initialize(ServiceExtensionContext context) {
registerNamespaces();
registerTransformers();

dataspaceProfileContextRegistry.registerDefault(new DataspaceProfileContext(DATASPACE_PROTOCOL_HTTP_V_2025_1, V_2025_1, () -> dspWebhookAddress.get() + V_2025_1_PATH, participantIdExtractionFunction));
var profileContext = new DataspaceProfileContext(DATASPACE_PROTOCOL_HTTP_V_2025_1, V_2025_1, () -> dspWebhookAddress.get() + V_2025_1_PATH, participantIdExtractionFunction);
dataspaceProfileContextRegistry.registerDefault(profileContext);
}

private void registerNamespaces() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ public DspRequestBasePathProviderImpl(DataspaceProfileContextRegistry dataspaceP

@Override
public String provideBasePath(RemoteMessage message) {
var protocolPath = "";
if (wellKnownPath) {
protocolPath = Optional.ofNullable(dataspaceProfileContextRegistry.getProtocolVersion(message.getProtocol()))
.map(ProtocolVersion::path)
.map(this::removeTrailingSlash)
.orElseThrow(() -> new EdcException(format("No protocol version found for protocol: %s", message.getProtocol())));
if (!wellKnownPath) {
return message.getCounterPartyAddress();
}

var protocolPath = Optional.ofNullable(dataspaceProfileContextRegistry.getProtocolVersion(message.getProtocol()))
.map(ProtocolVersion::path)
.map(this::removeTrailingSlash)
.orElseThrow(() -> new EdcException(format("No protocol version found for protocol: %s", message.getProtocol())));

return message.getCounterPartyAddress() + protocolPath;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,8 @@
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.stream.Stream;

import static java.lang.String.format;
import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_CONTEXT_2025_1;
import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_ODRL_PROFILE_2025_1;
import static org.eclipse.edc.jsonld.spi.Namespaces.EDC_DSPACE_CONTEXT;
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT;
import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT_V2;
import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD;

/**
Expand Down Expand Up @@ -95,16 +89,8 @@ public JsonLd createJsonLdService(ServiceExtensionContext context) {
var monitor = context.getMonitor();
var service = new TitaniumJsonLd(monitor, configuration);

Stream.of(
new JsonLdContext("odrl.jsonld", "http://www.w3.org/ns/odrl.jsonld"),
new JsonLdContext("dspace.jsonld", "https://w3id.org/dspace/2024/1/context.json"),
new JsonLdContext("management-context-v1.jsonld", EDC_CONNECTOR_MANAGEMENT_CONTEXT),
new JsonLdContext("management-context-v2.jsonld", EDC_CONNECTOR_MANAGEMENT_CONTEXT_V2),
new JsonLdContext("dspace-edc-context-v1.jsonld", EDC_DSPACE_CONTEXT),
new JsonLdContext("dspace-v2025-1.jsonld", DSPACE_CONTEXT_2025_1),
new JsonLdContext("dspace-v2025-1-odrl.jsonld", DSPACE_ODRL_PROFILE_2025_1)
).forEach(jsonLdContext -> getResourceUri("document/" + jsonLdContext.fileName())
.onSuccess(uri -> service.registerCachedDocument(jsonLdContext.url(), uri))
CachedDocumentRegistry.getDocuments().forEach(result -> result
.onSuccess(c -> service.registerCachedDocument(c.url(), c.resource()))
.onFailure(failure -> monitor.warning("Failed to register cached json-ld document: " + failure.getFailureDetail()))
);

Expand Down Expand Up @@ -141,7 +127,4 @@ private Result<URI> getResourceUri(String name) {
}
}

record JsonLdContext(String fileName, String url) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition;
import org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition;
import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates;
import org.eclipse.edc.jsonld.CachedDocumentRegistry;
import org.eclipse.edc.jsonld.TitaniumJsonLd;
import org.eclipse.edc.jsonld.spi.JsonLd;
import org.eclipse.edc.jsonld.util.JacksonJsonLd;
Expand Down Expand Up @@ -69,12 +70,11 @@ public class Participant {
protected String name;
protected LazySupplier<URI> controlPlaneManagement = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/management"));
protected LazySupplier<URI> controlPlaneProtocol = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/protocol"));
protected String protocolVersionPath = "";
protected UnaryOperator<RequestSpecification> enrichManagementRequest = r -> r;
protected JsonLd jsonLd;
protected ObjectMapper objectMapper;
protected Duration timeout = Duration.ofSeconds(30);
protected String protocol = "dataspace-protocol-http";
protected Protocol protocol = new Protocol("dataspace-protocol-http:2025-1", "/2025-1");
protected String managementVersionBasePath = MANAGEMENT_V3;

protected Participant() {
Expand All @@ -88,23 +88,10 @@ public Duration getTimeout() {
return timeout;
}

public String getProtocol() {
public Protocol getProtocol() {
return protocol;
}

public void setProtocol(String protocol) {
setProtocol(protocol, "");
}

public void setProtocol(String protocol, String path) {
this.protocol = protocol;
this.protocolVersionPath = path;
}

public String getProtocolVersionPath() {
return protocolVersionPath;
}

public String getId() {
return id;
}
Expand All @@ -113,17 +100,13 @@ public JsonLd getJsonLd() {
return jsonLd;
}

public void setJsonLd(JsonLd jsonLd) {
this.jsonLd = jsonLd;
}

/**
* Get the protocol URL of the participant which is the protocol base path + protocol version path (empty by default).
*
* @return protocol URL
*/
public String getProtocolUrl() {
return controlPlaneProtocol.get() + protocolVersionPath;
return controlPlaneProtocol.get() + protocol.versionPath();
}

public String createAsset(JsonObject requestBody) {
Expand Down Expand Up @@ -252,7 +235,7 @@ public JsonArray getCatalogDatasets(Participant provider, JsonObject querySpec)
.add(TYPE, "CatalogRequest")
.add("counterPartyId", provider.id)
.add("counterPartyAddress", provider.getProtocolUrl())
.add("protocol", protocol);
.add("protocol", protocol.name());

if (querySpec != null) {
requestBodyBuilder.add("querySpec", querySpec);
Expand Down Expand Up @@ -296,7 +279,7 @@ public JsonObject getDatasetForAsset(Participant provider, String assetId) {
.add(ID, assetId)
.add("counterPartyId", provider.id)
.add("counterPartyAddress", provider.getProtocolUrl())
.add("protocol", protocol)
.add("protocol", protocol.name())
.build();

var response = baseManagementRequest()
Expand Down Expand Up @@ -345,7 +328,7 @@ public String initContractNegotiation(Participant provider, JsonObject policy) {
.add(CONTEXT, createObjectBuilder().add(VOCAB, EDC_NAMESPACE))
.add(TYPE, "ContractRequest")
.add("counterPartyAddress", provider.getProtocolUrl())
.add("protocol", protocol)
.add("protocol", protocol.name())
.add("policy", jsonLd.compact(policy).getContent())
.build();

Expand Down Expand Up @@ -408,7 +391,7 @@ public String initiateTransfer(Participant provider, String contractAgreementId,
var requestBodyBuilder = createObjectBuilder()
.add(CONTEXT, createObjectBuilder().add(VOCAB, EDC_NAMESPACE))
.add(TYPE, "TransferRequest")
.add("protocol", protocol)
.add("protocol", protocol.name())
.add("contractId", contractAgreementId)
.add("connectorId", provider.id)
.add("counterPartyAddress", provider.getProtocolUrl());
Expand Down Expand Up @@ -624,11 +607,6 @@ public B name(String name) {
return self();
}

public B protocol(String protocol) {
participant.protocol = protocol;
return self();
}

public B timeout(Duration timeout) {
participant.timeout = timeout;
return self();
Expand All @@ -649,12 +627,20 @@ public B managementVersionBasePath(String managementVersionBasePath) {
return self();
}

public B protocol(String name, String versionPath) {
participant.protocol = new Protocol(name, versionPath);
return self();
}

public P build() {
Objects.requireNonNull(participant.id, "id");
Objects.requireNonNull(participant.name, "name");

if (participant.jsonLd == null) {
participant.jsonLd = new TitaniumJsonLd(new ConsoleMonitor());
CachedDocumentRegistry.getDocuments().forEach(result -> result
.onSuccess(c -> participant.jsonLd.registerCachedDocument(c.url(), c.resource()))
);
}
if (participant.objectMapper == null) {
participant.objectMapper = JacksonJsonLd.createObjectMapper();
Expand Down Expand Up @@ -720,4 +706,6 @@ public String execute() {
return transferProcessId;
}
}

public record Protocol(String name, String versionPath) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2025 Think-it GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Think-it GmbH - initial API and implementation
*
*/

package org.eclipse.edc.jsonld.spi;

import java.net.URI;

/**
* Represent a json-ld context file in resources, associated to a context url.
*
* @param resource the resource uri where the cached
* @param url the context url.
*/
public record JsonLdContext(URI resource, String url) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,7 @@ protected TransferEndToEndParticipant() {
}

public static TransferEndToEndParticipant forContext(ComponentRuntimeContext ctx) {
var id = ctx.getConfig().getString("edc.participant.id");
return TransferEndToEndParticipant.Builder.newInstance()
.id(id)
.name(ctx.getName())
.managementUrl(ctx.getEndpoint(MANAGEMENT))
.protocolUrl(ctx.getEndpoint(PROTOCOL))
.build();
return newInstance(ctx).build();
}

public static TransferEndToEndParticipant.Builder newInstance(ComponentRuntimeContext ctx) {
Expand Down
Loading