diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index e25e91d6..032e944f 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -2,6 +2,7 @@ name: Test Code (Style, Tests) on: push: + branches: [ main ] pull_request: branches: [ main ] paths-ignore: diff --git a/advanced/advanced-01-open-telemetry/resources/negotiate-contract.json b/advanced/advanced-01-open-telemetry/resources/negotiate-contract.json index 548d1f5e..932f5a8b 100644 --- a/advanced/advanced-01-open-telemetry/resources/negotiate-contract.json +++ b/advanced/advanced-01-open-telemetry/resources/negotiate-contract.json @@ -1,21 +1,18 @@ { "@context": { - "@vocab": "https://w3id.org/edc/v0.0.1/ns/", - "odrl": "http://www.w3.org/ns/odrl/2/" + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, - "@type": "NegotiationInitiateRequestDto", - "connectorId": "provider", + "@type": "ContractRequest", "counterPartyAddress": "http://provider:19194/protocol", - "consumerId": "consumer", - "providerId": "provider", "protocol": "dataspace-protocol-http", "policy": { "@context": "http://www.w3.org/ns/odrl.jsonld", "@id": "{{contract-offer-id}}", - "@type": "Set", + "@type": "Offer", "permission": [], "prohibition": [], "obligation": [], + "assigner": "provider", "target": "assetId" } } diff --git a/build.gradle.kts b/build.gradle.kts index 07cf7310..1915c302 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,17 +39,12 @@ allprojects { } configure { - versions { - // override default dependency versions here - metaModel.set(edcVersion) - } publish.set(false) } configure { configFile = rootProject.file("resources/edc-checkstyle-config.xml") configDirectory.set(rootProject.file("resources")) - maxWarnings = 0 } // EdcRuntimeExtension uses this to determine the runtime classpath of the module to run. @@ -58,4 +53,13 @@ allprojects { println(sourceSets["main"].runtimeClasspath.asPath) } } + + tasks.test { + testLogging { + showStandardStreams = true + } + } + } + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d0bd4ac0..f255523a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ format.version = "1.1" [versions] assertj = "3.25.3" awaitility = "4.2.1" -edc = "0.5.1" +edc = "0.6.0" jakarta-json = "2.0.1" junit-pioneer = "2.2.0" jupiter = "5.10.2" @@ -45,7 +45,8 @@ edc-http = { module = "org.eclipse.edc:http", version.ref = "edc" } edc-iam-mock = { module = "org.eclipse.edc:iam-mock", version.ref = "edc" } edc-jersey-micrometer = { module = "org.eclipse.edc:jersey-micrometer", version.ref = "edc" } edc-jetty-micrometer = { module = "org.eclipse.edc:jetty-micrometer", version.ref = "edc" } -edc-json-ld = { module = "org.eclipse.edc:json-ld", version.ref = "edc" } +edc-json-ld-lib = { module = "org.eclipse.edc:json-ld-lib", version.ref = "edc" } +edc-json-ld-spi = { module = "org.eclipse.edc:json-ld-spi", version.ref = "edc" } edc-junit = { module = "org.eclipse.edc:junit", version.ref = "edc" } edc-management-api = { module = "org.eclipse.edc:management-api", version.ref = "edc" } edc-micrometer-core = { module = "org.eclipse.edc:micrometer-core", version.ref = "edc" } diff --git a/policy/policy-01-policy-enforcement/policy-enforcement-consumer/build.gradle.kts b/policy/policy-01-policy-enforcement/policy-enforcement-consumer/build.gradle.kts index ee3f7ca9..106240af 100644 --- a/policy/policy-01-policy-enforcement/policy-enforcement-consumer/build.gradle.kts +++ b/policy/policy-01-policy-enforcement/policy-enforcement-consumer/build.gradle.kts @@ -19,12 +19,14 @@ plugins { } dependencies { + implementation(libs.edc.connector.core) implementation(libs.edc.control.plane.core) implementation(libs.edc.data.plane.selector.core) implementation(libs.edc.configuration.filesystem) implementation(libs.edc.management.api) implementation(libs.edc.dsp) implementation(libs.edc.iam.mock) + implementation(libs.edc.http) } application { diff --git a/policy/policy-01-policy-enforcement/policy-enforcement-provider/build.gradle.kts b/policy/policy-01-policy-enforcement/policy-enforcement-provider/build.gradle.kts index 5067d560..f79f931b 100644 --- a/policy/policy-01-policy-enforcement/policy-enforcement-provider/build.gradle.kts +++ b/policy/policy-01-policy-enforcement/policy-enforcement-provider/build.gradle.kts @@ -20,12 +20,14 @@ plugins { dependencies { + implementation(libs.edc.connector.core) implementation(libs.edc.control.plane.core) implementation(libs.edc.data.plane.selector.core) implementation(libs.edc.configuration.filesystem) implementation(libs.edc.management.api) implementation(libs.edc.dsp) implementation(libs.edc.iam.mock) + implementation(libs.edc.http) implementation(project(":policy:policy-01-policy-enforcement:policy-functions")) } diff --git a/policy/policy-01-policy-enforcement/policy-functions/build.gradle.kts b/policy/policy-01-policy-enforcement/policy-functions/build.gradle.kts index fe635374..3010cd8d 100644 --- a/policy/policy-01-policy-enforcement/policy-functions/build.gradle.kts +++ b/policy/policy-01-policy-enforcement/policy-functions/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { api(libs.edc.data.plane.spi) + api(libs.edc.json.ld.spi) implementation(libs.edc.control.plane.core) diff --git a/policy/policy-01-policy-enforcement/policy-functions/src/main/java/org/eclipse/edc/sample/extension/policy/PolicyFunctionsExtension.java b/policy/policy-01-policy-enforcement/policy-functions/src/main/java/org/eclipse/edc/sample/extension/policy/PolicyFunctionsExtension.java index 5cf1ecc3..85881a7f 100644 --- a/policy/policy-01-policy-enforcement/policy-functions/src/main/java/org/eclipse/edc/sample/extension/policy/PolicyFunctionsExtension.java +++ b/policy/policy-01-policy-enforcement/policy-functions/src/main/java/org/eclipse/edc/sample/extension/policy/PolicyFunctionsExtension.java @@ -22,10 +22,12 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import static org.eclipse.edc.connector.contract.spi.validation.ContractValidationService.NEGOTIATION_SCOPE; +import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_USE_ACTION_ATTRIBUTE; import static org.eclipse.edc.policy.engine.spi.PolicyEngine.ALL_SCOPES; +import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; public class PolicyFunctionsExtension implements ServiceExtension { - private static final String LOCATION_CONSTRAINT_KEY = "location"; + private static final String LOCATION_CONSTRAINT_KEY = EDC_NAMESPACE + "location"; @Inject private RuleBindingRegistry ruleBindingRegistry; @@ -41,7 +43,7 @@ public String name() { public void initialize(ServiceExtensionContext context) { var monitor = context.getMonitor(); - ruleBindingRegistry.bind("use", ALL_SCOPES); + ruleBindingRegistry.bind(ODRL_USE_ACTION_ATTRIBUTE, ALL_SCOPES); ruleBindingRegistry.bind(LOCATION_CONSTRAINT_KEY, NEGOTIATION_SCOPE); policyEngine.registerFunction(ALL_SCOPES, Permission.class, LOCATION_CONSTRAINT_KEY, new LocationConstraintFunction(monitor)); } diff --git a/policy/policy-01-policy-enforcement/resources/contract-request.json b/policy/policy-01-policy-enforcement/resources/contract-request.json index c6eaec50..e254def0 100644 --- a/policy/policy-01-policy-enforcement/resources/contract-request.json +++ b/policy/policy-01-policy-enforcement/resources/contract-request.json @@ -1,35 +1,27 @@ { "@context": { - "edc": "https://w3id.org/edc/v0.0.1/ns/", - "odrl": "http://www.w3.org/ns/odrl/2/" + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, - "@type": "NegotiationInitiateRequestDto", - "connectorId": "provider", - "consumerId": "consumer", - "providerId": "provider", - "connectorAddress": "http://localhost:19194/protocol", + "@type": "ContractRequest", + "counterPartyAddress": "http://localhost:19194/protocol", "protocol": "dataspace-protocol-http", - "offer": { - "offerId": "1:test-document:3a75736e-001d-4364-8bd4-9888490edb58", - "assetId": "test-document", - "policy": { - "@id": "1:test-document:13dce0f1-52ed-4554-a194-e83e92733ee5", - "@type": "Set", - "odrl:permission": [ - { - "odrl:action": "use", - "odrl:target": "test-document", - "odrl:constraint": { - "@type": "AtomicConstraint", - "odrl:leftOperand": "location", - "odrl:operator": { - "@id": "odrl:eq" - }, - "odrl:rightOperand": "eu" - } + "policy": { + "@context": "http://www.w3.org/ns/odrl.jsonld", + "@id": "1:test-document:13dce0f1-52ed-4554-a194-e83e92733ee5", + "@type": "Offer", + "permission": [ + { + "action": "use", + "target": "test-document", + "constraint": { + "@type": "AtomicConstraint", + "leftOperand": "location", + "operator": "eq", + "rightOperand": "eu" } - ], - "odrl:target": "test-document" - } + } + ], + "assigner": "provider", + "target": "test-document" } } diff --git a/policy/policy-01-policy-enforcement/resources/create-policy.json b/policy/policy-01-policy-enforcement/resources/create-policy.json index 13802d3a..b31e2801 100644 --- a/policy/policy-01-policy-enforcement/resources/create-policy.json +++ b/policy/policy-01-policy-enforcement/resources/create-policy.json @@ -1,25 +1,25 @@ { "@context": { - "@vocab": "https://w3id.org/edc/v0.0.1/ns/", - "odrl": "http://www.w3.org/ns/odrl/2/" + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, "@id": "eu-policy", "policy": { + "@context": "http://www.w3.org/ns/odrl.jsonld", "@type": "Set", - "odrl:permission": [ + "permission": [ { - "odrl:action": "use", - "odrl:constraint": { + "action": "use", + "constraint": { "@type": "AtomicConstraint", - "odrl:leftOperand": "location", - "odrl:operator": { + "leftOperand": "location", + "operator": { "@id": "odrl:eq" }, - "odrl:rightOperand": "eu" + "rightOperand": "eu" } } ], - "odrl:prohibition": [], - "odrl:obligation": [] + "prohibition": [], + "obligation": [] } } diff --git a/system-tests/build.gradle.kts b/system-tests/build.gradle.kts index 30fad202..3f924704 100644 --- a/system-tests/build.gradle.kts +++ b/system-tests/build.gradle.kts @@ -18,7 +18,8 @@ plugins { dependencies { testImplementation(libs.edc.junit) - testImplementation(libs.edc.json.ld) + testImplementation(libs.edc.json.ld.lib) + testImplementation(libs.edc.json.ld.spi) testImplementation(libs.edc.control.plane.spi) testImplementation(libs.awaitility) testImplementation(libs.okhttp.mockwebserver) diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/common/NegotiationCommon.java b/system-tests/src/test/java/org/eclipse/edc/samples/common/NegotiationCommon.java index 6f22418a..b1aff819 100644 --- a/system-tests/src/test/java/org/eclipse/edc/samples/common/NegotiationCommon.java +++ b/system-tests/src/test/java/org/eclipse/edc/samples/common/NegotiationCommon.java @@ -78,20 +78,16 @@ public static String negotiateContract(String negotiateContractFilePath, String } public static String getContractAgreementId(String contractNegotiationId) { - String url = PrerequisitesCommon.CONSUMER_MANAGEMENT_URL + V2_CONTRACT_NEGOTIATIONS_PATH + contractNegotiationId; + var url = PrerequisitesCommon.CONSUMER_MANAGEMENT_URL + V2_CONTRACT_NEGOTIATIONS_PATH + contractNegotiationId; return await() .atMost(TIMEOUT) .pollInterval(POLL_INTERVAL) .until(() -> get(url, CONTRACT_AGREEMENT_ID), Objects::nonNull); } - - public static void checkContractNegotiationState(String contractNegotiationId, String expectedState) { + + public static String getContractNegotiationState(String contractNegotiationId) { var url = PrerequisitesCommon.CONSUMER_MANAGEMENT_URL + V2_CONTRACT_NEGOTIATIONS_PATH + contractNegotiationId; - - await() - .atMost(TIMEOUT) - .pollInterval(POLL_INTERVAL) - .until(() -> get(url, "state"), state -> state.equals(expectedState)); + return get(url, "state"); } public static String runNegotiation() { diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/common/PolicyCommon.java b/system-tests/src/test/java/org/eclipse/edc/samples/common/PolicyCommon.java index 59511c46..977b2f3b 100644 --- a/system-tests/src/test/java/org/eclipse/edc/samples/common/PolicyCommon.java +++ b/system-tests/src/test/java/org/eclipse/edc/samples/common/PolicyCommon.java @@ -18,24 +18,21 @@ import static org.eclipse.edc.samples.util.TransferUtil.post; public class PolicyCommon { - - private static final String CREATE_ASSET_FILE_PATH = "policy/policy-01-policy-enforcement/resources/create-asset.json"; + private static final String V3_ASSETS_PATH = "/v3/assets"; - private static final String CREATE_POLICY_FILE_PATH = "policy/policy-01-policy-enforcement/resources/create-policy.json"; private static final String V2_POLICY_DEFINITIONS_PATH = "/v2/policydefinitions"; - private static final String CREATE_CONTRACT_DEFINITION_FILE_PATH = "policy/policy-01-policy-enforcement/resources/create-contract-definition.json"; private static final String V2_CONTRACT_DEFINITIONS_PATH = "/v2/contractdefinitions"; - public static void createAsset() { - post(PrerequisitesCommon.PROVIDER_MANAGEMENT_URL + V3_ASSETS_PATH, getFileContentFromRelativePath(CREATE_ASSET_FILE_PATH)); + public static void createAsset(String createAssetFilePath) { + post(PrerequisitesCommon.PROVIDER_MANAGEMENT_URL + V3_ASSETS_PATH, getFileContentFromRelativePath(createAssetFilePath)); } - public static void createPolicy() { - post(PrerequisitesCommon.PROVIDER_MANAGEMENT_URL + V2_POLICY_DEFINITIONS_PATH, getFileContentFromRelativePath(CREATE_POLICY_FILE_PATH)); + public static void createPolicy(String createPolicyFilePath) { + post(PrerequisitesCommon.PROVIDER_MANAGEMENT_URL + V2_POLICY_DEFINITIONS_PATH, getFileContentFromRelativePath(createPolicyFilePath)); } - public static void createContractDefinition() { - post(PrerequisitesCommon.PROVIDER_MANAGEMENT_URL + V2_CONTRACT_DEFINITIONS_PATH, getFileContentFromRelativePath(CREATE_CONTRACT_DEFINITION_FILE_PATH)); + public static void createContractDefinition(String createContractDefinitionFilePath) { + post(PrerequisitesCommon.PROVIDER_MANAGEMENT_URL + V2_CONTRACT_DEFINITIONS_PATH, getFileContentFromRelativePath(createContractDefinitionFilePath)); } } diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicFinalizedTest.java b/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicFinalizedTest.java deleted file mode 100644 index d3816a15..00000000 --- a/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicFinalizedTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2024 Fraunhofer Institute for Software and Systems Engineering - * - * 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: - * Fraunhofer Institute for Software and Systems Engineering - initial API and implementation - * - */ - -package org.eclipse.edc.samples.policy; - -import org.eclipse.edc.junit.annotations.EndToEndTest; -import org.eclipse.edc.junit.extensions.EdcRuntimeExtension; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.Map; - -import static org.eclipse.edc.samples.common.FileTransferCommon.getFileFromRelativePath; -import static org.eclipse.edc.samples.common.NegotiationCommon.checkContractNegotiationState; -import static org.eclipse.edc.samples.common.NegotiationCommon.negotiateContract; -import static org.eclipse.edc.samples.common.PolicyCommon.createAsset; -import static org.eclipse.edc.samples.common.PolicyCommon.createContractDefinition; -import static org.eclipse.edc.samples.common.PolicyCommon.createPolicy; - -@EndToEndTest -class Policy01BasicFinalizedTest { - - private static final String CONTRACT_OFFER_FILE_PATH = "policy/policy-01-policy-enforcement/resources/contract-request.json"; - private static final String PROVIDER_CONFIG_PROPERTIES_FILE_PATH = "policy/policy-01-policy-enforcement/policy-enforcement-provider/config.properties"; - private static final String CONSUMER_CONFIG_PROPERTIES_FILE_PATH = "system-tests/src/test/resources/policy/config-eu.properties"; - - @RegisterExtension - static EdcRuntimeExtension provider = new EdcRuntimeExtension(":policy:policy-01-policy-enforcement:policy-enforcement-provider", - "provider", Map.of("edc.fs.config", getFileFromRelativePath(PROVIDER_CONFIG_PROPERTIES_FILE_PATH).getAbsolutePath())); - - @RegisterExtension - static EdcRuntimeExtension consumer = new EdcRuntimeExtension(":policy:policy-01-policy-enforcement:policy-enforcement-consumer", - "consumer", Map.of("edc.fs.config", getFileFromRelativePath(CONSUMER_CONFIG_PROPERTIES_FILE_PATH).getAbsolutePath())); - - @Test - void runSampleSteps() { - createAsset(); - createPolicy(); - createContractDefinition(); - var negotiationId = negotiateContract(CONTRACT_OFFER_FILE_PATH, ""); - checkContractNegotiationState(negotiationId, "FINALIZED"); - } -} diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicTerminatedTest.java b/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicTerminatedTest.java deleted file mode 100644 index fafdfc1e..00000000 --- a/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicTerminatedTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2024 Fraunhofer Institute for Software and Systems Engineering - * - * 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: - * Fraunhofer Institute for Software and Systems Engineering - initial API and implementation - * - */ - -package org.eclipse.edc.samples.policy; - -import org.eclipse.edc.junit.annotations.EndToEndTest; -import org.eclipse.edc.junit.extensions.EdcRuntimeExtension; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.Map; - -import static org.eclipse.edc.samples.common.FileTransferCommon.getFileFromRelativePath; -import static org.eclipse.edc.samples.common.NegotiationCommon.checkContractNegotiationState; -import static org.eclipse.edc.samples.common.NegotiationCommon.negotiateContract; -import static org.eclipse.edc.samples.common.PolicyCommon.createAsset; -import static org.eclipse.edc.samples.common.PolicyCommon.createContractDefinition; -import static org.eclipse.edc.samples.common.PolicyCommon.createPolicy; - -@EndToEndTest -class Policy01BasicTerminatedTest { - - private static final String CONTRACT_OFFER_FILE_PATH = "policy/policy-01-policy-enforcement/resources/contract-request.json"; - static final String PROVIDER_CONFIG_PROPERTIES_FILE_PATH = "policy/policy-01-policy-enforcement/policy-enforcement-provider/config.properties"; - static final String CONSUMER_CONFIG_PROPERTIES_FILE_PATH = "system-tests/src/test/resources/policy/config-us.properties"; - - @RegisterExtension - static EdcRuntimeExtension provider = new EdcRuntimeExtension(":policy:policy-01-policy-enforcement:policy-enforcement-provider", - "provider", Map.of("edc.fs.config", getFileFromRelativePath(PROVIDER_CONFIG_PROPERTIES_FILE_PATH).getAbsolutePath())); - - @RegisterExtension - static EdcRuntimeExtension consumer = new EdcRuntimeExtension(":policy:policy-01-policy-enforcement:policy-enforcement-consumer", - "consumer", Map.of("edc.fs.config", getFileFromRelativePath(CONSUMER_CONFIG_PROPERTIES_FILE_PATH).getAbsolutePath())); - - @Test - void runSampleSteps() { - createAsset(); - createPolicy(); - createContractDefinition(); - var negotiationId = negotiateContract(CONTRACT_OFFER_FILE_PATH, ""); - checkContractNegotiationState(negotiationId, "TERMINATED"); - } -} diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicTest.java b/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicTest.java new file mode 100644 index 00000000..e52aac2e --- /dev/null +++ b/system-tests/src/test/java/org/eclipse/edc/samples/policy/Policy01BasicTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024 Fraunhofer Institute for Software and Systems Engineering + * + * 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: + * Fraunhofer Institute for Software and Systems Engineering - initial API and implementation + * + */ + +package org.eclipse.edc.samples.policy; + +import org.eclipse.edc.junit.annotations.EndToEndTest; +import org.eclipse.edc.junit.extensions.EdcRuntimeExtension; +import org.eclipse.edc.samples.common.NegotiationCommon; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.Map; + +import static org.awaitility.Awaitility.await; +import static org.eclipse.edc.samples.common.FileTransferCommon.getFileFromRelativePath; +import static org.eclipse.edc.samples.common.NegotiationCommon.getContractNegotiationState; +import static org.eclipse.edc.samples.common.NegotiationCommon.negotiateContract; +import static org.eclipse.edc.samples.common.PolicyCommon.createAsset; +import static org.eclipse.edc.samples.common.PolicyCommon.createContractDefinition; +import static org.eclipse.edc.samples.common.PolicyCommon.createPolicy; +import static org.eclipse.edc.samples.util.TransferUtil.POLL_INTERVAL; +import static org.eclipse.edc.samples.util.TransferUtil.TIMEOUT; + +@EndToEndTest +class Policy01BasicTest { + + private static final String SAMPLE_FOLDER = "policy/policy-01-policy-enforcement"; + private static final String CREATE_ASSET_FILE_PATH = SAMPLE_FOLDER + "/resources/create-asset.json"; + private static final String CREATE_POLICY_FILE_PATH = SAMPLE_FOLDER + "/resources/create-policy.json"; + private static final String CREATE_CONTRACT_DEFINITION_FILE_PATH = SAMPLE_FOLDER + "/resources/create-contract-definition.json"; + private static final String CONTRACT_OFFER_FILE_PATH = SAMPLE_FOLDER + "/resources/contract-request.json"; + + @RegisterExtension + static final EdcRuntimeExtension PROVIDER_RUNTIME = provider(); + + @Nested + class Terminated { + + @RegisterExtension + static final EdcRuntimeExtension CONSUMER_RUNTIME = consumer("system-tests/src/test/resources/policy/config-us.properties"); + + @Test + void runSampleSteps() { + createAsset(CREATE_ASSET_FILE_PATH); + createPolicy(CREATE_POLICY_FILE_PATH); + createContractDefinition(CREATE_CONTRACT_DEFINITION_FILE_PATH); + var negotiationId = negotiateContract(CONTRACT_OFFER_FILE_PATH, ""); + + await() + .atMost(TIMEOUT) + .pollInterval(POLL_INTERVAL) + .until(() -> NegotiationCommon.getContractNegotiationState(negotiationId), s -> s.equals("TERMINATED")); + } + + } + + @Nested + class Finalized { + + @RegisterExtension + static final EdcRuntimeExtension CONSUMER_RUNTIME = consumer("system-tests/src/test/resources/policy/config-eu.properties"); + + @Test + void runSampleSteps() { + createAsset(CREATE_ASSET_FILE_PATH); + createPolicy(CREATE_POLICY_FILE_PATH); + createContractDefinition(CREATE_CONTRACT_DEFINITION_FILE_PATH); + var negotiationId = negotiateContract(CONTRACT_OFFER_FILE_PATH, ""); + + await().atMost(TIMEOUT).pollInterval(POLL_INTERVAL) + .until(() -> getContractNegotiationState(negotiationId), s -> s.equals("FINALIZED")); + } + + } + + private static EdcRuntimeExtension provider() { + return new EdcRuntimeExtension(":policy:policy-01-policy-enforcement:policy-enforcement-provider", + "provider", + Map.of("edc.fs.config", getFileFromRelativePath(SAMPLE_FOLDER + "/policy-enforcement-provider/config.properties").getAbsolutePath()) + ); + } + + private static EdcRuntimeExtension consumer(String configurationFilePath) { + return new EdcRuntimeExtension(":policy:policy-01-policy-enforcement:policy-enforcement-consumer", + "consumer", Map.of("edc.fs.config", getFileFromRelativePath(configurationFilePath).getAbsolutePath())); + } + +} diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Participant.java b/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Participant.java index 53f14490..7d6b7be4 100644 --- a/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Participant.java +++ b/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Participant.java @@ -19,7 +19,6 @@ import jakarta.json.Json; import jakarta.json.JsonArray; import jakarta.json.JsonObject; -import org.eclipse.edc.connector.contract.spi.ContractOfferId; import org.eclipse.edc.jsonld.TitaniumJsonLd; import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.jsonld.util.JacksonJsonLd; @@ -46,7 +45,9 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.DCAT_DATASET_ATTRIBUTE; +import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_ASSIGNER_ATTRIBUTE; import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_POLICY_ATTRIBUTE; +import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_TARGET_ATTRIBUTE; import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; import static org.eclipse.edc.spi.CoreConstants.EDC_PREFIX; @@ -148,7 +149,7 @@ public JsonArray getCatalogDatasets(Participant provider) { .body(requestBody) .post("/v2/catalog/request") .then() - .log().all() + .log().ifValidationFails() .statusCode(200) .extract().body().asString(); @@ -189,7 +190,7 @@ public JsonObject getDatasetForAsset(Participant provider, String assetId) { .body(requestBody) .post("/v2/catalog/dataset/request") .then() - .log().all() + .log().ifValidationFails() .statusCode(200) .extract().body().asString(); @@ -207,19 +208,17 @@ public JsonObject getDatasetForAsset(Participant provider, String assetId) { * Initiate negotiation with a provider. * * @param provider data provider - * @param offerId contract definition id - * @param assetId asset id - * @param policy policy + * @param offer the contract offer * @return id of the contract agreement. */ - public String negotiateContract(Participant provider, String offerId, String assetId, JsonObject policy) { + public String negotiateContract(Participant provider, JsonObject offer) { var requestBody = createObjectBuilder() .add(CONTEXT, createObjectBuilder().add(EDC_PREFIX, EDC_NAMESPACE)) .add(TYPE, "ContractRequestDto") .add("providerId", provider.id) .add("counterPartyAddress", provider.protocolEndpoint.url.toString()) .add("protocol", DSP_PROTOCOL) - .add("policy", jsonLd.compact(policy).getContent()) + .add("policy", jsonLd.compact(offer).getContent()) .build(); var negotiationId = managementEndpoint.baseRequest() @@ -228,6 +227,7 @@ public String negotiateContract(Participant provider, String offerId, String ass .when() .post("/v2/contractnegotiations") .then() + .log().ifValidationFails() .statusCode(200) .extract().body().jsonPath().getString(ID); @@ -286,16 +286,23 @@ public String initiateTransfer(Participant provider, String contractAgreementId, * @return transfer process id. */ public String requestAsset(Participant provider, String assetId, JsonObject privateProperties, JsonObject destination) { - var dataset = getDatasetForAsset(provider, assetId); - var policy = dataset.getJsonArray(ODRL_POLICY_ATTRIBUTE).get(0).asJsonObject(); - var contractDefinitionId = ContractOfferId.parseId(policy.getString(ID)) - .orElseThrow(failure -> new RuntimeException(failure.getFailureDetail())); - var contractAgreementId = negotiateContract(provider, contractDefinitionId.toString(), assetId, policy); + var offer = getOfferForAsset(provider, assetId); + + var contractAgreementId = negotiateContract(provider, offer); var transferProcessId = initiateTransfer(provider, contractAgreementId, assetId, privateProperties, destination); assertThat(transferProcessId).isNotNull(); return transferProcessId; } + private JsonObject getOfferForAsset(Participant provider, String assetId) { + var dataset = getDatasetForAsset(provider, assetId); + var policy = dataset.getJsonArray(ODRL_POLICY_ATTRIBUTE).get(0).asJsonObject(); + return createObjectBuilder(policy) + .add(ODRL_ASSIGNER_ATTRIBUTE, createObjectBuilder().add(ID, provider.id)) + .add(ODRL_TARGET_ATTRIBUTE, createObjectBuilder().add(ID, dataset.get(ID))) + .build(); + } + /** * Get current state of a transfer process. * diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming01httpToHttpTest.java b/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming01httpToHttpTest.java index 12b70552..1699c8d2 100644 --- a/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming01httpToHttpTest.java +++ b/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming01httpToHttpTest.java @@ -18,7 +18,7 @@ import okhttp3.mockwebserver.MockWebServer; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.EdcRuntimeExtension; -import org.eclipse.edc.junit.testfixtures.TestUtils; +import org.eclipse.edc.util.io.Ports; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -79,7 +79,7 @@ public class Streaming01httpToHttpTest { "edc.fs.config", getFileFromRelativePath(SAMPLE_FOLDER + "/streaming-01-runtime/consumer.properties").getAbsolutePath() ) ); - private final int httpReceiverPort = TestUtils.getFreePort(); + private final int httpReceiverPort = Ports.getFreePort(); private final MockWebServer consumerReceiverServer = new MockWebServer(); @BeforeEach diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming02KafkaToHttpTest.java b/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming02KafkaToHttpTest.java index de876440..266cc7ad 100644 --- a/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming02KafkaToHttpTest.java +++ b/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming02KafkaToHttpTest.java @@ -23,7 +23,7 @@ import org.apache.kafka.common.serialization.StringSerializer; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.EdcRuntimeExtension; -import org.eclipse.edc.junit.testfixtures.TestUtils; +import org.eclipse.edc.util.io.Ports; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -98,7 +98,7 @@ public class Streaming02KafkaToHttpTest { .getAbsolutePath() ) ); - private final int httpReceiverPort = TestUtils.getFreePort(); + private final int httpReceiverPort = Ports.getFreePort(); private final MockWebServer consumerReceiverServer = new MockWebServer(); @BeforeEach @@ -128,7 +128,7 @@ void streamData() { Json.createObjectBuilder().build(), destination); await().atMost(TIMEOUT).untilAsserted(() -> { - String state = CONSUMER.getTransferProcessState(transferProcessId); + var state = CONSUMER.getTransferProcessState(transferProcessId); assertThat(state).isEqualTo(STARTED.name()); }); diff --git a/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming03KafkaToKafkaTest.java b/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming03KafkaToKafkaTest.java index 2416592f..5f2882a5 100644 --- a/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming03KafkaToKafkaTest.java +++ b/system-tests/src/test/java/org/eclipse/edc/samples/transfer/streaming/Streaming03KafkaToKafkaTest.java @@ -40,8 +40,8 @@ import org.apache.kafka.common.serialization.StringSerializer; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.EdcRuntimeExtension; -import org.eclipse.edc.junit.testfixtures.TestUtils; import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.edc.util.io.Ports; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; @@ -126,7 +126,7 @@ public class Streaming03KafkaToKafkaTest { ) ); - private final int httpReceiverPort = TestUtils.getFreePort(); + private final int httpReceiverPort = Ports.getFreePort(); private final MockWebServer edrReceiverServer = new MockWebServer(); @BeforeEach diff --git a/transfer/streaming/streaming-01-http-to-http/negotiate-contract.json b/transfer/streaming/streaming-01-http-to-http/negotiate-contract.json index 5b905364..43c42a2e 100644 --- a/transfer/streaming/streaming-01-http-to-http/negotiate-contract.json +++ b/transfer/streaming/streaming-01-http-to-http/negotiate-contract.json @@ -3,13 +3,13 @@ "@vocab": "https://w3id.org/edc/v0.0.1/ns/", "odrl": "http://www.w3.org/ns/odrl/2/" }, - "@type": "NegotiationInitiateRequestDto", + "@type": "ContractRequest", "counterPartyAddress": "http://localhost:18182/protocol", "providerId": "provider", "protocol": "dataspace-protocol-http", "policy": { "@id": "{{offerId}}", - "@type": "use", + "@type": "Offer", "odrl:permission": [], "odrl:prohibition": [], "odrl:obligation": [], diff --git a/transfer/streaming/streaming-01-http-to-http/policy-definition.json b/transfer/streaming/streaming-01-http-to-http/policy-definition.json index e1bdd6af..4ef2a1ec 100644 --- a/transfer/streaming/streaming-01-http-to-http/policy-definition.json +++ b/transfer/streaming/streaming-01-http-to-http/policy-definition.json @@ -3,6 +3,6 @@ "@id": "no-constraint-policy", "policy": { "@context": "http://www.w3.org/ns/odrl.jsonld", - "@type": "use" + "@type": "Set" } } diff --git a/transfer/streaming/streaming-01-http-to-http/streaming-01-runtime/src/main/java/org/eclipse/edc/samples/transfer/streaming/http/HttpStreamingDataSourceFactory.java b/transfer/streaming/streaming-01-http-to-http/streaming-01-runtime/src/main/java/org/eclipse/edc/samples/transfer/streaming/http/HttpStreamingDataSourceFactory.java index 45c2af8c..0fbb3d92 100644 --- a/transfer/streaming/streaming-01-http-to-http/streaming-01-runtime/src/main/java/org/eclipse/edc/samples/transfer/streaming/http/HttpStreamingDataSourceFactory.java +++ b/transfer/streaming/streaming-01-http-to-http/streaming-01-runtime/src/main/java/org/eclipse/edc/samples/transfer/streaming/http/HttpStreamingDataSourceFactory.java @@ -18,7 +18,7 @@ import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSourceFactory; import org.eclipse.edc.connector.transfer.spi.types.TransferProcess; import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.spi.types.domain.transfer.DataFlowRequest; +import org.eclipse.edc.spi.types.domain.transfer.DataFlowStartMessage; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -31,28 +31,27 @@ public class HttpStreamingDataSourceFactory implements DataSourceFactory { @Override - public boolean canHandle(DataFlowRequest request) { - return request.getSourceDataAddress().getType().equals("HttpStreaming"); + public boolean canHandle(DataFlowStartMessage dataFlowStartMessage) { + return dataFlowStartMessage.getSourceDataAddress().getType().equals("HttpStreaming"); } @Override - public DataSource createSource(DataFlowRequest request) { - return new HttpStreamingDataSource(sourceFolder(request).get()); + public DataSource createSource(DataFlowStartMessage dataFlowStartMessage) { + return new HttpStreamingDataSource(sourceFolder(dataFlowStartMessage).get()); } @Override - public @NotNull Result validateRequest(DataFlowRequest request) { - return sourceFolder(request) + public @NotNull Result validateRequest(DataFlowStartMessage dataFlowStartMessage) { + return sourceFolder(dataFlowStartMessage) .map(it -> Result.success()) .orElseGet(() -> Result.failure("sourceFolder is not found or it does not exist")); } - private Optional sourceFolder(DataFlowRequest request) { + private Optional sourceFolder(DataFlowStartMessage request) { return Optional.of(request) - .map(DataFlowRequest::getSourceDataAddress) + .map(DataFlowStartMessage::getSourceDataAddress) .map(it -> it.getStringProperty("sourceFolder")) .map(File::new) .filter(File::exists); } - } diff --git a/transfer/streaming/streaming-02-kafka-to-http/2-policy-definition.json b/transfer/streaming/streaming-02-kafka-to-http/2-policy-definition.json index 4919c71a..5ff4e910 100644 --- a/transfer/streaming/streaming-02-kafka-to-http/2-policy-definition.json +++ b/transfer/streaming/streaming-02-kafka-to-http/2-policy-definition.json @@ -5,6 +5,6 @@ }, "@id": "no-constraint-policy", "policy": { - "@type": "odrl:use" + "@type": "odrl:Set" } } diff --git a/transfer/streaming/streaming-02-kafka-to-http/5-negotiate-contract.json b/transfer/streaming/streaming-02-kafka-to-http/5-negotiate-contract.json index b78eca2b..0307f917 100644 --- a/transfer/streaming/streaming-02-kafka-to-http/5-negotiate-contract.json +++ b/transfer/streaming/streaming-02-kafka-to-http/5-negotiate-contract.json @@ -3,16 +3,16 @@ "@vocab": "https://w3id.org/edc/v0.0.1/ns/", "odrl": "http://www.w3.org/ns/odrl/2/" }, - "@type": "NegotiationInitiateRequestDto", + "@type": "ContractRequest", "counterPartyAddress": "http://localhost:18182/protocol", - "providerId": "provider", "protocol": "dataspace-protocol-http", "policy": { "@id": "{{offerId}}", - "@type": "Use", + "@type": "Offer", "odrl:permission": [], "odrl:prohibition": [], "odrl:obligation": [], + "odrl:assigner": "provider", "odrl:target": "kafka-stream-asset" } } diff --git a/transfer/streaming/streaming-03-kafka-broker/2-policy-definition.json b/transfer/streaming/streaming-03-kafka-broker/2-policy-definition.json index 4919c71a..5ff4e910 100644 --- a/transfer/streaming/streaming-03-kafka-broker/2-policy-definition.json +++ b/transfer/streaming/streaming-03-kafka-broker/2-policy-definition.json @@ -5,6 +5,6 @@ }, "@id": "no-constraint-policy", "policy": { - "@type": "odrl:use" + "@type": "odrl:Set" } } diff --git a/transfer/streaming/streaming-03-kafka-broker/5-negotiate-contract.json b/transfer/streaming/streaming-03-kafka-broker/5-negotiate-contract.json index b525b894..a5803296 100644 --- a/transfer/streaming/streaming-03-kafka-broker/5-negotiate-contract.json +++ b/transfer/streaming/streaming-03-kafka-broker/5-negotiate-contract.json @@ -3,21 +3,16 @@ "edc": "https://w3id.org/edc/v0.0.1/ns/", "odrl": "http://www.w3.org/ns/odrl/2/" }, - "@type": "NegotiationInitiateRequestDto", - "connectorAddress": "http://localhost:18182/protocol", + "@type": "ContractRequest", "counterPartyAddress": "http://localhost:18182/protocol", - "providerId": "provider", "protocol": "dataspace-protocol-http", - "offer": { - "offerId": "{{offerId}}", - "assetId": "kafka-stream-asset", - "policy": { - "@id": "{{offerId}}", - "@type": "use", - "odrl:permission": [], - "odrl:prohibition": [], - "odrl:obligation": [], - "odrl:target": "kafka-stream-asset" - } + "policy": { + "@id": "{{offerId}}", + "@type": "Offer", + "odrl:permission": [], + "odrl:prohibition": [], + "odrl:obligation": [], + "odrl:assigner": "provider", + "odrl:target": "kafka-stream-asset" } } diff --git a/transfer/streaming/streaming-03-kafka-broker/streaming-03-runtime/src/main/java/org/eclipse/edc/samples/streaming/KafkaToKafkaDataFlowController.java b/transfer/streaming/streaming-03-kafka-broker/streaming-03-runtime/src/main/java/org/eclipse/edc/samples/streaming/KafkaToKafkaDataFlowController.java index a10b4b7c..ca659483 100644 --- a/transfer/streaming/streaming-03-kafka-broker/streaming-03-runtime/src/main/java/org/eclipse/edc/samples/streaming/KafkaToKafkaDataFlowController.java +++ b/transfer/streaming/streaming-03-kafka-broker/streaming-03-runtime/src/main/java/org/eclipse/edc/samples/streaming/KafkaToKafkaDataFlowController.java @@ -28,17 +28,16 @@ import java.util.Set; import static org.eclipse.edc.dataaddress.kafka.spi.KafkaDataAddressSchema.KAFKA_TYPE; -import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE; class KafkaToKafkaDataFlowController implements DataFlowController { @Override public boolean canHandle(TransferProcess transferProcess) { - return KAFKA_TYPE.equals(transferProcess.getContentDataAddress().getType()) && "KafkaBroker".equals(transferProcess.getDestinationType()); + return KAFKA_TYPE.equals(transferProcess.getContentDataAddress().getType()) && "KafkaBroker".equals(transferProcess.getTransferType()); } @Override - public @NotNull StatusResult initiateFlow(TransferProcess transferProcess, Policy policy) { + public @NotNull StatusResult start(TransferProcess transferProcess, Policy policy) { // static credentials, in a production case these should be created dynamically and an ACLs entry should be added var username = "alice"; var password = "alice-secret"; @@ -51,12 +50,18 @@ public boolean canHandle(TransferProcess transferProcess) { .property(EndpointDataReference.AUTH_KEY, username) .property(EndpointDataReference.AUTH_CODE, password) .property(EndpointDataReference.CONTRACT_ID, transferProcess.getContractId()) - .property(EDC_NAMESPACE + KafkaDataAddressSchema.TOPIC, contentDataAddress.getStringProperty(KafkaDataAddressSchema.TOPIC)) + .property(KafkaDataAddressSchema.TOPIC, contentDataAddress.getStringProperty(KafkaDataAddressSchema.TOPIC)) .build(); return StatusResult.success(DataFlowResponse.Builder.newInstance().dataAddress(kafkaDataAddress).build()); } + @Override + public StatusResult suspend(TransferProcess transferProcess) { + // here the flow can be suspended, not something covered in this sample + return StatusResult.success(); + } + @Override public StatusResult terminate(TransferProcess transferProcess) { // here the flow can be terminated, not something covered in this sample diff --git a/transfer/transfer-01-negotiation/resources/create-policy.json b/transfer/transfer-01-negotiation/resources/create-policy.json index 4aab1e42..cf7a4703 100644 --- a/transfer/transfer-01-negotiation/resources/create-policy.json +++ b/transfer/transfer-01-negotiation/resources/create-policy.json @@ -5,9 +5,10 @@ }, "@id": "aPolicy", "policy": { + "@context": "http://www.w3.org/ns/odrl.jsonld", "@type": "Set", - "odrl:permission": [], - "odrl:prohibition": [], - "odrl:obligation": [] + "permission": [], + "prohibition": [], + "obligation": [] } } diff --git a/transfer/transfer-01-negotiation/resources/negotiate-contract.json b/transfer/transfer-01-negotiation/resources/negotiate-contract.json index 85762a75..82fe8036 100644 --- a/transfer/transfer-01-negotiation/resources/negotiate-contract.json +++ b/transfer/transfer-01-negotiation/resources/negotiate-contract.json @@ -2,19 +2,14 @@ "@context": { "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, - "@type": "NegotiationInitiateRequestDto", - "connectorId": "provider", + "@type": "ContractRequest", "counterPartyAddress": "http://localhost:19194/protocol", - "consumerId": "consumer", - "providerId": "provider", "protocol": "dataspace-protocol-http", "policy": { "@context": "http://www.w3.org/ns/odrl.jsonld", "@id": "{{contract-offer-id}}", - "@type": "Set", - "permission": [], - "prohibition": [], - "obligation": [], + "@type": "Offer", + "assigner": "provider", "target": "assetId" } }