From 38d7c421c2653ce04399ed20e5fe8928d7329a9e Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Tue, 24 Mar 2026 15:39:46 +0100 Subject: [PATCH 001/259] feat: Move labels from issue to PR (#2692) --- .github/workflows/copy-labels.yaml | 97 ++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 .github/workflows/copy-labels.yaml diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml new file mode 100644 index 0000000000..74b0057c5b --- /dev/null +++ b/.github/workflows/copy-labels.yaml @@ -0,0 +1,97 @@ +################################################################################# +# Copyright (c) 2026 Cofinity-X GmbH +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + + +--- +name: Copy labels from closing issue to PR + +on: + pull_request_target: + types: [opened, edited] + +permissions: + issues: write + pull-requests: write + +jobs: + copy-labels: + runs-on: ubuntu-latest + steps: + - name: Copy labels from linked issue to PR + uses: actions/github-script@v7 + with: + script: | + const CLOSING_KEYWORDS = /\b(?:closes?|fixes?|resolves?)\s+#(\d+)\b/gi; + + // Only these labels are meaningful to copy to a PR + const ALLOWED_LABELS = new Set([ + "breaking change", "bug", "documentation", "enhancement", + "Feature", "infrastructure", "refactoring" + ]); + + const { owner, repo } = context.repo; + const prNumber = context.payload.pull_request.number; + + const { data: pr } = await github.rest.pulls.get({ + owner, + repo, + pull_number: prNumber, + }); + + const text = [pr.title || "", pr.body || ""].join("\n"); + + const issueNumbers = [...text.matchAll(CLOSING_KEYWORDS)].map(m => Number(m[1])); + + if (!issueNumbers.length) { + core.info("No closing-keyword issue references found."); + return; + } + + const prLabelsRes = await github.rest.issues.listLabelsOnIssue({ + owner, repo, issue_number: prNumber + }); + const existingPrLabels = new Set(prLabelsRes.data.map(l => l.name)); + + for (const issue_number of issueNumbers) { + let issue; + try { + issue = await github.rest.issues.get({ owner, repo, issue_number }); + } catch (error) { + core.warning(`Issue #${issue_number} not found or inaccessible: ${error.message}`); + continue; + } + + const labels = issue.data.labels + .map(label => typeof label === "string" ? label : label.name) + .filter(name => name && ALLOWED_LABELS.has(name) && !existingPrLabels.has(name)); + + if (!labels.length) { + core.info(`Issue #${issue_number} has no new applicable labels to copy.`); + continue; + } + + core.info(`Copying labels from issue #${issue_number} to PR #${prNumber}: ${labels.join(", ")}`); + + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: prNumber, + labels + }); + } From 968b132f138574b43a8c32e932f9322c0068ab3d Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Fri, 27 Mar 2026 09:03:28 +0100 Subject: [PATCH 002/259] fix: Handle older connectors <=0.9.0 for version metadata (#2698) * fix: Handle older connectors <=0.9.0 for version metadata Signed-off-by: Lars Geyer-Blaumeiser * Fix e2e test to new expectations Signed-off-by: Lars Geyer-Blaumeiser --------- Signed-off-by: Lars Geyer-Blaumeiser --- .../BaseConnectorDiscoveryServiceImpl.java | 39 ++++++++++++---- .../DefaultConnectorDiscoveryServiceImpl.java | 7 +++ ...aultConnectorDiscoveryServiceImplTest.java | 33 +++++++++++++- ...AndDsp08ConnectorDiscoveryServiceImpl.java | 14 ++++++ ...sp08ConnectorDiscoveryServiceImplTest.java | 45 ++++++++++++++++++- .../e2e/ConnectorParameterDiscoveryTest.java | 4 +- 6 files changed, 128 insertions(+), 14 deletions(-) diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/BaseConnectorDiscoveryServiceImpl.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/BaseConnectorDiscoveryServiceImpl.java index 7e6946f80a..16b9050d95 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/BaseConnectorDiscoveryServiceImpl.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/BaseConnectorDiscoveryServiceImpl.java @@ -146,16 +146,27 @@ public CompletableFuture discoverVersionParams(ConnectorParamsDiscov .build(); return httpClient.executeAsync(wellKnownRequest, emptyList()) - .thenApply(response -> { + .handle((response, throwable) -> { + if (throwable != null) { + var msg = "Counterparty well-known endpoint call has failed with message: %s" + .formatted(throwable.getLocalizedMessage()); + monitor.warning(msg); + throw new BadGatewayException(msg); + } try (response) { - if (!response.isSuccessful()) { - var msg = "Counterparty well-known endpoint has failed with status %s and message: %s" - .formatted(response.code(), response.message()); - monitor.warning(msg); - throw new BadGatewayException(msg); + ProtocolVersion protocolVersion; + if (response.isSuccessful()) { + protocolVersion = extractLatestSupportedVersion(parseResponseBody(response)); + } else { + protocolVersion = handleSpecialStatusCode(response); + if (protocolVersion == null) { + var msg = "Counterparty well-known endpoint has failed with status %s and message: %s" + .formatted(response.code(), response.message()); + monitor.warning(msg); + throw new BadGatewayException(msg); + } } - var protocolVersion = extractLatestSupportedVersion(parseResponseBody(response)); var resultObject = createResultObjectFromProtocolVersionData(request, protocolVersion); versionsCache.put(versionEndpoint, new TimestampedValue<>(protocolVersion, cacheValidity)); return resultObject; @@ -163,6 +174,18 @@ public CompletableFuture discoverVersionParams(ConnectorParamsDiscov }); } + /** + * This method allows to handle certain status codes returned in the response of the version metadata call. + * Needed for older connector versions, as they had and access-restricted endpoint which results in a 401. + * Intention is, to allow to handle this status code instead of doing an authenticated call, as this is + * a temporary situation. + * + * @param response The response object of the version metadata request + * @return Either a default ProtocolVersion object, if the status code is caught or null, if the response does + * not map to a default value + */ + protected abstract ProtocolVersion handleSpecialStatusCode(Response response); + /** * The connector discovery basically deals with two potential input root patterns. First input pattern is, that * the base root of a connector is provided. This is the root endpoint of all dsp endpoints and is basically the root @@ -182,7 +205,7 @@ public CompletableFuture discoverVersionParams(ConnectorParamsDiscov * @return A joint path cleaned from unneeded slashes following the pattern 'root/subpath' * @throws InvalidRequestException If the created path, i.e., the root parameter is not a correct url. */ - protected String createFullPath(String root, String subpath) { + private String createFullPath(String root, String subpath) { var input = root; if (root.endsWith(DSP_DISCOVERY_PATH)) { input = root.substring(0, root.length() - DSP_DISCOVERY_PATH.length() - 1); diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/DefaultConnectorDiscoveryServiceImpl.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/DefaultConnectorDiscoveryServiceImpl.java index 280583ee27..710e343020 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/DefaultConnectorDiscoveryServiceImpl.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/DefaultConnectorDiscoveryServiceImpl.java @@ -21,9 +21,11 @@ package org.eclipse.tractusx.edc.discovery.v4alpha.service; import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.Response; import org.eclipse.edc.http.spi.EdcHttpClient; import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; import org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants; +import org.eclipse.edc.protocol.spi.ProtocolVersion; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.web.spi.exception.InvalidRequestException; import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; @@ -41,6 +43,11 @@ public DefaultConnectorDiscoveryServiceImpl( super(httpClient, didResolver, mapper, List.of(Dsp2025Constants.V_2025_1_VERSION), cacheConfig, monitor); } + @Override + protected ProtocolVersion handleSpecialStatusCode(Response response) { + return null; + } + @Override protected VersionParameters createVersionParameterForProtocolVersion( String counterPartyId, String versionAddress, String version) { diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/DefaultConnectorDiscoveryServiceImplTest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/DefaultConnectorDiscoveryServiceImplTest.java index c78629a8e2..416496e924 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/DefaultConnectorDiscoveryServiceImplTest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/DefaultConnectorDiscoveryServiceImplTest.java @@ -49,6 +49,7 @@ import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; +import java.io.IOException; import java.time.Clock; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -131,7 +132,7 @@ void discoverVersionParams_shouldReturnDsp2025_whenDsp2025Available() { } @Test - void discoverVersionParams_shouldReturnUseCacheDuringSucccess() throws InterruptedException { + void discoverVersionParams_shouldReturnUseCacheDuringSuccess() throws InterruptedException { var paramsDiscoveryRequest = new ConnectorParamsDiscoveryRequest(TEST_DID, TEST_ADDRESS); var expectedJson = Json.createObjectBuilder() @@ -180,7 +181,7 @@ void discoverVersionParams_shouldReturnException_whenOnlyDsp08Available() { } @Test - void discoverVersionParams_shouldReturnException_whenMetadataEndpointHasError() { + void discoverVersionParams_shouldReturnException_whenMetadataEndpointNotFound() { var paramsDiscoveryRequest = new ConnectorParamsDiscoveryRequest(TEST_DID, TEST_ADDRESS); when(httpClient.executeAsync(any(), any())) @@ -194,6 +195,34 @@ void discoverVersionParams_shouldReturnException_whenMetadataEndpointHasError() .hasMessageContaining("404"); } + @Test + void discoverVersionParams_shouldReturnException_whenMetadataEndpointNotAuthenticated() { + var paramsDiscoveryRequest = new ConnectorParamsDiscoveryRequest(TEST_DID, TEST_ADDRESS); + + when(httpClient.executeAsync(any(), any())) + .thenReturn(CompletableFuture.completedFuture( + dummyResponseBuilder(401, "Unauthorized", "Unauthorized").build())); + + assertThatThrownBy(() -> testee.discoverVersionParams(paramsDiscoveryRequest).join()) + .isInstanceOf(CompletionException.class) + .hasCauseInstanceOf(BadGatewayException.class) + .hasMessageContaining("Counterparty well-known endpoint has failed with status") + .hasMessageContaining("401"); + } + + @Test + void discoverVersionParams_shouldReturnException_whenHttpClientThrowsException() { + var paramsDiscoveryRequest = new ConnectorParamsDiscoveryRequest(TEST_DID, TEST_ADDRESS); + + when(httpClient.executeAsync(any(), any())) + .thenReturn(CompletableFuture.failedFuture(new IOException("Failed Call"))); + assertThatThrownBy(() -> testee.discoverVersionParams(paramsDiscoveryRequest).join()) + .isInstanceOf(CompletionException.class) + .hasCauseInstanceOf(BadGatewayException.class) + .hasMessageContaining("Failed Call"); + + } + @Test void discoverVersionParams_shouldReturnException_whenVersionRequestHasMissingProps() { var paramsDiscoveryRequest = new ConnectorParamsDiscoveryRequest(TEST_DID, TEST_ADDRESS); diff --git a/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/service/BpnlAndDsp08ConnectorDiscoveryServiceImpl.java b/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/service/BpnlAndDsp08ConnectorDiscoveryServiceImpl.java index 6cc0a4e943..61595132b4 100644 --- a/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/service/BpnlAndDsp08ConnectorDiscoveryServiceImpl.java +++ b/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/service/BpnlAndDsp08ConnectorDiscoveryServiceImpl.java @@ -22,10 +22,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.json.JsonArray; +import okhttp3.Response; import org.eclipse.edc.http.spi.EdcHttpClient; import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; import org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants; import org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants; +import org.eclipse.edc.protocol.spi.ProtocolVersion; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.web.spi.exception.InvalidRequestException; import org.eclipse.tractusx.edc.discovery.v4alpha.service.BaseConnectorDiscoveryServiceImpl; @@ -65,6 +67,18 @@ public CompletableFuture discoverConnectors(ConnectorDiscoveryRequest mapToDid(request.counterPartyId()), request.knownConnectors())); } + @Override + protected ProtocolVersion handleSpecialStatusCode(Response response) { + if (response.code() == 401) { + // Connectors of version 0.9.0 and earlier had access-control for the version metadata endpoint + // This way, we assume, that a 401 indicates such a case and therefore default the protocol version to be used + // Wrong endpoint urls result in a 404, so the assumption here should be valid, if not, no big harm is + // done, as the call to a dsp endpoint would simply fail anyway. + return new ProtocolVersion("v0.8", "", ""); + } + return null; + } + @Override protected VersionParameters createVersionParameterForProtocolVersion( String counterPartyId, String versionAddress, String version) { diff --git a/edc-extensions/connector-discovery/cx-connector-discovery/src/test/java/org/eclipse/tractusx/edc/discovery/cx/BpnlAndDsp08ConnectorDiscoveryServiceImplTest.java b/edc-extensions/connector-discovery/cx-connector-discovery/src/test/java/org/eclipse/tractusx/edc/discovery/cx/BpnlAndDsp08ConnectorDiscoveryServiceImplTest.java index 5b20ce33f0..57ab2937d7 100644 --- a/edc-extensions/connector-discovery/cx-connector-discovery/src/test/java/org/eclipse/tractusx/edc/discovery/cx/BpnlAndDsp08ConnectorDiscoveryServiceImplTest.java +++ b/edc-extensions/connector-discovery/cx-connector-discovery/src/test/java/org/eclipse/tractusx/edc/discovery/cx/BpnlAndDsp08ConnectorDiscoveryServiceImplTest.java @@ -33,6 +33,7 @@ import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.web.spi.exception.BadGatewayException; import org.eclipse.edc.web.spi.exception.InvalidRequestException; import org.eclipse.tractusx.edc.discovery.cx.service.BpnlAndDsp08ConnectorDiscoveryServiceImpl; import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; @@ -160,6 +161,42 @@ void discoverVersionParams_shouldReturnDsp08_whenDidDsp2025NotAvailable(String c assertThat(response).isEqualTo(expectedJson); } + @Test + void discoverVersionParams_shouldReturnDsp08_whenMetadataEndpointIsAccessControlled() { + var paramsDiscoveryRequest = new ConnectorParamsDiscoveryRequest(TEST_DID, TEST_ADDRESS); + + when(bdrsClient.resolveBpn(TEST_DID)) + .thenReturn(TEST_BPNL); + when(httpClient.executeAsync(any(), any())) + .thenReturn(CompletableFuture.completedFuture( + dummyResponseBuilder(401, "Unauthorized", "Unauthorized").build())); + + var expectedJson = Json.createObjectBuilder() + .add(CATALOG_REQUEST_COUNTER_PARTY_ID, TEST_BPNL) + .add(CATALOG_REQUEST_PROTOCOL, VERSION_PROTOCOL_OLD) + .add(CATALOG_REQUEST_COUNTER_PARTY_ADDRESS, TEST_ADDRESS) + .build(); + + var response = testee.discoverVersionParams(paramsDiscoveryRequest).join(); + + assertThat(response).isEqualTo(expectedJson); + } + + @Test + void discoverVersionParams_shouldReturnFailure_whenMetadataEndpointReturnsNotFound() { + var paramsDiscoveryRequest = new ConnectorParamsDiscoveryRequest(TEST_DID, TEST_ADDRESS); + + when(httpClient.executeAsync(any(), any())) + .thenReturn(CompletableFuture.completedFuture( + dummyResponseBuilder(404, "Not found", "Not found").build())); + + assertThatThrownBy(() -> testee.discoverVersionParams(paramsDiscoveryRequest).join()) + .isInstanceOf(CompletionException.class) + .hasCauseInstanceOf(BadGatewayException.class) + .hasMessageContaining("Counterparty well-known endpoint has failed with status") + .hasMessageContaining("404"); + } + @Test void discoverVersionParams_shouldReturnFailure_whenDidNotResolvable() { var paramsDiscoveryRequest = new ConnectorParamsDiscoveryRequest(TEST_BPNL, TEST_ADDRESS); @@ -338,9 +375,13 @@ void discoverConnectors_shouldReturnExpectedValues_WithKnownConnectorsProvided(S } static okhttp3.Response.Builder dummyResponseBuilder(String body) { + return dummyResponseBuilder(200, body, "any"); + } + + static okhttp3.Response.Builder dummyResponseBuilder(int code, String body, String message) { return new okhttp3.Response.Builder() - .code(200) - .message("any") + .code(code) + .message(message) .body(ResponseBody.create(body, MediaType.get("application/json"))) .protocol(Protocol.HTTP_1_1) .request(new Request.Builder().url(TEST_ADDRESS).build()); diff --git a/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorParameterDiscoveryTest.java b/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorParameterDiscoveryTest.java index fedd3931bb..6b5f50804a 100644 --- a/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorParameterDiscoveryTest.java +++ b/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorParameterDiscoveryTest.java @@ -222,13 +222,13 @@ void discoveryShouldReturn502_ifMetadaEndpointNotReachable() { } @Test - void discoveryShouldReturn500_whenProviderEndpointNotReachable() { + void discoveryShouldReturn502_whenProviderEndpointNotReachable() { var requestBody = createRequestBody(PROVIDER_FULL_DSP.getBpn(), "http://non-existing-provider.com"); var response = CONSUMER.discoverDspParameters(requestBody); - response.statusCode(500) + response.statusCode(502) .extract().body().asString(); } From ea561875feb4c965fc61c8af3d2a286d2a7befdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 09:03:52 +0100 Subject: [PATCH 003/259] chore(deps): bump flyway from 12.1.1 to 12.2.0 (#2709) Bumps `flyway` from 12.1.1 to 12.2.0. Updates `org.flywaydb:flyway-core` from 12.1.1 to 12.2.0 - [Release notes](https://github.com/flyway/flyway/releases) - [Commits](https://github.com/flyway/flyway/compare/flyway-12.1.1...flyway-12.2.0) Updates `org.flywaydb:flyway-database-postgresql` from 12.1.1 to 12.2.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.2.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 33ed321338..4265fc0a51 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ azure-storage-blob = "12.33.2" bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" -flyway = "12.1.1" +flyway = "12.2.0" jackson = "2.21.1" jakarta-json = "2.1.3" junit = "6.0.3" From c049a880395300869062d946b02bb42b36d3ed58 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 09:04:37 +0100 Subject: [PATCH 004/259] chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations (#2708) Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.25.0 to 2.26.1. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.25.0...v2.26.1) --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations dependency-version: 2.26.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4265fc0a51..af8cd674c4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ junit = "6.0.3" nimbus = "10.8" okhttp = "5.3.2" opentelemetry = "2.26.0" -opentelemetry-instrumentation = "2.25.0" +opentelemetry-instrumentation = "2.26.1" opentelemetry-log4j-appender = "2.25.0-alpha" postgres = "42.7.10" restAssured = "6.0.0" From 82a57b7c3a413383e3b1285e0c4b5b8f86739898 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 09:04:57 +0100 Subject: [PATCH 005/259] chore(deps): bump gradle-wrapper from 9.4.0 to 9.4.1 (#2707) Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.4.0 to 9.4.1. - [Release notes](https://github.com/gradle/gradle/releases) - [Commits](https://github.com/gradle/gradle/compare/v9.4.0...v9.4.1) --- updated-dependencies: - dependency-name: gradle-wrapper dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index dbc3ce4a04..c61a118f7d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 0262dcbd52..739907dfd1 100755 --- a/gradlew +++ b/gradlew @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. From 30bb737e309b9b805abed117a3483ad871d2fb65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 11:05:07 +0100 Subject: [PATCH 006/259] chore(deps): bump io.opentelemetry.javaagent:opentelemetry-javaagent (#2705) Bumps [io.opentelemetry.javaagent:opentelemetry-javaagent](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.26.0 to 2.26.1. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.26.0...v2.26.1) --- updated-dependencies: - dependency-name: io.opentelemetry.javaagent:opentelemetry-javaagent dependency-version: 2.26.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index af8cd674c4..9c52b43838 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,7 +18,7 @@ jakarta-json = "2.1.3" junit = "6.0.3" nimbus = "10.8" okhttp = "5.3.2" -opentelemetry = "2.26.0" +opentelemetry = "2.26.1" opentelemetry-instrumentation = "2.26.1" opentelemetry-log4j-appender = "2.25.0-alpha" postgres = "42.7.10" From d867a56c4ec6a4c01f8ca9f4cda5b509d2b70535 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 11:05:31 +0100 Subject: [PATCH 007/259] chore(deps): bump com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp (#2710) Bumps [com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp](https://github.com/FasterXML/jackson-datatypes-misc) from 2.21.1 to 2.21.2. - [Commits](https://github.com/FasterXML/jackson-datatypes-misc/compare/jackson-datatypes-misc-parent-2.21.1...jackson-datatypes-misc-parent-2.21.2) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp dependency-version: 2.21.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9c52b43838..8c126f2b41 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" flyway = "12.2.0" -jackson = "2.21.1" +jackson = "2.21.2" jakarta-json = "2.1.3" junit = "6.0.3" nimbus = "10.8" From ae61697dab70bfca51adf8b11326bd9e0898553d Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Tue, 31 Mar 2026 13:11:09 +0200 Subject: [PATCH 008/259] fix: move from localstack to floci (#2716) --- ...tackExtension.java => FlociExtension.java} | 85 +++++++++++++------ .../tests/transfer/S3ToS3EndToEndTest.java | 7 +- 2 files changed, 61 insertions(+), 31 deletions(-) rename edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/aws/{LocalstackExtension.java => FlociExtension.java} (57%) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/aws/LocalstackExtension.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/aws/FlociExtension.java similarity index 57% rename from edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/aws/LocalstackExtension.java rename to edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/aws/FlociExtension.java index c446e1d63b..2d92f6d441 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/aws/LocalstackExtension.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/aws/FlociExtension.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -24,15 +25,19 @@ import org.eclipse.edc.aws.s3.AwsClientProviderImpl; import org.eclipse.edc.aws.s3.S3ClientRequest; import org.eclipse.edc.junit.utils.LazySupplier; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExtensionContext; -import org.testcontainers.containers.localstack.LocalStackContainer; +import org.testcontainers.containers.GenericContainer; import org.testcontainers.utility.DockerImageName; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.s3.S3AsyncClient; +import software.amazon.awssdk.services.iam.IamAsyncClient; +import software.amazon.awssdk.services.iam.model.CreateUserRequest; +import software.amazon.awssdk.services.iam.model.EntityAlreadyExistsException; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.CreateBucketRequest; import software.amazon.awssdk.services.s3.model.ListObjectsRequest; @@ -42,62 +47,65 @@ import java.net.URI; import java.nio.file.Path; import java.util.List; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.CompletionException; import static org.assertj.core.api.Assertions.assertThat; -public class LocalstackExtension implements BeforeAllCallback, AfterAllCallback { +public class FlociExtension implements BeforeAllCallback, AfterAllCallback { + private static final DockerImageName FLOCI_IMAGE = DockerImageName.parse("hectorvent/floci:latest"); private static final String S3_REGION = Region.US_WEST_2.id(); + private static final int EDGE_PORT = 4566; private static final String SYSTEM_PROPERTY_AWS_ACCESS_KEY_ID = "aws.accessKeyId"; private static final String SYSTEM_PROPERTY_AWS_SECRET_ACCESS_KEY = "aws.secretAccessKey"; - - private final String accessKeyId = "test-access-key"; - private final String secretAccessKey = UUID.randomUUID().toString(); + private static final String SYSTEM_PROPERTY_AWS_REGION = "aws.region"; + private static final String STORAGE_PATH = "/app/data"; + private static final String ROOT_USER_NAME = "root"; + + private final AwsCredentials credentials = AwsBasicCredentials.create("test-access-key", UUID.randomUUID().toString()); + @SuppressWarnings("resource") + private final GenericContainer flociContainer = new GenericContainer<>(FLOCI_IMAGE) + .withExposedPorts(EDGE_PORT) + .withEnv("FLOCI_STORAGE_MODE", "hybrid") + .withEnv("FLOCI_STORAGE_PERSISTENT_PATH", STORAGE_PATH) + .withTmpFs(Map.of(STORAGE_PATH, "rw")) + .withLogConsumer(frame -> System.out.print(frame.getUtf8String())); private final LazySupplier clientProvider = new LazySupplier<>(() -> new AwsClientProviderImpl(getConfiguration())); - private final LocalStackContainer localStackContainer = new LocalStackContainer( - DockerImageName.parse("localstack/localstack") - ).withServices(LocalStackContainer.Service.S3, LocalStackContainer.Service.IAM, LocalStackContainer.Service.STS) - .withEnv("DEFAULT_REGION", S3_REGION) - .withEnv("AWS_ACCESS_KEY_ID", accessKeyId) - .withEnv("AWS_SECRET_ACCESS_KEY", secretAccessKey) - .withExposedPorts(4566, 9000) - .withLogConsumer(frame -> System.out.print(frame.getUtf8String())); - @Override - public void beforeAll(ExtensionContext context) { - System.setProperty(SYSTEM_PROPERTY_AWS_ACCESS_KEY_ID, accessKeyId); - System.setProperty(SYSTEM_PROPERTY_AWS_SECRET_ACCESS_KEY, secretAccessKey); - localStackContainer.start(); + public void beforeAll(@NotNull ExtensionContext context) { + System.setProperty(SYSTEM_PROPERTY_AWS_ACCESS_KEY_ID, credentials.accessKeyId()); + System.setProperty(SYSTEM_PROPERTY_AWS_SECRET_ACCESS_KEY, credentials.secretAccessKey()); + System.setProperty(SYSTEM_PROPERTY_AWS_REGION, S3_REGION); + flociContainer.start(); + initializeRootUser(); } @Override - public void afterAll(ExtensionContext context) { - localStackContainer.stop(); + public void afterAll(@NotNull ExtensionContext context) { + flociContainer.stop(); } public AwsCredentials getCredentials() { - return AwsBasicCredentials.create(accessKeyId, secretAccessKey); + return credentials; } public String getEndpointOverride() { - return "http://localhost:%s/".formatted(localStackContainer.getFirstMappedPort()); + return endpointUri().toString(); } public S3Client s3Client() { return clientProvider.get().s3Client(S3ClientRequest.from(S3_REGION, getEndpointOverride())); } - public S3AsyncClient s3AsyncClient() { - return clientProvider.get().s3AsyncClient(S3ClientRequest.from(S3_REGION, getEndpointOverride())); - } - public String getS3region() { return S3_REGION; } + @SuppressWarnings("resource") public String createBucket() { var bucketName = UUID.randomUUID().toString(); var response = s3Client().createBucket(CreateBucketRequest.builder().bucket(bucketName).build()); @@ -105,11 +113,13 @@ public String createBucket() { return bucketName; } + @SuppressWarnings("resource") public void uploadObjectOnBucket(String bucketName, String key, Path filePath) { var response = s3Client().putObject(PutObjectRequest.builder().bucket(bucketName).key(key).build(), filePath); assertThat(response.sdkHttpResponse().isSuccessful()).isTrue(); } + @SuppressWarnings("resource") public List listObjects(String bucketName) { return s3Client().listObjects(ListObjectsRequest.builder().bucket(bucketName).build()) .contents().stream().map(S3Object::key).toList(); @@ -117,9 +127,28 @@ public List listObjects(String bucketName) { private AwsClientProviderConfiguration getConfiguration() { return AwsClientProviderConfiguration.Builder.newInstance() - .endpointOverride(URI.create(getEndpointOverride())) + .endpointOverride(endpointUri()) .credentialsProvider(this::getCredentials) .build(); } + private void initializeRootUser() { + try (var iamClient = IamAsyncClient.builder() + .credentialsProvider(StaticCredentialsProvider.create(credentials)) + .region(Region.AWS_GLOBAL) + .endpointOverride(endpointUri()) + .build()) { + try { + iamClient.createUser(CreateUserRequest.builder().userName(ROOT_USER_NAME).build()).join(); + } catch (CompletionException exception) { + if (!(exception.getCause() instanceof EntityAlreadyExistsException)) { + throw new RuntimeException("Failed to initialize Floci IAM root user", exception); + } + } + } + } + + private URI endpointUri() { + return URI.create("http://localhost:%s/".formatted(flociContainer.getMappedPort(EDGE_PORT))); + } } diff --git a/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/S3ToS3EndToEndTest.java b/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/S3ToS3EndToEndTest.java index e362ccc40a..aebddde99c 100644 --- a/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/S3ToS3EndToEndTest.java +++ b/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/S3ToS3EndToEndTest.java @@ -24,7 +24,7 @@ import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.junit.testfixtures.TestUtils; -import org.eclipse.tractusx.edc.tests.aws.LocalstackExtension; +import org.eclipse.tractusx.edc.tests.aws.FlociExtension; import org.eclipse.tractusx.edc.tests.participant.TransferParticipant; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; import org.junit.jupiter.api.BeforeEach; @@ -85,9 +85,10 @@ public class S3ToS3EndToEndTest { private static final RuntimeExtension CONSUMER_RUNTIME = pgRuntime(CONSUMER, POSTGRES, CONSUMER::getConfig); @RegisterExtension - private static final LocalstackExtension PROVIDER_CONTAINER = new LocalstackExtension(); + private static final FlociExtension PROVIDER_CONTAINER = new FlociExtension(); + @RegisterExtension - private static final LocalstackExtension CONSUMER_CONTAINER = new LocalstackExtension(); + private static final FlociExtension CONSUMER_CONTAINER = new FlociExtension(); @BeforeEach void setup() { From 220f99a091e8942bd6c7eebadae6d90a6cefd758 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Tue, 31 Mar 2026 15:48:05 +0200 Subject: [PATCH 009/259] fix: remove json-schema-validator (#2717) --- edc-tests/compatibility-tests/build.gradle.kts | 6 ++++-- edc-tests/e2e/iatp-tests/build.gradle.kts | 6 ------ edc-tests/runtime/iatp/iatp-extensions/build.gradle.kts | 3 --- .../tractusx/edc/iatp/CredentialsJsonLdExtension.java | 9 --------- .../runtime/iatp/runtime-memory-iatp-ih/build.gradle.kts | 6 ------ 5 files changed, 4 insertions(+), 26 deletions(-) diff --git a/edc-tests/compatibility-tests/build.gradle.kts b/edc-tests/compatibility-tests/build.gradle.kts index 974b72c824..d2c9e06ada 100644 --- a/edc-tests/compatibility-tests/build.gradle.kts +++ b/edc-tests/compatibility-tests/build.gradle.kts @@ -24,6 +24,7 @@ plugins { configurations.all { exclude("org.eclipse.edc", "decentralized-claims-core") + exclude("com.networknt", "json-schema-validator") } dependencies { @@ -41,11 +42,12 @@ dependencies { testImplementation(libs.jacksonJsonP) testImplementation(libs.restAssured) testImplementation(libs.awaitility) - testImplementation(libs.wiremock) + testImplementation(libs.wiremock) { + exclude("com.networknt", "json-schema-validator") + } testImplementation(libs.testcontainers.junit) testImplementation(libs.testcontainers.postgres) testImplementation(testFixtures(libs.edc.api.management.test.fixtures)) testImplementation(testFixtures(libs.edc.sql.test.fixtures)) testImplementation(testFixtures(project(":edc-tests:e2e-fixtures"))) - testImplementation("com.networknt:json-schema-validator:2.0.0") } diff --git a/edc-tests/e2e/iatp-tests/build.gradle.kts b/edc-tests/e2e/iatp-tests/build.gradle.kts index 50be7e9a7e..ca838f7c3c 100644 --- a/edc-tests/e2e/iatp-tests/build.gradle.kts +++ b/edc-tests/e2e/iatp-tests/build.gradle.kts @@ -28,12 +28,6 @@ configurations.all { } dependencies { - constraints { - testImplementation("com.networknt:json-schema-validator:3.0.0") { - because("older versions cause runtime issues") - } - } - testImplementation(testFixtures(project(":edc-tests:e2e-fixtures"))) testImplementation(libs.edc.spi.keypair) testImplementation(libs.edc.ih.spi) diff --git a/edc-tests/runtime/iatp/iatp-extensions/build.gradle.kts b/edc-tests/runtime/iatp/iatp-extensions/build.gradle.kts index ea3f4a7fb4..4a53d5fa6f 100644 --- a/edc-tests/runtime/iatp/iatp-extensions/build.gradle.kts +++ b/edc-tests/runtime/iatp/iatp-extensions/build.gradle.kts @@ -25,9 +25,6 @@ dependencies { implementation(libs.edc.ih.spi) implementation(libs.edc.spi.jsonld) implementation(project(":spi:core-spi")) - - // TODO: test - implementation("com.networknt:json-schema-validator:3.0.0") } // do not publish diff --git a/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/CredentialsJsonLdExtension.java b/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/CredentialsJsonLdExtension.java index ff5f270118..c4e67b638a 100644 --- a/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/CredentialsJsonLdExtension.java +++ b/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/CredentialsJsonLdExtension.java @@ -19,7 +19,6 @@ package org.eclipse.tractusx.edc.iatp; -import com.networknt.schema.format.PatternFormat; import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; @@ -38,18 +37,10 @@ public class CredentialsJsonLdExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - try { jsonLd.registerCachedDocument(BUSINESS_PARTNER_DATA, Thread.currentThread().getContextClassLoader().getResource("cx-credentials-context.json").toURI()); } catch (URISyntaxException e) { throw new RuntimeException(e); } - - // TODO: test - try { - getClass().getClassLoader().loadClass(PatternFormat.class.getName()); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } } } diff --git a/edc-tests/runtime/iatp/runtime-memory-iatp-ih/build.gradle.kts b/edc-tests/runtime/iatp/runtime-memory-iatp-ih/build.gradle.kts index eaf9f7b5e6..69b34cc831 100644 --- a/edc-tests/runtime/iatp/runtime-memory-iatp-ih/build.gradle.kts +++ b/edc-tests/runtime/iatp/runtime-memory-iatp-ih/build.gradle.kts @@ -42,12 +42,6 @@ dependencies { exclude("org.eclipse.edc", "data-plane-selector-client") } - constraints { - implementation("com.networknt:json-schema-validator:3.0.0") { - because("older versions cause runtime issues") - } - } - implementation(libs.edc.core.controlplane) implementation(libs.edc.core.did) implementation(libs.edc.decentralized.claims.transform) From f8fe5a7a35ea4c3a06af5c22fabb406b11c72a39 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Tue, 31 Mar 2026 16:06:04 +0200 Subject: [PATCH 010/259] feat: remove dependency force constrains (#2720) --- build.gradle.kts | 13 ---------- .../edc-controlplane-base/build.gradle.kts | 26 ------------------- .../edc-dataplane-base/build.gradle.kts | 23 ---------------- 3 files changed, 62 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 82be11fe4e..8dea41cf18 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -63,23 +63,10 @@ allprojects { apply(plugin = "jacoco") dependencies { - implementation("org.slf4j:slf4j-api:2.0.17") constraints { plugins.apply("org.gradle.java-test-fixtures") - implementation("org.yaml:snakeyaml:2.6") { - because("version 1.33 has vulnerabilities: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-1471.") - } - implementation("net.minidev:json-smart:2.6.0") { - because("version 2.4.8 has vulnerabilities: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-1370.") - } - implementation("com.azure:azure-core-http-netty:1.16.3") { - because("Version 1.15.12 depends on netty libs that have two vulnerabilities: https://mvnrepository.com/artifact/com.azure/azure-core-http-netty/1.15.12") - } - implementation("io.netty:netty-codec-http2:4.2.9.Final") { - because("Version 4.1.123.Final vulnerability: https://www.cve.org/CVERecord?id=CVE-2025-8916") - } } } diff --git a/edc-controlplane/edc-controlplane-base/build.gradle.kts b/edc-controlplane/edc-controlplane-base/build.gradle.kts index 660c369368..a2eb22205c 100644 --- a/edc-controlplane/edc-controlplane-base/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-base/build.gradle.kts @@ -32,32 +32,6 @@ configurations.all { } dependencies { - constraints { - runtimeOnly("tools.jackson.core:jackson-core:3.1.0") { - because("older version has vulnerability") - } - runtimeOnly("com.fasterxml.jackson.core:jackson-core:2.21.1") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty:jetty-server:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty:jetty-http:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty:jetty-security:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty.ee10:jetty-ee10-servlet:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty.websocket:jetty-websocket:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty:jetty-session:12.1.7") { - because("older version has vulnerability") - } - } runtimeOnly(libs.edc.bom.controlplane.base) { exclude(module = "dsp-2024") } diff --git a/edc-dataplane/edc-dataplane-base/build.gradle.kts b/edc-dataplane/edc-dataplane-base/build.gradle.kts index c31bc0f0fc..8c105884cc 100644 --- a/edc-dataplane/edc-dataplane-base/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-base/build.gradle.kts @@ -28,29 +28,6 @@ configurations.all { } dependencies { - constraints { - runtimeOnly("tools.jackson.core:jackson-core:3.1.0") { - because("older version has vulnerability") - } - runtimeOnly("com.fasterxml.jackson.core:jackson-core:2.21.1") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty:jetty-server:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty:jetty-security:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty:jetty-session:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty.ee10:jetty-ee10-servlet:12.1.7") { - because("older version has vulnerability") - } - runtimeOnly("org.eclipse.jetty.websocket:jetty-websocket:12.1.7") { - because("older version has vulnerability") - } - } runtimeOnly(libs.edc.bom.dataplane.base) implementation(project(":core:edr-core")) From b5a5ceddd7f5691a69580f76f0fd7e58eb95f9d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 09:07:00 +0100 Subject: [PATCH 011/259] chore(deps): bump log4j2 from 2.25.3 to 2.25.4 (#2724) Bumps `log4j2` from 2.25.3 to 2.25.4. Updates `org.apache.logging.log4j:log4j-api` from 2.25.3 to 2.25.4 Updates `org.apache.logging.log4j:log4j-core` from 2.25.3 to 2.25.4 Updates `org.apache.logging.log4j:log4j-core-test` from 2.25.3 to 2.25.4 Updates `org.apache.logging.log4j:log4j-layout-template-json` from 2.25.3 to 2.25.4 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-version: 2.25.4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-core dependency-version: 2.25.4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-core-test dependency-version: 2.25.4 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-layout-template-json dependency-version: 2.25.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8c126f2b41..d53c020090 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,7 +27,7 @@ rsApi = "4.0.0" testcontainers = "2.0.4" testcontainers-keycloak = "4.1.1" titanium = "1.7.0" -log4j2 = "2.25.3" +log4j2 = "2.25.4" wiremock = "3.13.2" From cdb6987cae7995f2573cf7540075807169487b69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 09:08:54 +0100 Subject: [PATCH 012/259] chore(deps): bump com.nimbusds:nimbus-jose-jwt from 10.8 to 10.9 (#2726) Bumps [com.nimbusds:nimbus-jose-jwt](https://bitbucket.org/connect2id/nimbus-jose-jwt) from 10.8 to 10.9. - [Changelog](https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/CHANGELOG.txt) - [Commits](https://bitbucket.org/connect2id/nimbus-jose-jwt/branches/compare/10.9..10.8) --- updated-dependencies: - dependency-name: com.nimbusds:nimbus-jose-jwt dependency-version: '10.9' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d53c020090..ca0aebed58 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ flyway = "12.2.0" jackson = "2.21.2" jakarta-json = "2.1.3" junit = "6.0.3" -nimbus = "10.8" +nimbus = "10.9" okhttp = "5.3.2" opentelemetry = "2.26.1" opentelemetry-instrumentation = "2.26.1" From d5d532023d3510b5b4caaf02d769bd00a922cf29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 09:24:50 +0200 Subject: [PATCH 013/259] chore(deps): bump flyway from 12.2.0 to 12.3.0 (#2727) Bumps `flyway` from 12.2.0 to 12.3.0. Updates `org.flywaydb:flyway-core` from 12.2.0 to 12.3.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.2.0 to 12.3.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.3.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ca0aebed58..1b9f6f7178 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ azure-storage-blob = "12.33.2" bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" -flyway = "12.2.0" +flyway = "12.3.0" jackson = "2.21.2" jakarta-json = "2.1.3" junit = "6.0.3" From 861417a6ee421e5da43508690a2901c9aaa56678 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 09:25:10 +0200 Subject: [PATCH 014/259] chore(deps): bump com.gradleup.shadow from 9.3.2 to 9.4.1 (#2725) Bumps [com.gradleup.shadow](https://github.com/GradleUp/shadow) from 9.3.2 to 9.4.1. - [Release notes](https://github.com/GradleUp/shadow/releases) - [Commits](https://github.com/GradleUp/shadow/compare/9.3.2...9.4.1) --- updated-dependencies: - dependency-name: com.gradleup.shadow dependency-version: 9.4.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1b9f6f7178..3f207f139a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -241,6 +241,6 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } -shadow = { id = "com.gradleup.shadow", version = "9.3.2" } +shadow = { id = "com.gradleup.shadow", version = "9.4.1" } swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.45" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From a52cebadc2be7325e18d4fa534aa7fcf3ac7f306 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 09:25:27 +0200 Subject: [PATCH 015/259] chore(deps): bump trufflesecurity/trufflehog from 3.93.8 to 3.94.2 (#2723) Bumps [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) from 3.93.8 to 3.94.2. - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/6c05c4a00b91aa542267d8e32a8254774799d68d...6bd2d14f7a4bc1e569fa3550efa7ec632a4fa67b) --- updated-dependencies: - dependency-name: trufflesecurity/trufflehog dependency-version: 3.94.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/secrets-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index a87e33be6b..6eb33dfbb5 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -46,7 +46,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@6c05c4a00b91aa542267d8e32a8254774799d68d + uses: trufflesecurity/trufflehog@6bd2d14f7a4bc1e569fa3550efa7ec632a4fa67b continue-on-error: true with: path: ./ # Scan the entire repository From 7b295119eacd620511e86c1bb5f99d0a3ce33244 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Apr 2026 09:25:57 +0200 Subject: [PATCH 016/259] chore(deps): bump aws from 2.42.12 to 2.42.27 (#2722) Bumps `aws` from 2.42.12 to 2.42.27. Updates `software.amazon.awssdk:s3` from 2.42.12 to 2.42.27 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.42.12 to 2.42.27 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.42.27 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.42.27 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3f207f139a..6559fc46c2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.1.6" allure = "2.33.0" awaitility = "4.3.0" -aws = "2.42.12" +aws = "2.42.27" azure-storage-blob = "12.33.2" bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" From d8418b14c896d38f9c0ca479f67d076b0e645215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo?= <18561736+bmg13@users.noreply.github.com> Date: Wed, 8 Apr 2026 10:03:58 +0100 Subject: [PATCH 017/259] refactoring: move DSP 0.8 implementation to tractusx edc (#2694) * Add dsp-spi-08 module. * Add DSP08 API. * Include Remaining Modules. * Small Code Refactor. * Update E2E testing. * Small Code Cleanup. * Fix Copy Right. * Update Token-Interceptor Dependency. * Update Settings File. --- core/json-ld-core/build.gradle.kts | 2 +- core/json-ld-cx/build.gradle.kts | 2 +- .../connector-discovery-api/build.gradle.kts | 2 +- .../cx-connector-discovery/build.gradle.kts | 2 +- .../cx-dataspace-protocol/build.gradle.kts | 2 +- edc-extensions/dcp/cx-dcp/build.gradle.kts | 2 +- edc-extensions/dcp/tx-dcp/build.gradle.kts | 2 +- .../dsp/dsp-catalog-08/build.gradle.kts | 27 ++ .../dsp-catalog-http-api-08/build.gradle.kts | 50 ++++ .../http/api/DspCatalogApiV08Extension.java | 124 +++++++++ .../controller/DspCatalogApiController08.java | 47 ++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++ .../api/DspCatalogApiV08ExtensionTest.java | 62 +++++ .../DspCatalogApiController08Test.java | 45 ++++ .../dsp-catalog-transform-08/build.gradle.kts | 30 +++ .../DspCatalogTransformV08Extension.java | 84 ++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++ .../build.gradle.kts | 35 +++ .../DspApiConfigurationV08Extension.java | 134 ++++++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++ .../DspApiConfigurationV08ExtensionTest.java | 109 ++++++++ .../dsp-http-dispatcher-08/build.gradle.kts | 27 ++ .../DspHttpDispatcherV08Extension.java | 44 ++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++ .../dsp/dsp-negotiation-08/build.gradle.kts | 27 ++ .../build.gradle.kts | 52 ++++ .../api/DspNegotiationApiV08Extension.java | 99 +++++++ .../DspNegotiationApiController08.java | 50 ++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++ .../DspNegotiationApiV08ExtensionTest.java | 62 +++++ .../DspNegotiationApiController08Test.java | 45 ++++ .../build.gradle.kts | 30 +++ .../DspNegotiationTransformV08Extension.java | 92 +++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++ .../dsp-transfer-process-08/build.gradle.kts | 27 ++ .../build.gradle.kts | 51 ++++ .../DspTransferProcessApiV08Extension.java | 89 +++++++ .../DspTransferProcessApiController08.java | 47 ++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++ ...DspTransferProcessApiV08ExtensionTest.java | 59 +++++ ...DspTransferProcessApiController08Test.java | 45 ++++ .../build.gradle.kts | 36 +++ ...pTransferProcessTransformV08Extension.java | 94 +++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++ .../token-interceptor/build.gradle.kts | 1 + .../edc/interceptor/OkHttpInterceptor.java | 2 +- .../edc/tests/catalog/CatalogTestDspV08.java | 242 ++++++++++++++++++ gradle/libs.versions.toml | 10 +- settings.gradle.kts | 12 + spi/dsp-spi-08/build.gradle.kts | 27 ++ .../protocol/dsp/spi/type/Dsp08Constants.java | 42 +++ 51 files changed, 2224 insertions(+), 9 deletions(-) create mode 100644 edc-extensions/dsp/dsp-catalog-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08Extension.java create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/controller/DspCatalogApiController08.java create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08ExtensionTest.java create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/catalog/http/api/controller/DspCatalogApiController08Test.java create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/DspCatalogTransformV08Extension.java create mode 100644 edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dsp/dsp-http-api-configuration-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java create mode 100644 edc-extensions/dsp/dsp-http-api-configuration-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dsp/dsp-http-api-configuration-08/src/test/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08ExtensionTest.java create mode 100644 edc-extensions/dsp/dsp-http-dispatcher-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-http-dispatcher-08/src/main/java/org/eclipse/edc/protocol/dsp/http/dispatcher/DspHttpDispatcherV08Extension.java create mode 100644 edc-extensions/dsp/dsp-http-dispatcher-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dsp/dsp-negotiation-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiV08Extension.java create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/controller/DspNegotiationApiController08.java create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiV08ExtensionTest.java create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/controller/DspNegotiationApiController08Test.java create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/transform/DspNegotiationTransformV08Extension.java create mode 100644 edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiV08Extension.java create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/controller/DspTransferProcessApiController08.java create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiV08ExtensionTest.java create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/controller/DspTransferProcessApiController08Test.java create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/build.gradle.kts create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transform/DspTransferProcessTransformV08Extension.java create mode 100644 edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java create mode 100644 spi/dsp-spi-08/build.gradle.kts create mode 100644 spi/dsp-spi-08/src/main/java/org/eclipse/edc/protocol/dsp/spi/type/Dsp08Constants.java diff --git a/core/json-ld-core/build.gradle.kts b/core/json-ld-core/build.gradle.kts index 70123e50f9..68d3b018bd 100644 --- a/core/json-ld-core/build.gradle.kts +++ b/core/json-ld-core/build.gradle.kts @@ -27,7 +27,7 @@ dependencies { implementation(libs.edc.spi.core) implementation(libs.edc.spi.jsonld) implementation(libs.dsp.spi.v2025) - implementation(libs.dsp.spi.v08) + implementation(project(":spi:dsp-spi-08")) implementation(libs.edc.lib.management.api) testImplementation(testFixtures(libs.edc.junit)) } diff --git a/core/json-ld-cx/build.gradle.kts b/core/json-ld-cx/build.gradle.kts index 12f9b9a4a6..b06559e742 100644 --- a/core/json-ld-cx/build.gradle.kts +++ b/core/json-ld-cx/build.gradle.kts @@ -28,7 +28,7 @@ dependencies { implementation(libs.edc.spi.core) implementation(libs.edc.spi.jsonld) implementation(libs.dsp.spi.v2025) - implementation(libs.dsp.spi.v08) + implementation(project(":spi:dsp-spi-08")) implementation(libs.edc.lib.management.api) testImplementation(testFixtures(libs.edc.junit)) } diff --git a/edc-extensions/connector-discovery/connector-discovery-api/build.gradle.kts b/edc-extensions/connector-discovery/connector-discovery-api/build.gradle.kts index 3f82ef0099..9ac82c8e11 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/build.gradle.kts +++ b/edc-extensions/connector-discovery/connector-discovery-api/build.gradle.kts @@ -32,7 +32,7 @@ dependencies { api(libs.edc.spi.http) api(libs.edc.spi.jsonld) api(libs.edc.spi.controlplane) - api(libs.dsp.spi.v08) + api(project(":spi:dsp-spi-08")) api(libs.dsp.spi.v2025) api(libs.edc.spi.identity.did) diff --git a/edc-extensions/connector-discovery/cx-connector-discovery/build.gradle.kts b/edc-extensions/connector-discovery/cx-connector-discovery/build.gradle.kts index 059d6438b4..e3bea89774 100644 --- a/edc-extensions/connector-discovery/cx-connector-discovery/build.gradle.kts +++ b/edc-extensions/connector-discovery/cx-connector-discovery/build.gradle.kts @@ -31,7 +31,7 @@ dependencies { api(libs.edc.spi.http) api(libs.edc.spi.jsonld) api(libs.edc.spi.controlplane) - api(libs.dsp.spi.v08) + api(project(":spi:dsp-spi-08")) api(libs.dsp.spi.v2025) api(libs.edc.spi.identity.did) diff --git a/edc-extensions/dataspace-protocol/cx-dataspace-protocol/build.gradle.kts b/edc-extensions/dataspace-protocol/cx-dataspace-protocol/build.gradle.kts index c8e1e9d1fe..57c39887dd 100644 --- a/edc-extensions/dataspace-protocol/cx-dataspace-protocol/build.gradle.kts +++ b/edc-extensions/dataspace-protocol/cx-dataspace-protocol/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { implementation(libs.edc.ih.spi.credentials) implementation(libs.dsp.spi.http) - implementation(libs.dsp.spi.v08) + implementation(project(":spi:dsp-spi-08")) implementation(libs.edc.spi.participant) implementation(libs.edc.spi.protocol) diff --git a/edc-extensions/dcp/cx-dcp/build.gradle.kts b/edc-extensions/dcp/cx-dcp/build.gradle.kts index d97a7b5593..0e9a7e9b5d 100644 --- a/edc-extensions/dcp/cx-dcp/build.gradle.kts +++ b/edc-extensions/dcp/cx-dcp/build.gradle.kts @@ -31,7 +31,7 @@ dependencies { implementation(libs.edc.spi.transfer) implementation(libs.edc.spi.catalog) implementation(libs.dsp.spi.v2025) - implementation(libs.dsp.spi.v08) + implementation(project(":spi:dsp-spi-08")) implementation(project(":spi:core-spi")) implementation(project(":edc-extensions:dcp:tx-dcp")) diff --git a/edc-extensions/dcp/tx-dcp/build.gradle.kts b/edc-extensions/dcp/tx-dcp/build.gradle.kts index 3e92bdd65d..81893fff12 100644 --- a/edc-extensions/dcp/tx-dcp/build.gradle.kts +++ b/edc-extensions/dcp/tx-dcp/build.gradle.kts @@ -30,7 +30,7 @@ dependencies { implementation(libs.edc.spi.transfer) implementation(libs.edc.spi.catalog) implementation(libs.dsp.spi.v2025) - implementation(libs.dsp.spi.v08) + implementation(project(":spi:dsp-spi-08")) implementation(project(":spi:core-spi")) implementation(project(":core:core-utils")) diff --git a/edc-extensions/dsp/dsp-catalog-08/build.gradle.kts b/edc-extensions/dsp/dsp-catalog-08/build.gradle.kts new file mode 100644 index 0000000000..de7120d266 --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/build.gradle.kts @@ -0,0 +1,27 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(project(":edc-extensions:dsp:dsp-catalog-08:dsp-catalog-http-api-08")) + api(project(":edc-extensions:dsp:dsp-catalog-08:dsp-catalog-transform-08")) +} diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/build.gradle.kts b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/build.gradle.kts new file mode 100644 index 0000000000..0bfccacdc9 --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/build.gradle.kts @@ -0,0 +1,50 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` + id(libs.plugins.swagger.get().pluginId) +} + +dependencies { + api(project(":spi:dsp-spi-08")) + api(libs.dsp.spi.http) + api(libs.edc.spi.core) + api(libs.edc.spi.web) + api(libs.edc.spi.jsonld) + + api(libs.edc.spi.controlplane) + + implementation(libs.edc.lib.jersey.providers) + implementation(libs.edc.lib.dsp.catalog.validation) + implementation(libs.edc.lib.dsp.catalog.http.api) + + implementation(libs.jakarta.rsApi) + + testImplementation(testFixtures(libs.edc.core.jersey)) + testImplementation(libs.edc.junit) + testImplementation(libs.restAssured) + testImplementation(testFixtures(libs.edc.lib.dsp.catalog.http.api)) +} + +edcBuild { + swagger { + apiGroup.set("dsp-api") + } +} diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08Extension.java b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08Extension.java new file mode 100644 index 0000000000..8449c4fb60 --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08Extension.java @@ -0,0 +1,124 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.catalog.http.api; + +import org.eclipse.edc.connector.controlplane.catalog.spi.DataService; +import org.eclipse.edc.connector.controlplane.catalog.spi.DataServiceRegistry; +import org.eclipse.edc.connector.controlplane.services.spi.catalog.CatalogProtocolService; +import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.protocol.dsp.catalog.http.api.controller.DspCatalogApiController08; +import org.eclipse.edc.protocol.dsp.catalog.http.api.decorator.Base64continuationTokenSerDes; +import org.eclipse.edc.protocol.dsp.catalog.http.api.decorator.ContinuationTokenManagerImpl; +import org.eclipse.edc.protocol.dsp.catalog.validation.CatalogRequestMessageValidator; +import org.eclipse.edc.protocol.dsp.http.spi.message.ContinuationTokenManager; +import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; +import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.query.CriterionOperatorRegistry; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; +import org.eclipse.edc.web.spi.WebService; +import org.eclipse.edc.web.spi.configuration.ApiContext; + +import static org.eclipse.edc.protocol.dsp.http.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_TRANSFORMER_CONTEXT_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspCatalogPropertyAndTypeNames.DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; + +/** + * Creates and registers the controller for dataspace protocol v0.8 catalog requests. + */ +@Extension(value = DspCatalogApiV08Extension.NAME) +public class DspCatalogApiV08Extension implements ServiceExtension { + + public static final String NAME = "Dataspace Protocol Catalog v08 Extension"; + + @Inject + private WebService webService; + @Inject + private CatalogProtocolService service; + @Inject + private DataServiceRegistry dataServiceRegistry; + @Inject + private JsonObjectValidatorRegistry validatorRegistry; + @Inject + private DspRequestHandler dspRequestHandler; + @Inject + private CriterionOperatorRegistry criterionOperatorRegistry; + @Inject + private DataspaceProfileContextRegistry dataspaceProfileContextRegistry; + @Inject + private TypeTransformerRegistry transformerRegistry; + @Inject + private Monitor monitor; + @Inject + private TypeManager typeManager; + @Inject + private JsonLd jsonLd; + + @Inject + private SingleParticipantContextSupplier participantContextSupplier; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + registerValidators(); + + webService.registerResource(ApiContext.PROTOCOL, new DspCatalogApiController08(service, dspRequestHandler, continuationTokenManager(monitor), participantContextSupplier)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspCatalogApiController08.class, new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, DSP_SCOPE_V_08)); + } + + @Override + public void prepare() { + registerDataService(); + } + + private void registerDataService() { + var webhook = dataspaceProfileContextRegistry.getWebhook(DATASPACE_PROTOCOL_HTTP); + if (webhook != null) { + dataServiceRegistry.register(DATASPACE_PROTOCOL_HTTP, (ctx, protocol) -> DataService.Builder.newInstance() + .endpointDescription("dspace:connector") + .endpointUrl(webhook.url()) + .build()); + } + } + + private ContinuationTokenManager continuationTokenManager(Monitor monitor) { + var continuationTokenSerDes = new Base64continuationTokenSerDes(transformerRegistry.forContext(DSP_TRANSFORMER_CONTEXT_V_08), jsonLd); + return new ContinuationTokenManagerImpl(continuationTokenSerDes, DSP_NAMESPACE_V_08, monitor); + } + + private void registerValidators() { + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM), CatalogRequestMessageValidator.instance(criterionOperatorRegistry, DSP_NAMESPACE_V_08)); + } +} diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/controller/DspCatalogApiController08.java b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/controller/DspCatalogApiController08.java new file mode 100644 index 0000000000..fd06b5d453 --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/controller/DspCatalogApiController08.java @@ -0,0 +1,47 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.catalog.http.api.controller; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import org.eclipse.edc.connector.controlplane.services.spi.catalog.CatalogProtocolService; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.protocol.dsp.http.spi.message.ContinuationTokenManager; +import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; + +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; +import static org.eclipse.edc.protocol.dsp.catalog.http.api.CatalogApiPaths.BASE_PATH; +import static org.eclipse.edc.protocol.dsp.http.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; + +/** + * Provides the HTTP endpoint for receiving catalog requests. + */ +@Consumes({APPLICATION_JSON}) +@Produces({APPLICATION_JSON}) +@Path(BASE_PATH) +public class DspCatalogApiController08 extends BaseDspCatalogApiController { + + public DspCatalogApiController08(CatalogProtocolService service, DspRequestHandler dspRequestHandler, ContinuationTokenManager continuationTokenManager, SingleParticipantContextSupplier participantContextSupplier) { + super(service, dspRequestHandler, continuationTokenManager, participantContextSupplier, DATASPACE_PROTOCOL_HTTP, DSP_NAMESPACE_V_08); + } + +} diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..1f45517c84 --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.edc.protocol.dsp.catalog.http.api.DspCatalogApiV08Extension \ No newline at end of file diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08ExtensionTest.java b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08ExtensionTest.java new file mode 100644 index 0000000000..5fa9b90a2e --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08ExtensionTest.java @@ -0,0 +1,62 @@ +/******************************************************************************** + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.catalog.http.api; + +import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.protocol.dsp.spi.transform.DspProtocolTypeTransformerRegistry; +import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspCatalogPropertyAndTypeNames.DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(DependencyInjectionExtension.class) +class DspCatalogApiV08ExtensionTest { + + private final JsonObjectValidatorRegistry validatorRegistry = mock(); + private final DataspaceProfileContextRegistry versionRegistry = mock(); + private final DspProtocolTypeTransformerRegistry dspTransformerRegistry = mock(); + + @BeforeEach + void setUp(ServiceExtensionContext context) { + context.registerService(JsonObjectValidatorRegistry.class, validatorRegistry); + context.registerService(DataspaceProfileContextRegistry.class, versionRegistry); + context.registerService(DspProtocolTypeTransformerRegistry.class, dspTransformerRegistry); + + when(dspTransformerRegistry.forProtocol(any())).thenReturn(Result.success(mock())); + } + + @Test + void shouldRegisterMessageValidator(DspCatalogApiV08Extension extension, ServiceExtensionContext context) { + extension.initialize(context); + + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CATALOG_REQUEST_MESSAGE_TERM)), any()); + } +} diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/catalog/http/api/controller/DspCatalogApiController08Test.java b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/catalog/http/api/controller/DspCatalogApiController08Test.java new file mode 100644 index 0000000000..bfa0d0bf22 --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/catalog/http/api/controller/DspCatalogApiController08Test.java @@ -0,0 +1,45 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.catalog.http.api.controller; + +import org.eclipse.edc.jsonld.spi.JsonLdNamespace; +import org.eclipse.edc.junit.annotations.ApiTest; + +import static org.eclipse.edc.protocol.dsp.catalog.http.api.CatalogApiPaths.BASE_PATH; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; + +@ApiTest +class DspCatalogApiController08Test extends DspCatalogApiControllerTestBase { + + @Override + protected String basePath() { + return BASE_PATH; + } + + @Override + protected JsonLdNamespace namespace() { + return DSP_NAMESPACE_V_08; + } + + @Override + protected Object controller() { + return new DspCatalogApiController08(service, dspRequestHandler, continuationTokenManager, participantContextSupplier); + } +} diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/build.gradle.kts b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/build.gradle.kts new file mode 100644 index 0000000000..31f468d992 --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/build.gradle.kts @@ -0,0 +1,30 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(libs.edc.spi.core) + api(project(":spi:dsp-spi-08")) + + implementation(libs.edc.lib.transform) + implementation(libs.edc.lib.dsp.catalog.transform) +} diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/DspCatalogTransformV08Extension.java b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/DspCatalogTransformV08Extension.java new file mode 100644 index 0000000000..513b598c3d --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/transform/DspCatalogTransformV08Extension.java @@ -0,0 +1,84 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.catalog.transform; + +import jakarta.json.Json; +import org.eclipse.edc.participant.spi.ParticipantIdMapper; +import org.eclipse.edc.protocol.dsp.catalog.transform.from.JsonObjectFromCatalogErrorTransformer; +import org.eclipse.edc.protocol.dsp.catalog.transform.from.JsonObjectFromCatalogRequestMessageTransformer; +import org.eclipse.edc.protocol.dsp.catalog.transform.from.JsonObjectFromCatalogTransformer; +import org.eclipse.edc.protocol.dsp.catalog.transform.from.JsonObjectFromDataServiceTransformer; +import org.eclipse.edc.protocol.dsp.catalog.transform.from.JsonObjectFromDatasetTransformer; +import org.eclipse.edc.protocol.dsp.catalog.transform.from.JsonObjectFromDistributionTransformer; +import org.eclipse.edc.protocol.dsp.catalog.transform.to.JsonObjectToCatalogRequestMessageTransformer; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; + +import java.util.Map; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_TRANSFORMER_CONTEXT_V_08; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; + +/** + * Provides the transformers for DSP v0.8 catalog message types via the {@link TypeTransformerRegistry}. + */ +@Extension(value = DspCatalogTransformV08Extension.NAME) +public class DspCatalogTransformV08Extension implements ServiceExtension { + + public static final String NAME = "Dataspace Protocol Catalog Transform v08 Extension"; + + @Inject + private TypeTransformerRegistry registry; + + @Inject + private TypeManager typeManager; + + @Inject + private ParticipantIdMapper participantIdMapper; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + registerTransformers(); + } + + private void registerTransformers() { + var jsonFactory = Json.createBuilderFactory(Map.of()); + + var dspApiTransformerRegistry = registry.forContext(DSP_TRANSFORMER_CONTEXT_V_08); + dspApiTransformerRegistry.register(new JsonObjectFromCatalogRequestMessageTransformer(jsonFactory, DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectToCatalogRequestMessageTransformer(DSP_NAMESPACE_V_08)); + + dspApiTransformerRegistry.register(new JsonObjectFromCatalogTransformer(jsonFactory, typeManager, JSON_LD, participantIdMapper, DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectFromDatasetTransformer(jsonFactory, typeManager, JSON_LD)); + dspApiTransformerRegistry.register(new JsonObjectFromDistributionTransformer(jsonFactory)); + dspApiTransformerRegistry.register(new JsonObjectFromDataServiceTransformer(jsonFactory)); + dspApiTransformerRegistry.register(new JsonObjectFromCatalogErrorTransformer(jsonFactory, DSP_NAMESPACE_V_08)); + } +} diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..0b1721bb5f --- /dev/null +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.edc.protocol.dsp.catalog.transform.DspCatalogTransformV08Extension \ No newline at end of file diff --git a/edc-extensions/dsp/dsp-http-api-configuration-08/build.gradle.kts b/edc-extensions/dsp/dsp-http-api-configuration-08/build.gradle.kts new file mode 100644 index 0000000000..980f55f957 --- /dev/null +++ b/edc-extensions/dsp/dsp-http-api-configuration-08/build.gradle.kts @@ -0,0 +1,35 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(libs.edc.spi.catalog) + api(libs.edc.spi.core) + api(libs.dsp.spi) + api(project(":spi:dsp-spi-08")) + api(libs.dsp.spi.http) + + implementation(libs.edc.lib.transform) + implementation(libs.edc.transform.controlplane) + + testImplementation(libs.edc.junit) +} diff --git a/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java b/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java new file mode 100644 index 0000000000..30cd1a965d --- /dev/null +++ b/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java @@ -0,0 +1,134 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.http.api.configuration; + +import jakarta.json.Json; +import org.eclipse.edc.connector.controlplane.transform.edc.from.JsonObjectFromAssetTransformer; +import org.eclipse.edc.connector.controlplane.transform.edc.to.JsonObjectToAssetTransformer; +import org.eclipse.edc.connector.controlplane.transform.odrl.OdrlTransformersFactory; +import org.eclipse.edc.connector.controlplane.transform.odrl.from.JsonObjectFromPolicyTransformer; +import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.participant.spi.ParticipantIdMapper; +import org.eclipse.edc.protocol.dsp.http.spi.api.DspBaseWebhookAddress; +import org.eclipse.edc.protocol.spi.DataspaceProfileContext; +import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; +import org.eclipse.edc.protocol.spi.DefaultParticipantIdExtractionFunction; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.transform.transformer.dspace.from.JsonObjectFromDataAddressDspaceTransformer; +import org.eclipse.edc.transform.transformer.dspace.to.JsonObjectToDataAddressDspaceTransformer; +import org.eclipse.edc.transform.transformer.edc.from.JsonObjectFromCriterionTransformer; +import org.eclipse.edc.transform.transformer.edc.from.JsonObjectFromQuerySpecTransformer; +import org.eclipse.edc.transform.transformer.edc.to.JsonObjectToCriterionTransformer; +import org.eclipse.edc.transform.transformer.edc.to.JsonObjectToQuerySpecTransformer; +import org.eclipse.edc.transform.transformer.edc.to.JsonValueToGenericTypeTransformer; + +import java.util.Map; + +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_PREFIX; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_SCHEMA; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCT_PREFIX; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCT_SCHEMA; +import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_PREFIX; +import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_PREFIX; +import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA; +import static org.eclipse.edc.protocol.dsp.http.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_TRANSFORMER_CONTEXT_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.V_08; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; + +/** + * Registers protocol webhook, API transformers and namespaces for DSP v0.8. + */ +@Extension(value = DspApiConfigurationV08Extension.NAME) +public class DspApiConfigurationV08Extension implements ServiceExtension { + + public static final String NAME = "Dataspace Protocol API Configuration v08 Extension"; + + @Inject + private TypeManager typeManager; + @Inject + private JsonLd jsonLd; + @Inject + private TypeTransformerRegistry transformerRegistry; + @Inject + private ParticipantIdMapper participantIdMapper; + @Inject + private DspBaseWebhookAddress dspWebhookAddress; + @Inject + private DataspaceProfileContextRegistry dataspaceProfileContextRegistry; + @Inject + private DefaultParticipantIdExtractionFunction participantIdExtractionFunction; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + dataspaceProfileContextRegistry.registerDefault(new DataspaceProfileContext(DATASPACE_PROTOCOL_HTTP, V_08, () -> dspWebhookAddress.get(), participantIdExtractionFunction)); + + // registers ns for DSP scope + registerNamespaces(); + registerTransformers(); + } + + private void registerNamespaces() { + jsonLd.registerNamespace(DCAT_PREFIX, DCAT_SCHEMA, DSP_SCOPE_V_08); + jsonLd.registerNamespace(DCT_PREFIX, DCT_SCHEMA, DSP_SCOPE_V_08); + jsonLd.registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, DSP_SCOPE_V_08); + jsonLd.registerNamespace(DSPACE_PREFIX, DSP_NAMESPACE_V_08.namespace(), DSP_SCOPE_V_08); + jsonLd.registerNamespace(VOCAB, EDC_NAMESPACE, DSP_SCOPE_V_08); + jsonLd.registerNamespace(EDC_PREFIX, EDC_NAMESPACE, DSP_SCOPE_V_08); + } + + private void registerTransformers() { + var jsonBuilderFactory = Json.createBuilderFactory(Map.of()); + + // EDC model to JSON-LD transformers + var dspApiTransformerRegistry = transformerRegistry.forContext(DSP_TRANSFORMER_CONTEXT_V_08); + dspApiTransformerRegistry.register(new JsonObjectFromAssetTransformer(jsonBuilderFactory, typeManager, JSON_LD)); + dspApiTransformerRegistry.register(new JsonObjectFromQuerySpecTransformer(jsonBuilderFactory)); + dspApiTransformerRegistry.register(new JsonObjectFromCriterionTransformer(jsonBuilderFactory, typeManager, JSON_LD)); + + // JSON-LD to EDC model transformers + // ODRL Transformers + OdrlTransformersFactory.jsonObjectToOdrlTransformers(participantIdMapper).forEach(dspApiTransformerRegistry::register); + + dspApiTransformerRegistry.register(new JsonValueToGenericTypeTransformer(typeManager, JSON_LD)); + dspApiTransformerRegistry.register(new JsonObjectToAssetTransformer()); + dspApiTransformerRegistry.register(new JsonObjectToQuerySpecTransformer()); + dspApiTransformerRegistry.register(new JsonObjectToCriterionTransformer()); + dspApiTransformerRegistry.register(new JsonObjectToDataAddressDspaceTransformer(DSP_NAMESPACE_V_08)); + + dspApiTransformerRegistry.register(new JsonObjectFromPolicyTransformer(jsonBuilderFactory, participantIdMapper)); + dspApiTransformerRegistry.register(new JsonObjectFromDataAddressDspaceTransformer(jsonBuilderFactory, typeManager, JSON_LD)); + } +} diff --git a/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..b32d3c89f4 --- /dev/null +++ b/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.edc.protocol.dsp.http.api.configuration.DspApiConfigurationV08Extension \ No newline at end of file diff --git a/edc-extensions/dsp/dsp-http-api-configuration-08/src/test/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08ExtensionTest.java b/edc-extensions/dsp/dsp-http-api-configuration-08/src/test/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08ExtensionTest.java new file mode 100644 index 0000000000..a4b624b77c --- /dev/null +++ b/edc-extensions/dsp/dsp-http-api-configuration-08/src/test/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08ExtensionTest.java @@ -0,0 +1,109 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.http.api.configuration; + +import org.eclipse.edc.boot.system.injection.ObjectFactory; +import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.protocol.dsp.http.spi.api.DspBaseWebhookAddress; +import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.configuration.ConfigFactory; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.Map; + +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_PREFIX; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCAT_SCHEMA; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCT_PREFIX; +import static org.eclipse.edc.jsonld.spi.Namespaces.DCT_SCHEMA; +import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_PREFIX; +import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA; +import static org.eclipse.edc.protocol.dsp.http.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_PREFIX; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(DependencyInjectionExtension.class) +class DspApiConfigurationV08ExtensionTest { + + private final String webhookUrl = "http://webhook"; + + private final TypeManager typeManager = mock(); + private final JsonLd jsonLd = mock(); + private final DataspaceProfileContextRegistry dataspaceProfileContextRegistry = mock(); + + @BeforeEach + void setUp(ServiceExtensionContext context) { + context.registerService(TypeManager.class, typeManager); + context.registerService(JsonLd.class, jsonLd); + context.registerService(DspBaseWebhookAddress.class, () -> webhookUrl); + context.registerService(DataspaceProfileContextRegistry.class, dataspaceProfileContextRegistry); + TypeTransformerRegistry typeTransformerRegistry = mock(); + when(typeTransformerRegistry.forContext(any())).thenReturn(mock()); + context.registerService(TypeTransformerRegistry.class, typeTransformerRegistry); + + when(typeManager.getMapper(any())).thenReturn(mock()); + } + + @Test + void shouldUseInjectedBaseWebhook(DspApiConfigurationV08Extension extension, ServiceExtensionContext context) { + when(context.getConfig()).thenReturn(ConfigFactory.empty()); + + extension.initialize(context); + + verify(dataspaceProfileContextRegistry).registerDefault(argThat(it -> it.name().equals(DATASPACE_PROTOCOL_HTTP) && it.webhook().url().equals(webhookUrl))); + } + + @Test + void shouldRegisterCorrectProtocolWebhooks_whenWellKnownPathsEnabled(ServiceExtensionContext context, ObjectFactory factory) { + when(context.getConfig()).thenReturn(ConfigFactory.fromMap(Map.of( + "edc.dsp.well-known-path.enabled", "true")) + ); + var extension = factory.constructInstance(DspApiConfigurationV08Extension.class); + + extension.initialize(context); + + verify(dataspaceProfileContextRegistry).registerDefault(argThat(it -> it.name().equals(DATASPACE_PROTOCOL_HTTP) && it.webhook().url().equals(webhookUrl))); + } + + @Test + void initialize_shouldRegisterNamespaces(DspApiConfigurationV08Extension extension, ServiceExtensionContext context) { + extension.initialize(context); + + verify(jsonLd).registerNamespace(DCAT_PREFIX, DCAT_SCHEMA, DSP_SCOPE_V_08); + verify(jsonLd).registerNamespace(DCT_PREFIX, DCT_SCHEMA, DSP_SCOPE_V_08); + verify(jsonLd).registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, DSP_SCOPE_V_08); + verify(jsonLd).registerNamespace(VOCAB, EDC_NAMESPACE, DSP_SCOPE_V_08); + verify(jsonLd).registerNamespace(EDC_PREFIX, EDC_NAMESPACE, DSP_SCOPE_V_08); + verify(jsonLd).registerNamespace(ODRL_PREFIX, ODRL_SCHEMA, DSP_SCOPE_V_08); + } + +} diff --git a/edc-extensions/dsp/dsp-http-dispatcher-08/build.gradle.kts b/edc-extensions/dsp/dsp-http-dispatcher-08/build.gradle.kts new file mode 100644 index 0000000000..e8ef99b108 --- /dev/null +++ b/edc-extensions/dsp/dsp-http-dispatcher-08/build.gradle.kts @@ -0,0 +1,27 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(libs.edc.spi.core) + api(libs.dsp.spi.http) +} diff --git a/edc-extensions/dsp/dsp-http-dispatcher-08/src/main/java/org/eclipse/edc/protocol/dsp/http/dispatcher/DspHttpDispatcherV08Extension.java b/edc-extensions/dsp/dsp-http-dispatcher-08/src/main/java/org/eclipse/edc/protocol/dsp/http/dispatcher/DspHttpDispatcherV08Extension.java new file mode 100644 index 0000000000..ef10aa9345 --- /dev/null +++ b/edc-extensions/dsp/dsp-http-dispatcher-08/src/main/java/org/eclipse/edc/protocol/dsp/http/dispatcher/DspHttpDispatcherV08Extension.java @@ -0,0 +1,44 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.http.dispatcher; + +import org.eclipse.edc.protocol.dsp.http.spi.dispatcher.DspHttpRemoteMessageDispatcher; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.message.RemoteMessageDispatcherRegistry; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; + +import static org.eclipse.edc.protocol.dsp.http.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; + +/** + * Registers the message dispatcher for DSP v0.8. + */ +public class DspHttpDispatcherV08Extension implements ServiceExtension { + + @Inject + private RemoteMessageDispatcherRegistry dispatcherRegistry; + @Inject + private DspHttpRemoteMessageDispatcher dispatcher; + + @Override + public void initialize(ServiceExtensionContext context) { + dispatcherRegistry.register(DATASPACE_PROTOCOL_HTTP, dispatcher); + } +} diff --git a/edc-extensions/dsp/dsp-http-dispatcher-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dsp/dsp-http-dispatcher-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..5417f334e5 --- /dev/null +++ b/edc-extensions/dsp/dsp-http-dispatcher-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2025 Cofinity-X +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.edc.protocol.dsp.http.dispatcher.DspHttpDispatcherV08Extension diff --git a/edc-extensions/dsp/dsp-negotiation-08/build.gradle.kts b/edc-extensions/dsp/dsp-negotiation-08/build.gradle.kts new file mode 100644 index 0000000000..1a3c2582d0 --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/build.gradle.kts @@ -0,0 +1,27 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(project(":edc-extensions:dsp:dsp-negotiation-08:dsp-negotiation-http-api-08")) + api(project(":edc-extensions:dsp:dsp-negotiation-08:dsp-negotiation-transform-08")) +} diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/build.gradle.kts b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/build.gradle.kts new file mode 100644 index 0000000000..be54080411 --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/build.gradle.kts @@ -0,0 +1,52 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` + id(libs.plugins.swagger.get().pluginId) +} + +dependencies { + api(libs.dsp.spi) + api(project(":spi:dsp-spi-08")) + api(libs.dsp.spi.http) + api(libs.edc.spi.core) + api(libs.edc.spi.web) + api(libs.edc.spi.controlplane) + api(libs.edc.ext.jsonld) + + implementation(libs.edc.lib.dsp.negotiation.validation) + implementation(libs.edc.lib.dsp.negotiation.http.api) + implementation(libs.edc.lib.jersey.providers) + + + implementation(libs.jakarta.rsApi) + + testImplementation(libs.edc.junit) + testImplementation(testFixtures(libs.edc.core.jersey)) + testImplementation(libs.restAssured) + testImplementation(testFixtures(libs.edc.lib.dsp.negotiation.http.api)) + +} + +edcBuild { + swagger { + apiGroup.set("dsp-api") + } +} diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiV08Extension.java b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiV08Extension.java new file mode 100644 index 0000000000..dea1a7be2d --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiV08Extension.java @@ -0,0 +1,99 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.negotiation.http.api; + +import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationProtocolService; +import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; +import org.eclipse.edc.protocol.dsp.negotiation.http.api.controller.DspNegotiationApiController08; +import org.eclipse.edc.protocol.dsp.negotiation.validation.ContractAgreementMessageValidator; +import org.eclipse.edc.protocol.dsp.negotiation.validation.ContractAgreementVerificationMessageValidator; +import org.eclipse.edc.protocol.dsp.negotiation.validation.ContractNegotiationEventMessageValidator; +import org.eclipse.edc.protocol.dsp.negotiation.validation.ContractNegotiationTerminationMessageValidator; +import org.eclipse.edc.protocol.dsp.negotiation.validation.ContractOfferMessageValidator; +import org.eclipse.edc.protocol.dsp.negotiation.validation.ContractRequestMessageValidator; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; +import org.eclipse.edc.web.spi.WebService; +import org.eclipse.edc.web.spi.configuration.ApiContext; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_AGREEMENT_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_AGREEMENT_VERIFICATION_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_NEGOTIATION_EVENT_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_NEGOTIATION_TERMINATION_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_OFFER_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_REQUEST_MESSAGE_TERM; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; + +/** + * Creates and registers the controller for dataspace protocol v0.8 negotiation requests. + */ +@Extension(value = DspNegotiationApiV08Extension.NAME) +public class DspNegotiationApiV08Extension implements ServiceExtension { + + public static final String NAME = "Dataspace Protocol Negotiation Api v08"; + + @Inject + private WebService webService; + @Inject + private ContractNegotiationProtocolService protocolService; + @Inject + private JsonObjectValidatorRegistry validatorRegistry; + @Inject + private DspRequestHandler dspRequestHandler; + @Inject + private JsonLd jsonLd; + + @Inject + private TypeManager typeManager; + + @Inject + private SingleParticipantContextSupplier participantContextSupplier; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + registerValidators(); + + webService.registerResource(ApiContext.PROTOCOL, new DspNegotiationApiController08(protocolService, dspRequestHandler, participantContextSupplier)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspNegotiationApiController08.class, new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, DSP_SCOPE_V_08)); + } + + private void registerValidators() { + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_REQUEST_MESSAGE_TERM), ContractRequestMessageValidator.instance(DSP_NAMESPACE_V_08)); + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_OFFER_MESSAGE_TERM), ContractOfferMessageValidator.instance(DSP_NAMESPACE_V_08)); + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_NEGOTIATION_EVENT_MESSAGE_TERM), ContractNegotiationEventMessageValidator.instance(DSP_NAMESPACE_V_08)); + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_AGREEMENT_MESSAGE_TERM), ContractAgreementMessageValidator.instance(DSP_NAMESPACE_V_08)); + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_AGREEMENT_VERIFICATION_MESSAGE_TERM), ContractAgreementVerificationMessageValidator.instance(DSP_NAMESPACE_V_08)); + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_NEGOTIATION_TERMINATION_MESSAGE_TERM), ContractNegotiationTerminationMessageValidator.instance(DSP_NAMESPACE_V_08)); + } +} diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/controller/DspNegotiationApiController08.java b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/controller/DspNegotiationApiController08.java new file mode 100644 index 0000000000..35cc3affc6 --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/controller/DspNegotiationApiController08.java @@ -0,0 +1,50 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.negotiation.http.api.controller; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationProtocolService; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; + +import static org.eclipse.edc.protocol.dsp.http.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; +import static org.eclipse.edc.protocol.dsp.negotiation.http.api.NegotiationApiPaths.BASE_PATH; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; + +/** + * Provides consumer and provider endpoints for the contract negotiation according to the http binding + * of the dataspace protocol. + */ +@Consumes({MediaType.APPLICATION_JSON}) +@Produces({MediaType.APPLICATION_JSON}) +@Path(BASE_PATH) +public class DspNegotiationApiController08 extends BaseDspNegotiationApiController { + + + public DspNegotiationApiController08(ContractNegotiationProtocolService protocolService, + DspRequestHandler dspRequestHandler, SingleParticipantContextSupplier participantContextSupplier) { + + super(protocolService, dspRequestHandler, participantContextSupplier, DATASPACE_PROTOCOL_HTTP, DSP_NAMESPACE_V_08); + } + +} diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..e19e030d5f --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.edc.protocol.dsp.negotiation.http.api.DspNegotiationApiV08Extension \ No newline at end of file diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiV08ExtensionTest.java b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiV08ExtensionTest.java new file mode 100644 index 0000000000..b389fe8c89 --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/DspNegotiationApiV08ExtensionTest.java @@ -0,0 +1,62 @@ +/******************************************************************************** + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.negotiation.http.api; + +import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_AGREEMENT_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_AGREEMENT_VERIFICATION_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_NEGOTIATION_EVENT_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_NEGOTIATION_TERMINATION_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_OFFER_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspNegotiationPropertyAndTypeNames.DSPACE_TYPE_CONTRACT_REQUEST_MESSAGE_TERM; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +@ExtendWith(DependencyInjectionExtension.class) +class DspNegotiationApiV08ExtensionTest { + + private final JsonObjectValidatorRegistry validatorRegistry = mock(); + + @BeforeEach + void setUp(ServiceExtensionContext context) { + context.registerService(JsonObjectValidatorRegistry.class, validatorRegistry); + } + + @Test + void shouldRegisterMessageValidators(DspNegotiationApiV08Extension extension, ServiceExtensionContext context) { + extension.initialize(context); + + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_REQUEST_MESSAGE_TERM)), any()); + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_OFFER_MESSAGE_TERM)), any()); + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_NEGOTIATION_EVENT_MESSAGE_TERM)), any()); + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_AGREEMENT_MESSAGE_TERM)), any()); + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_AGREEMENT_VERIFICATION_MESSAGE_TERM)), any()); + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_CONTRACT_NEGOTIATION_TERMINATION_MESSAGE_TERM)), any()); + } +} diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/controller/DspNegotiationApiController08Test.java b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/controller/DspNegotiationApiController08Test.java new file mode 100644 index 0000000000..1de27565b9 --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/negotiation/http/api/controller/DspNegotiationApiController08Test.java @@ -0,0 +1,45 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.negotiation.http.api.controller; + +import org.eclipse.edc.jsonld.spi.JsonLdNamespace; +import org.eclipse.edc.junit.annotations.ApiTest; + +import static org.eclipse.edc.protocol.dsp.negotiation.http.api.NegotiationApiPaths.BASE_PATH; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; + +@ApiTest +class DspNegotiationApiController08Test extends DspNegotiationApiControllerTestBase { + + @Override + protected String basePath() { + return BASE_PATH; + } + + @Override + protected JsonLdNamespace namespace() { + return DSP_NAMESPACE_V_08; + } + + @Override + protected Object controller() { + return new DspNegotiationApiController08(protocolService, dspRequestHandler, participantContextSupplier); + } +} diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/build.gradle.kts b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/build.gradle.kts new file mode 100644 index 0000000000..82ca6d5637 --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/build.gradle.kts @@ -0,0 +1,30 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(libs.edc.spi.core) + api(libs.edc.spi.transform) + api(project(":spi:dsp-spi-08")) + + implementation(libs.edc.lib.dsp.negotiation.transform) +} diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/transform/DspNegotiationTransformV08Extension.java b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/transform/DspNegotiationTransformV08Extension.java new file mode 100644 index 0000000000..536df1b47f --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/negotiation/transform/DspNegotiationTransformV08Extension.java @@ -0,0 +1,92 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.negotiation.transform; + +import jakarta.json.Json; +import org.eclipse.edc.protocol.dsp.negotiation.transform.from.JsonObjectFromContractAgreementMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.from.JsonObjectFromContractAgreementVerificationMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.from.JsonObjectFromContractNegotiationErrorTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.from.JsonObjectFromContractNegotiationEventMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.from.JsonObjectFromContractNegotiationTerminationMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.from.JsonObjectFromContractNegotiationTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.from.JsonObjectFromContractOfferMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.from.JsonObjectFromContractRequestMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.to.JsonObjectToContractAgreementMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.to.JsonObjectToContractAgreementVerificationMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.to.JsonObjectToContractNegotiationAckTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.to.JsonObjectToContractNegotiationEventMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.to.JsonObjectToContractNegotiationTerminationMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.to.JsonObjectToContractOfferMessageTransformer; +import org.eclipse.edc.protocol.dsp.negotiation.transform.to.JsonObjectToContractRequestMessageTransformer; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; + +import java.util.Map; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_TRANSFORMER_CONTEXT_V_08; + +/** + * Provides the transformers for DSP v0.8 negotiation message types via the {@link TypeTransformerRegistry}. + */ +@Extension(value = DspNegotiationTransformV08Extension.NAME) +public class DspNegotiationTransformV08Extension implements ServiceExtension { + + public static final String NAME = "Dataspace Protocol Negotiation Transform v08 Extension"; + + @Inject + private TypeTransformerRegistry registry; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + registerTransformers(); + } + + private void registerTransformers() { + var builderFactory = Json.createBuilderFactory(Map.of()); + + var dspApiTransformerRegistry = registry.forContext(DSP_TRANSFORMER_CONTEXT_V_08); + dspApiTransformerRegistry.register(new JsonObjectFromContractNegotiationErrorTransformer(builderFactory, DSP_NAMESPACE_V_08)); + + dspApiTransformerRegistry.register(new JsonObjectToContractAgreementMessageTransformer(DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectToContractAgreementVerificationMessageTransformer(DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectToContractNegotiationEventMessageTransformer(DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectToContractRequestMessageTransformer(DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectToContractNegotiationTerminationMessageTransformer(DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectToContractOfferMessageTransformer(DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectToContractNegotiationAckTransformer(DSP_NAMESPACE_V_08)); + + dspApiTransformerRegistry.register(new JsonObjectFromContractNegotiationTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectFromContractRequestMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectFromContractOfferMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectFromContractAgreementMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectFromContractAgreementVerificationMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectFromContractNegotiationEventMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspApiTransformerRegistry.register(new JsonObjectFromContractNegotiationTerminationMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + } +} \ No newline at end of file diff --git a/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..ace8e483fe --- /dev/null +++ b/edc-extensions/dsp/dsp-negotiation-08/dsp-negotiation-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.edc.protocol.dsp.negotiation.transform.DspNegotiationTransformV08Extension \ No newline at end of file diff --git a/edc-extensions/dsp/dsp-transfer-process-08/build.gradle.kts b/edc-extensions/dsp/dsp-transfer-process-08/build.gradle.kts new file mode 100644 index 0000000000..0c943c0079 --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/build.gradle.kts @@ -0,0 +1,27 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(project(":edc-extensions:dsp:dsp-transfer-process-08:dsp-transfer-process-http-api-08")) + api(project(":edc-extensions:dsp:dsp-transfer-process-08:dsp-transfer-process-transform-08")) +} diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/build.gradle.kts b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/build.gradle.kts new file mode 100644 index 0000000000..73f806d7b8 --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/build.gradle.kts @@ -0,0 +1,51 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` + id(libs.plugins.swagger.get().pluginId) +} + +dependencies { + api(libs.edc.spi.web) + api(libs.edc.spi.transfer) + api(libs.edc.spi.controlplane) + api(libs.dsp.spi) + api(project(":spi:dsp-spi-08")) + api(libs.dsp.spi.http) + + api(libs.edc.spi.jsonld) + implementation(libs.edc.lib.dsp.transfer.process.validation) + implementation(libs.edc.lib.dsp.transfer.process.http.api) + implementation(libs.edc.lib.jersey.providers) + + implementation(libs.jakarta.rsApi) + + testImplementation(libs.edc.junit) + testImplementation(testFixtures(libs.edc.core.jersey)) + testImplementation(testFixtures(libs.edc.lib.dsp.transfer.http.api)) + + testImplementation(libs.restAssured) +} + +edcBuild { + swagger { + apiGroup.set("dsp-api") + } +} diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiV08Extension.java b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiV08Extension.java new file mode 100644 index 0000000000..ebba94bbbb --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiV08Extension.java @@ -0,0 +1,89 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.transferprocess.http.api; + +import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessProtocolService; +import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; +import org.eclipse.edc.protocol.dsp.transferprocess.http.api.controller.DspTransferProcessApiController08; +import org.eclipse.edc.protocol.dsp.transferprocess.validation.TransferCompletionMessageValidator; +import org.eclipse.edc.protocol.dsp.transferprocess.validation.TransferRequestMessageValidator; +import org.eclipse.edc.protocol.dsp.transferprocess.validation.TransferStartMessageValidator; +import org.eclipse.edc.protocol.dsp.transferprocess.validation.TransferTerminationMessageValidator; +import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; +import org.eclipse.edc.web.spi.WebService; +import org.eclipse.edc.web.spi.configuration.ApiContext; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_COMPLETION_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_REQUEST_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_START_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_TERMINATION_MESSAGE_TERM; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; + +/** + * Creates and registers the controller for dataspace protocol v0.8 transfer process requests. + */ +@Extension(value = DspTransferProcessApiV08Extension.NAME) +public class DspTransferProcessApiV08Extension implements ServiceExtension { + + public static final String NAME = "Dataspace Protocol: TransferProcess API v08 Extension"; + @Inject + private WebService webService; + @Inject + private TransferProcessProtocolService transferProcessProtocolService; + @Inject + private DspRequestHandler dspRequestHandler; + @Inject + private JsonObjectValidatorRegistry validatorRegistry; + @Inject + private DataspaceProfileContextRegistry versionRegistry; + @Inject + private JsonLd jsonLd; + @Inject + private TypeManager typeManager; + + @Inject + private SingleParticipantContextSupplier participantContextSupplier; + + @Override + public void initialize(ServiceExtensionContext context) { + registerValidators(); + + webService.registerResource(ApiContext.PROTOCOL, new DspTransferProcessApiController08(transferProcessProtocolService, dspRequestHandler, participantContextSupplier)); + webService.registerDynamicResource(ApiContext.PROTOCOL, DspTransferProcessApiController08.class, new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, DSP_SCOPE_V_08)); + } + + private void registerValidators() { + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_TRANSFER_REQUEST_MESSAGE_TERM), TransferRequestMessageValidator.instance(DSP_NAMESPACE_V_08)); + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_TRANSFER_START_MESSAGE_TERM), TransferStartMessageValidator.instance(DSP_NAMESPACE_V_08)); + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_TRANSFER_COMPLETION_MESSAGE_TERM), TransferCompletionMessageValidator.instance(DSP_NAMESPACE_V_08)); + validatorRegistry.register(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_TRANSFER_TERMINATION_MESSAGE_TERM), TransferTerminationMessageValidator.instance(DSP_NAMESPACE_V_08)); + } +} diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/controller/DspTransferProcessApiController08.java b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/controller/DspTransferProcessApiController08.java new file mode 100644 index 0000000000..4f6098bcfe --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/controller/DspTransferProcessApiController08.java @@ -0,0 +1,47 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.transferprocess.http.api.controller; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessProtocolService; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; + +import static org.eclipse.edc.protocol.dsp.http.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.transferprocess.http.api.TransferProcessApiPaths.BASE_PATH; + +/** + * Provides the endpoints for receiving messages regarding transfers, like initiating, completing + * and terminating a transfer process. + */ +@Consumes({MediaType.APPLICATION_JSON}) +@Produces({MediaType.APPLICATION_JSON}) +@Path(BASE_PATH) +public class DspTransferProcessApiController08 extends BaseDspTransferProcessApiController { + + public DspTransferProcessApiController08(TransferProcessProtocolService protocolService, DspRequestHandler dspRequestHandler, SingleParticipantContextSupplier participantContextSupplier) { + super(protocolService, dspRequestHandler, participantContextSupplier, DATASPACE_PROTOCOL_HTTP, DSP_NAMESPACE_V_08); + } + +} diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..5620d7615e --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.edc.protocol.dsp.transferprocess.http.api.DspTransferProcessApiV08Extension diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiV08ExtensionTest.java b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiV08ExtensionTest.java new file mode 100644 index 0000000000..f61311bc64 --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/DspTransferProcessApiV08ExtensionTest.java @@ -0,0 +1,59 @@ +/******************************************************************************** + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.transferprocess.http.api; + +import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_COMPLETION_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_REQUEST_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_START_MESSAGE_TERM; +import static org.eclipse.edc.protocol.dsp.spi.type.DspTransferProcessPropertyAndTypeNames.DSPACE_TYPE_TRANSFER_TERMINATION_MESSAGE_TERM; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +@ExtendWith(DependencyInjectionExtension.class) +class DspTransferProcessApiV08ExtensionTest { + + private final JsonObjectValidatorRegistry validatorRegistry = mock(); + + @BeforeEach + void setUp(ServiceExtensionContext context) { + context.registerService(JsonObjectValidatorRegistry.class, validatorRegistry); + } + + @Test + void shouldRegisterMessageValidators(DspTransferProcessApiV08Extension extension, ServiceExtensionContext context) { + extension.initialize(context); + + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_TRANSFER_REQUEST_MESSAGE_TERM)), any()); + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_TRANSFER_START_MESSAGE_TERM)), any()); + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_TRANSFER_COMPLETION_MESSAGE_TERM)), any()); + verify(validatorRegistry).register(eq(DSP_NAMESPACE_V_08.toIri(DSPACE_TYPE_TRANSFER_TERMINATION_MESSAGE_TERM)), any()); + } + +} diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/controller/DspTransferProcessApiController08Test.java b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/controller/DspTransferProcessApiController08Test.java new file mode 100644 index 0000000000..7aa26c2070 --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-http-api-08/src/test/java/org/eclipse/edc/protocol/dsp/transferprocess/http/api/controller/DspTransferProcessApiController08Test.java @@ -0,0 +1,45 @@ +/******************************************************************************** + * Copyright (c) 2025 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.transferprocess.http.api.controller; + +import org.eclipse.edc.jsonld.spi.JsonLdNamespace; +import org.eclipse.edc.junit.annotations.ApiTest; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.transferprocess.http.api.TransferProcessApiPaths.BASE_PATH; + +@ApiTest +class DspTransferProcessApiController08Test extends DspTransferProcessApiControllerBaseTest { + + @Override + protected String basePath() { + return BASE_PATH; + } + + @Override + protected JsonLdNamespace namespace() { + return DSP_NAMESPACE_V_08; + } + + @Override + protected Object controller() { + return new DspTransferProcessApiController08(protocolService, dspRequestHandler, participantContextSupplier); + } +} diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/build.gradle.kts b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/build.gradle.kts new file mode 100644 index 0000000000..b8916a92a8 --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/build.gradle.kts @@ -0,0 +1,36 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(libs.edc.spi.transfer) + api(libs.edc.spi.transform) + api(libs.edc.ext.jsonld) + api(libs.dsp.spi) + api(project(":spi:dsp-spi-08")) + api(libs.dsp.spi.http) + implementation(libs.edc.lib.transform) + implementation(libs.edc.lib.dsp.transfer.process.transform) + + testImplementation(libs.edc.ext.jsonld) + testImplementation(libs.edc.junit) +} diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transform/DspTransferProcessTransformV08Extension.java b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transform/DspTransferProcessTransformV08Extension.java new file mode 100644 index 0000000000..6f8c7c5b03 --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/src/main/java/org/eclipse/edc/protocol/dsp/transferprocess/transform/DspTransferProcessTransformV08Extension.java @@ -0,0 +1,94 @@ +/******************************************************************************** + * Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.transferprocess.transform; + +import jakarta.json.Json; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.from.JsonObjectFromTransferCompletionMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.from.JsonObjectFromTransferErrorTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.from.JsonObjectFromTransferProcessTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.from.JsonObjectFromTransferRequestMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.from.JsonObjectFromTransferStartMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.from.JsonObjectFromTransferSuspensionMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.from.JsonObjectFromTransferTerminationMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.to.JsonObjectToTransferCompletionMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.to.JsonObjectToTransferProcessAckTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.to.JsonObjectToTransferRequestMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.to.JsonObjectToTransferStartMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.to.JsonObjectToTransferSuspensionMessageTransformer; +import org.eclipse.edc.protocol.dsp.transferprocess.transform.type.to.JsonObjectToTransferTerminationMessageTransformer; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; + +import java.util.Map; + +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_TRANSFORMER_CONTEXT_V_08; +import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; + +/** + * Provides the transformers for DSP v0.8 transferprocess message types via the {@link TypeTransformerRegistry}. + */ +@Extension(value = DspTransferProcessTransformV08Extension.NAME) +public class DspTransferProcessTransformV08Extension implements ServiceExtension { + + public static final String NAME = "Dataspace Protocol Transfer Process Transform v08 Extension"; + + @Inject + private TypeTransformerRegistry registry; + + @Inject + private TypeManager typeManager; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + registerTransformers(); + } + + private void registerTransformers() { + var builderFactory = Json.createBuilderFactory(Map.of()); + + var dspRegistry = registry.forContext(DSP_TRANSFORMER_CONTEXT_V_08); + + dspRegistry.register(new JsonObjectFromTransferErrorTransformer(builderFactory, DSP_NAMESPACE_V_08)); + + dspRegistry.register(new JsonObjectToTransferRequestMessageTransformer(DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectToTransferCompletionMessageTransformer(DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectToTransferStartMessageTransformer(DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectToTransferTerminationMessageTransformer(DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectToTransferProcessAckTransformer(DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectToTransferSuspensionMessageTransformer(typeManager, JSON_LD, DSP_NAMESPACE_V_08)); + + dspRegistry.register(new JsonObjectFromTransferProcessTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectFromTransferRequestMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectFromTransferStartMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectFromTransferCompletionMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectFromTransferTerminationMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + dspRegistry.register(new JsonObjectFromTransferSuspensionMessageTransformer(builderFactory, DSP_NAMESPACE_V_08)); + } +} \ No newline at end of file diff --git a/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..9111788bc7 --- /dev/null +++ b/edc-extensions/dsp/dsp-transfer-process-08/dsp-transfer-process-transform-08/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.edc.protocol.dsp.transferprocess.transform.DspTransferProcessTransformV08Extension \ No newline at end of file diff --git a/edc-extensions/token-interceptor/build.gradle.kts b/edc-extensions/token-interceptor/build.gradle.kts index c73c2c068f..023624d5de 100644 --- a/edc-extensions/token-interceptor/build.gradle.kts +++ b/edc-extensions/token-interceptor/build.gradle.kts @@ -29,6 +29,7 @@ dependencies { implementation(libs.edc.lib.dsp.catalog.http.api) implementation(libs.edc.lib.dsp.negotiation.http.api) implementation(libs.edc.lib.dsp.transfer.http.api) + implementation(project(":spi:dsp-spi-08")) testImplementation(libs.edc.junit) } diff --git a/edc-extensions/token-interceptor/src/main/java/org/eclipse/tractusx/edc/interceptor/OkHttpInterceptor.java b/edc-extensions/token-interceptor/src/main/java/org/eclipse/tractusx/edc/interceptor/OkHttpInterceptor.java index 9be6a7ae35..f4c611eca1 100644 --- a/edc-extensions/token-interceptor/src/main/java/org/eclipse/tractusx/edc/interceptor/OkHttpInterceptor.java +++ b/edc-extensions/token-interceptor/src/main/java/org/eclipse/tractusx/edc/interceptor/OkHttpInterceptor.java @@ -36,9 +36,9 @@ import java.nio.charset.StandardCharsets; import java.util.List; -import static org.eclipse.edc.jsonld.spi.Namespaces.DSPACE_SCHEMA; import static org.eclipse.edc.protocol.dsp.catalog.http.api.CatalogApiPaths.CATALOG_REQUEST; import static org.eclipse.edc.protocol.dsp.catalog.http.api.CatalogApiPaths.DATASET_REQUEST; +import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSPACE_SCHEMA; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.V_2025_1_PATH; public class OkHttpInterceptor implements Interceptor { diff --git a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java new file mode 100644 index 0000000000..2f20d0f379 --- /dev/null +++ b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java @@ -0,0 +1,242 @@ +/******************************************************************************** + * Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.tests.catalog; + +import org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition; +import org.eclipse.edc.connector.controlplane.policy.spi.store.PolicyDefinitionStore; +import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.junit.annotations.EndToEndTest; +import org.eclipse.edc.junit.extensions.RuntimeExtension; +import org.eclipse.edc.policy.model.Action; +import org.eclipse.edc.policy.model.AtomicConstraint; +import org.eclipse.edc.policy.model.LiteralExpression; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.policy.model.Permission; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.policy.model.PolicyType; +import org.eclipse.tractusx.edc.tests.participant.TransferParticipant; +import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.edc.connector.controlplane.test.system.utils.PolicyFixtures.noConstraintPolicy; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_NS; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; +import static org.eclipse.tractusx.edc.tests.helpers.CatalogHelperFunctions.getDatasetAssetId; +import static org.eclipse.tractusx.edc.tests.helpers.CatalogHelperFunctions.getDatasetPolicies; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnGroupPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; +import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; + +@EndToEndTest +public class CatalogTestDspV08 { + + private static final TransferParticipant CONSUMER = TransferParticipant.Builder.newInstance() + .name(CONSUMER_NAME) + .id(CONSUMER_DID) + .bpn(CONSUMER_BPN) + .protocol(DSP_08) + .build(); + + + private static final TransferParticipant PROVIDER = TransferParticipant.Builder.newInstance() + .name(PROVIDER_NAME) + .id(PROVIDER_DID) + .bpn(PROVIDER_BPN) + .protocol(DSP_08) + .build(); + + @RegisterExtension + @Order(0) + private static final PostgresExtension POSTGRES = new PostgresExtension(CONSUMER.getName(), PROVIDER.getName()); + + @RegisterExtension + private static final RuntimeExtension CONSUMER_RUNTIME = pgRuntime(CONSUMER, POSTGRES); + + @RegisterExtension + private static final RuntimeExtension PROVIDER_RUNTIME = pgRuntime(PROVIDER, POSTGRES); + + @BeforeEach + void setup() { + CONSUMER.setJsonLd(CONSUMER_RUNTIME.getService(JsonLd.class)); + } + + @Test + @DisplayName("Consumer gets catalog from the provider. No constraints.") + void requestCatalog_fulfillsPolicy_shouldReturnOffer() { + // arrange + PROVIDER.createAsset("test-asset"); + var ap = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var cp = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + PROVIDER.createContractDefinition("test-asset", "test-def", ap, cp); + + // act + var catalog = CONSUMER.getCatalogDatasets(PROVIDER); + + // assert + assertThat(catalog).isNotEmpty() + .hasSize(1) + .allSatisfy(co -> { + assertThat(getDatasetAssetId(co.asJsonObject())).isEqualTo("test-asset"); + }); + + } + + @Test + @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the legacy BPN validation)") + void requestCatalog_filteredByBpnLegacy_shouldReject() { + var onlyConsumerPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAAAA", "BPNL123456ABCDEF", CONSUMER.getBpn()); + var onlyDiogenesPolicy = bpnPolicy("BPNLAAAAAAAAAABC"); + + var onlyConsumerId = PROVIDER.createPolicyDefinition(onlyConsumerPolicy); + var onlyDiogenesId = PROVIDER.createPolicyDefinition(onlyDiogenesPolicy); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + + PROVIDER.createAsset("test-asset1"); + PROVIDER.createAsset("test-asset2"); + PROVIDER.createAsset("test-asset3"); + + PROVIDER.createContractDefinition("test-asset1", "def1", noConstraintPolicyId, noConstraintPolicyId); + PROVIDER.createContractDefinition("test-asset2", "def2", onlyConsumerId, noConstraintPolicyId); + PROVIDER.createContractDefinition("test-asset3", "def3", onlyDiogenesId, noConstraintPolicyId); + + + // act + var catalog = CONSUMER.getCatalogDatasets(PROVIDER); + assertThat(catalog).hasSize(2); + } + + + @Test + @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the legacy BPN validation)") + void requestCatalog_filteredByBpnLegacy_WithNamespace_shouldReject() { + + var onlyConsumerPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAAAA", "BPNL123456ABCDEF", CONSUMER.getBpn()); + var onlyDiogenesPolicy = frameworkPolicy( + Map.of(CX_POLICY_2025_09_NS + "BusinessPartnerNumber", "BPNLAAAAAAAAAAAB"), + CX_POLICY_2025_09_NS + "access", + Operator.IS_ANY_OF); + + var onlyConsumerId = PROVIDER.createPolicyDefinition(onlyConsumerPolicy); + var onlyDiogenesId = PROVIDER.createPolicyDefinition(onlyDiogenesPolicy); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + + PROVIDER.createAsset("test-asset1"); + PROVIDER.createAsset("test-asset2"); + PROVIDER.createAsset("test-asset3"); + + PROVIDER.createContractDefinition("test-asset1", "def1", noConstraintPolicyId, noConstraintPolicyId); + PROVIDER.createContractDefinition("test-asset2", "def2", onlyConsumerId, noConstraintPolicyId); + PROVIDER.createContractDefinition("test-asset3", "def3", onlyDiogenesId, noConstraintPolicyId); + + + // act + var catalog = CONSUMER.getCatalogDatasets(PROVIDER); + assertThat(catalog).hasSize(2); + } + + @Test + @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the new BPN validation)") + void requestCatalog_filteredByBpn_shouldReject() { + + var mustBeGreekPhilosopher = bpnGroupPolicy(Operator.IS_ANY_OF, "greek_customer", "philosopher"); + var mustBeGreekMathematician = bpnGroupPolicy(Operator.IS_NONE_OF, "greek_customer", "mathematician"); + + + PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "greek_customer", "philosopher"); + var philosopherId = PROVIDER.createPolicyDefinition(mustBeGreekPhilosopher); + var mathId = PROVIDER.createPolicyDefinition(mustBeGreekMathematician); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + + PROVIDER.createAsset("test-asset1"); + PROVIDER.createAsset("test-asset2"); + PROVIDER.createAsset("test-asset3"); + + PROVIDER.createContractDefinition("test-asset1", "def1", noConstraintPolicyId, noConstraintPolicyId); + PROVIDER.createContractDefinition("test-asset2", "def2", philosopherId, noConstraintPolicyId); + PROVIDER.createContractDefinition("test-asset3", "def3", mathId, noConstraintPolicyId); + + + // act + var catalog = CONSUMER.getCatalogDatasets(PROVIDER); + assertThat(catalog).hasSize(2); + } + + @Test + @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the legacy CX policy)") + void requestCatalog_filteredByBpn_UsingLegacyCxPolicy_shouldReject() { + PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "greek_customer", "philosopher"); + var id = "philosopher-policy"; + PROVIDER_RUNTIME.getService(PolicyDefinitionStore.class) + .create(buildLegacyPolicyDefinition(id, "greek_customer", Operator.EQ, "philosopher")); + + PROVIDER.createAsset("test-asset1"); + PROVIDER.createAsset("test-asset2"); + + PROVIDER.createContractDefinition("test-asset2", "def1", id, id); + + // act + var catalog = CONSUMER.getCatalogDatasets(PROVIDER); + assertThat(catalog).hasSize(1) + .allSatisfy(cd -> { + assertThat(getDatasetAssetId(cd.asJsonObject())).isEqualTo("test-asset2"); + assertThat(getDatasetPolicies(cd)).hasSize(1); + }); + } + + private PolicyDefinition buildLegacyPolicyDefinition(String id, String leftExpression, Operator operator, Object rightExpression) { + var action = Action.Builder.newInstance() + .type(CX_POLICY_NS + "access") + .build(); + + var constraint = AtomicConstraint.Builder.newInstance() + .leftExpression(new LiteralExpression(leftExpression)) + .operator(operator) + .rightExpression(new LiteralExpression(rightExpression)) + .build(); + + var policy = Policy.Builder.newInstance() + .type(PolicyType.SET) + .permission(Permission.Builder.newInstance() + .action(action) + .constraint(constraint) + .build()) + .build(); + + return PolicyDefinition.Builder.newInstance() + .id(id) + .policy(policy) + .build(); + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6559fc46c2..359ee382b5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -73,6 +73,7 @@ edc-boot = { module = "org.eclipse.edc:boot", version.ref = "edc" } edc-vault-hashicorp = { module = "org.eclipse.edc:vault-hashicorp", version.ref = "edc" } edc-core-connector = { module = "org.eclipse.edc:connector-core", version.ref = "edc" } edc-core-controlplane = { module = "org.eclipse.edc:control-plane-core", version.ref = "edc" } +edc-transform-controlplane = { module = "org.eclipse.edc:control-plane-transform", version.ref = "edc" } edc-core-edrstore = { module = "org.eclipse.edc:edr-store-core", version.ref = "edc" } edc-core-jersey = { module = "org.eclipse.edc:jersey-core", version.ref = "edc" } edc-core-participant-context-config = { module = "org.eclipse.edc:participant-context-config-core", version.ref = "edc" } @@ -115,8 +116,15 @@ edc-lib-util = { module = "org.eclipse.edc:util-lib", version.ref = "edc" } edc-lib-validator = { module = "org.eclipse.edc:validator-lib", version.ref = "edc" } edc-lib-sql = { module = "org.eclipse.edc:sql-lib", version.ref = "edc" } edc-lib-dsp-catalog-http-api= { module = "org.eclipse.edc:dsp-catalog-http-api-lib", version.ref = "edc" } +edc-lib-dsp-catalog-validation= { module = "org.eclipse.edc:dsp-catalog-validation-lib", version.ref = "edc" } +edc-lib-dsp-catalog-transform= { module = "org.eclipse.edc:dsp-catalog-transform-lib", version.ref = "edc" } +edc-lib-dsp-negotiation-validation= { module = "org.eclipse.edc:dsp-negotiation-validation-lib", version.ref = "edc" } edc-lib-dsp-negotiation-http-api= { module = "org.eclipse.edc:dsp-negotiation-http-api-lib", version.ref = "edc" } +edc-lib-dsp-negotiation-transform= { module = "org.eclipse.edc:dsp-negotiation-transform-lib", version.ref = "edc" } edc-lib-dsp-transfer-http-api= { module = "org.eclipse.edc:dsp-transfer-process-http-api-lib", version.ref = "edc" } +edc-lib-dsp-transfer-process-validation= { module = "org.eclipse.edc:dsp-transfer-process-validation-lib", version.ref = "edc" } +edc-lib-dsp-transfer-process-http-api= { module = "org.eclipse.edc:dsp-transfer-process-http-api-lib", version.ref = "edc" } +edc-lib-dsp-transfer-process-transform= { module = "org.eclipse.edc:dsp-transfer-process-transform-lib", version.ref = "edc" } edc-lib-dcp = { module = "org.eclipse.edc:decentralized-claims-lib", version.ref = "edc" } # implementations @@ -170,8 +178,8 @@ tck-extension = { module = "org.eclipse.edc:tck-extension", version.ref = "edc-n # DSP libraries dsp-spi-http = { module = "org.eclipse.edc:dsp-http-spi", version.ref = "edc" } -dsp-spi-v08 = { module = "org.eclipse.edc:dsp-spi-08", version.ref = "edc" } dsp-spi-v2025 = { module = "org.eclipse.edc:dsp-spi-2025", version.ref = "edc" } +dsp-spi= { module = "org.eclipse.edc:dsp-spi", version.ref = "edc" } ## IH for testing diff --git a/settings.gradle.kts b/settings.gradle.kts index 9998cdc86f..bcf23f3194 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -55,6 +55,7 @@ include(":spi:bdrs-client-spi") include(":spi:dataflow-spi") include(":spi:dcp-spi") include(":spi:did-document-service-spi") +include(":spi:dsp-spi-08") // core modules @@ -86,6 +87,17 @@ include(":edc-extensions:dcp:cx-dcp") include(":edc-extensions:dcp:tx-dcp") include(":edc-extensions:dcp:tx-dcp-sts-div") include(":edc-extensions:dcp:verifiable-presentation-cache") +include(":edc-extensions:dsp:dsp-catalog-08") +include(":edc-extensions:dsp:dsp-catalog-08:dsp-catalog-http-api-08") +include(":edc-extensions:dsp:dsp-catalog-08:dsp-catalog-transform-08") +include(":edc-extensions:dsp:dsp-http-api-configuration-08") +include(":edc-extensions:dsp:dsp-http-dispatcher-08") +include(":edc-extensions:dsp:dsp-negotiation-08") +include(":edc-extensions:dsp:dsp-negotiation-08:dsp-negotiation-http-api-08") +include(":edc-extensions:dsp:dsp-negotiation-08:dsp-negotiation-transform-08") +include(":edc-extensions:dsp:dsp-transfer-process-08") +include(":edc-extensions:dsp:dsp-transfer-process-08:dsp-transfer-process-http-api-08") +include(":edc-extensions:dsp:dsp-transfer-process-08:dsp-transfer-process-transform-08") include(":edc-extensions:data-flow-properties-provider") include(":edc-extensions:validators:empty-asset-selector") include(":edc-extensions:log4j2-monitor") diff --git a/spi/dsp-spi-08/build.gradle.kts b/spi/dsp-spi-08/build.gradle.kts new file mode 100644 index 0000000000..c9345c160b --- /dev/null +++ b/spi/dsp-spi-08/build.gradle.kts @@ -0,0 +1,27 @@ +/******************************************************************************** + * Copyright (c) 2025 Metaform Systems Inc. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `java-library` +} + +dependencies { + api(libs.dsp.spi) + implementation(libs.edc.ext.jsonld) +} \ No newline at end of file diff --git a/spi/dsp-spi-08/src/main/java/org/eclipse/edc/protocol/dsp/spi/type/Dsp08Constants.java b/spi/dsp-spi-08/src/main/java/org/eclipse/edc/protocol/dsp/spi/type/Dsp08Constants.java new file mode 100644 index 0000000000..964387122a --- /dev/null +++ b/spi/dsp-spi-08/src/main/java/org/eclipse/edc/protocol/dsp/spi/type/Dsp08Constants.java @@ -0,0 +1,42 @@ +/******************************************************************************** + * Copyright (c) 2025 Metaform Systems Inc. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.edc.protocol.dsp.spi.type; + +import org.eclipse.edc.jsonld.spi.JsonLdNamespace; +import org.eclipse.edc.protocol.spi.ProtocolVersion; + +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_CONTEXT_SEPARATOR; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_HTTPS_BINDING; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_SCOPE; +import static org.eclipse.edc.protocol.dsp.spi.type.DspConstants.DSP_TRANSFORMER_CONTEXT; + +public interface Dsp08Constants { + + String DSPACE_SCHEMA = "https://w3id.org/dspace/v0.8/"; + String V_08_VERSION = "v0.8"; + String V_08_PATH = "/"; + ProtocolVersion V_08 = new ProtocolVersion(V_08_VERSION, V_08_PATH, DSP_HTTPS_BINDING); + + String DSP_SCOPE_V_08 = DSP_SCOPE + DSP_CONTEXT_SEPARATOR + V_08_VERSION; + + String DSP_TRANSFORMER_CONTEXT_V_08 = DSP_TRANSFORMER_CONTEXT + DSP_CONTEXT_SEPARATOR + V_08_VERSION; + + JsonLdNamespace DSP_NAMESPACE_V_08 = new JsonLdNamespace(DSPACE_SCHEMA); +} From 1e2fc3427eba131b0eae35d24326bd3a6c45e3dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 20:46:54 +0200 Subject: [PATCH 018/259] chore(deps): bump com.azure:azure-storage-blob from 12.33.2 to 12.33.3 (#2739) Bumps [com.azure:azure-storage-blob](https://github.com/Azure/azure-sdk-for-java) from 12.33.2 to 12.33.3. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/com.azure+azure-storage-blob_12.33.2...com.azure+azure-storage-blob_12.33.3) --- updated-dependencies: - dependency-name: com.azure:azure-storage-blob dependency-version: 12.33.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 359ee382b5..faff287d8b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ edc-build = "1.1.6" allure = "2.33.0" awaitility = "4.3.0" aws = "2.42.27" -azure-storage-blob = "12.33.2" +azure-storage-blob = "12.33.3" bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" From fac7316b2c3916d60b40f6aa731628430dcba2c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 20:47:11 +0200 Subject: [PATCH 019/259] chore(deps): bump io.qameta.allure:allure-junit5 from 2.33.0 to 2.34.0 (#2738) Bumps [io.qameta.allure:allure-junit5](https://github.com/allure-framework/allure-java) from 2.33.0 to 2.34.0. - [Release notes](https://github.com/allure-framework/allure-java/releases) - [Commits](https://github.com/allure-framework/allure-java/compare/2.33.0...2.34.0) --- updated-dependencies: - dependency-name: io.qameta.allure:allure-junit5 dependency-version: 2.34.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index faff287d8b..9a78bb059d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ format.version = "1.1" edc = "0.15.1" edc-next = "0.16.0" edc-build = "1.1.6" -allure = "2.33.0" +allure = "2.34.0" awaitility = "4.3.0" aws = "2.42.27" azure-storage-blob = "12.33.3" From e3eb7b048a527d85434259b461b353fc116da296 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 20:48:46 +0200 Subject: [PATCH 020/259] chore(deps): bump io.swagger.core.v3.swagger-gradle-plugin (#2735) Bumps io.swagger.core.v3.swagger-gradle-plugin from 2.2.45 to 2.2.47. --- updated-dependencies: - dependency-name: io.swagger.core.v3.swagger-gradle-plugin dependency-version: 2.2.47 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9a78bb059d..8d5fcf3aae 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -250,5 +250,5 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } shadow = { id = "com.gradleup.shadow", version = "9.4.1" } -swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.45" } +swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.47" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From 329a7f67b6ef4292725806879f27759d07867270 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 20:49:06 +0200 Subject: [PATCH 021/259] chore(deps): bump com.github.dasniko:testcontainers-keycloak (#2734) Bumps [com.github.dasniko:testcontainers-keycloak](https://github.com/dasniko/testcontainers-keycloak) from 4.1.1 to 4.2.0. - [Release notes](https://github.com/dasniko/testcontainers-keycloak/releases) - [Commits](https://github.com/dasniko/testcontainers-keycloak/compare/v4.1.1...v4.2.0) --- updated-dependencies: - dependency-name: com.github.dasniko:testcontainers-keycloak dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8d5fcf3aae..b2002236c3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ postgres = "42.7.10" restAssured = "6.0.0" rsApi = "4.0.0" testcontainers = "2.0.4" -testcontainers-keycloak = "4.1.1" +testcontainers-keycloak = "4.2.0" titanium = "1.7.0" log4j2 = "2.25.4" wiremock = "3.13.2" From 3f0e35d077961baa11fe7a8a9b6ad4fb577deb3d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 20:49:19 +0200 Subject: [PATCH 022/259] chore(deps): bump trufflesecurity/trufflehog from 3.94.2 to 3.94.3 (#2732) Bumps [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) from 3.94.2 to 3.94.3. - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/6bd2d14f7a4bc1e569fa3550efa7ec632a4fa67b...47e7b7cd74f578e1e3145d48f669f22fd1330ca6) --- updated-dependencies: - dependency-name: trufflesecurity/trufflehog dependency-version: 3.94.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/secrets-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 6eb33dfbb5..668f09c495 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -46,7 +46,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@6bd2d14f7a4bc1e569fa3550efa7ec632a4fa67b + uses: trufflesecurity/trufflehog@47e7b7cd74f578e1e3145d48f669f22fd1330ca6 continue-on-error: true with: path: ./ # Scan the entire repository From 16df4dfbf57539fbc7f8c425d5c632301be0b265 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 20:59:45 +0200 Subject: [PATCH 023/259] chore(deps): bump aws from 2.42.27 to 2.42.32 (#2736) Bumps `aws` from 2.42.27 to 2.42.32. Updates `software.amazon.awssdk:s3` from 2.42.27 to 2.42.32 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.42.27 to 2.42.32 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.42.32 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.42.32 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b2002236c3..c65fd6eabd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.1.6" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.42.27" +aws = "2.42.33" azure-storage-blob = "12.33.3" bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" From 550a9ee821ef329e03ee756f2f97a55f8c763cb4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 21:01:44 +0200 Subject: [PATCH 024/259] chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 from 2.25.0-alpha to 2.27.0-alpha-SNAPSHOT (#2737) * chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 Bumps io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 from 2.25.0-alpha to 2.27.0-alpha-SNAPSHOT. --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 dependency-version: 2.27.0-alpha-SNAPSHOT dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 to 2.26.1-alpha --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: AndrYurk --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c65fd6eabd..87f06f413c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ nimbus = "10.9" okhttp = "5.3.2" opentelemetry = "2.26.1" opentelemetry-instrumentation = "2.26.1" -opentelemetry-log4j-appender = "2.25.0-alpha" +opentelemetry-log4j-appender = "2.26.1-alpha" postgres = "42.7.10" restAssured = "6.0.0" rsApi = "4.0.0" From b6f9437a8901957c15f225543b5dbbe52bb85e55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 13:01:53 +0200 Subject: [PATCH 025/259] chore(deps): bump actions/github-script from 7 to 9 (#2731) Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 9. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v7...v9) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: '9' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index 74b0057c5b..56c4cac644 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Copy labels from linked issue to PR - uses: actions/github-script@v7 + uses: actions/github-script@v9 with: script: | const CLOSING_KEYWORDS = /\b(?:closes?|fixes?|resolves?)\s+#(\d+)\b/gi; diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c90f1341af..7d87232216 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -209,7 +209,7 @@ jobs: steps: - uses: actions/checkout@v6 - - uses: actions/github-script@v8 + - uses: actions/github-script@v9 with: script: | const { owner, repo } = context.repo; From c6ba7282d13484e1a9d4fce7528c2e1348658102 Mon Sep 17 00:00:00 2001 From: pratapipatelbcone Date: Tue, 14 Apr 2026 17:13:42 +0530 Subject: [PATCH 026/259] feat: Rename IATP to dcp (#2684) --- charts/tractusx-connector-memory/README.md | 32 +++++++++---------- .../README.md.gotmpl | 12 +++---- .../templates/deployment-runtime.yaml | 30 ++++++++--------- charts/tractusx-connector-memory/values.yaml | 2 +- charts/tractusx-connector/README.md | 32 +++++++++---------- charts/tractusx-connector/README.md.gotmpl | 12 +++---- .../templates/deployment-controlplane.yaml | 30 ++++++++--------- .../templates/deployment-dataplane.yaml | 14 ++++---- charts/tractusx-connector/values.yaml | 2 +- docs/development/mock-edc.md | 2 +- .../identity/mapper/BdrsClientExtension.java | 6 ++-- .../edc/identity/mapper/BdrsClientImpl.java | 4 +-- .../mapper/BdrsClientImplExtensionTest.java | 4 +-- .../dcp/cx/CxDcpDefaultScopeExtension.java | 6 ++-- .../cx/scope/CxCredentialScopeExtractor.java | 2 +- .../cx/CxDcpDefaultScopeExtensionTest.java | 10 +++--- .../scope/CxCredentialScopeExtractorTest.java | 2 +- .../sts/div/DivSecureTokenServiceTest.java | 2 +- .../DcpDefaultScopeExtension.java} | 20 ++++++------ .../scope/DefaultScopeExtractor.java | 2 +- ...rg.eclipse.edc.spi.system.ServiceExtension | 2 +- .../DcpDefaultScopeExtensionTest.java} | 18 +++++------ .../scope/DefaultScopeExtractorTest.java | 2 +- .../tests/fixtures/DcpHelperFunctions.java | 6 ++-- .../tests/fixtures/RemoteParticipant.java | 10 +++--- .../fixtures/RemoteParticipantExtension.java | 6 ++-- .../tests/fixtures/Runtimes.java | 2 +- .../tests/transfer/TransferEndToEndTest.java | 14 ++++---- .../helm/tractusx-connector-memory-test.yaml | 2 +- .../helm/tractusx-connector-test.yaml | 2 +- ...tpParticipant.java => DcpParticipant.java} | 10 +++--- ...e.java => TractusxDcpParticipantBase.java} | 8 ++--- .../participant/TractusxParticipantBase.java | 2 +- .../transfer/test/RuntimeConfig.java | 2 +- .../tck/dcp/DcpPresentationFlowTest.java | 8 ++--- .../build.gradle.kts | 6 ++-- .../AbstractDcpConsumerPullTest.java} | 6 ++-- .../tests/transfer/CredentialSpoofTest.java | 30 ++++++++--------- .../tests/transfer/DivConsumerPullTest.java | 18 +++++------ .../transfer/IdentityExtractionTest.java | 8 ++--- .../tests/transfer/StsConsumerPullTest.java | 20 ++++++------ .../dcp}/dispatchers/DivDispatcher.java | 2 +- .../transfer/dcp}/harness/StatusList2021.java | 2 +- .../transfer/dcp}/harness/StsParticipant.java | 6 ++-- .../dcp}/runtime/CredentialWiper.java | 2 +- .../DcpParticipantRuntimeExtension.java} | 6 ++-- .../tests/transfer/dcp}/runtime/Runtimes.java | 12 +++---- .../extension/BdrsServerExtension.java | 2 +- .../extension/DidServerExtension.java | 0 .../tck/dsp/EdcCompatibilityPostgresTest.java | 2 +- .../tokenrefresh/e2e/RuntimeConfig.java | 2 +- .../dcp-extensions}/build.gradle.kts | 0 .../edc/dcp}/CredentialsJsonLdExtension.java | 2 +- .../edc/dcp}/ih/IdentityHubExtension.java | 2 +- .../ih/TxScopeToCriterionTransformer.java | 2 +- ...rg.eclipse.edc.spi.system.ServiceExtension | 4 +-- .../resources/cx-credentials-context.json | 0 .../runtime-memory-dcp-div-ih}/README.md | 0 .../build.gradle.kts | 2 +- .../runtime-memory-dcp-ih}/README.md | 0 .../runtime-memory-dcp-ih}/build.gradle.kts | 8 ++++- .../runtime-memory-sts/README.md | 0 .../runtime-memory-sts/build.gradle.kts | 2 +- settings.gradle.kts | 10 +++--- ...IatpConstants.java => TxDcpConstants.java} | 2 +- 65 files changed, 242 insertions(+), 236 deletions(-) rename edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/{iatp/IatpDefaultScopeExtension.java => dcp/DcpDefaultScopeExtension.java} (79%) rename edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/{iatp => dcp}/scope/DefaultScopeExtractor.java (98%) rename edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/{iatp/IatpDefaultScopeExtensionTest.java => dcp/DcpDefaultScopeExtensionTest.java} (89%) rename edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/{iatp => dcp}/scope/DefaultScopeExtractorTest.java (98%) rename edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/{IatpParticipant.java => DcpParticipant.java} (96%) rename edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/{TractusxIatpParticipantBase.java => TractusxDcpParticipantBase.java} (91%) rename edc-tests/e2e/{iatp-tests => dcp-tests}/build.gradle.kts (89%) rename edc-tests/e2e/{iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractIatpConsumerPullTest.java => dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java} (98%) rename edc-tests/e2e/{iatp-tests => dcp-tests}/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java (88%) rename edc-tests/e2e/{iatp-tests => dcp-tests}/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java (93%) rename edc-tests/e2e/{iatp-tests => dcp-tests}/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java (93%) rename edc-tests/e2e/{iatp-tests => dcp-tests}/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java (85%) rename edc-tests/e2e/{iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp => dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp}/dispatchers/DivDispatcher.java (98%) rename edc-tests/e2e/{iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp => dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp}/harness/StatusList2021.java (97%) rename edc-tests/e2e/{iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp => dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp}/harness/StsParticipant.java (95%) rename edc-tests/e2e/{iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp => dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp}/runtime/CredentialWiper.java (96%) rename edc-tests/e2e/{iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/IatpParticipantRuntimeExtension.java => dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/DcpParticipantRuntimeExtension.java} (91%) rename edc-tests/e2e/{iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp => dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp}/runtime/Runtimes.java (83%) rename edc-tests/e2e/{iatp-tests => dcp-tests}/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/BdrsServerExtension.java (97%) rename edc-tests/e2e/{iatp-tests => dcp-tests}/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/DidServerExtension.java (100%) rename edc-tests/runtime/{iatp/iatp-extensions => dcp/dcp-extensions}/build.gradle.kts (100%) rename edc-tests/runtime/{iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp => dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp}/CredentialsJsonLdExtension.java (97%) rename edc-tests/runtime/{iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp => dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp}/ih/IdentityHubExtension.java (97%) rename edc-tests/runtime/{iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp => dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp}/ih/TxScopeToCriterionTransformer.java (98%) rename edc-tests/runtime/{iatp/iatp-extensions => dcp/dcp-extensions}/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension (89%) rename edc-tests/runtime/{iatp/iatp-extensions => dcp/dcp-extensions}/src/main/resources/cx-credentials-context.json (100%) rename edc-tests/runtime/{iatp/runtime-memory-iatp-div-ih => dcp/runtime-memory-dcp-div-ih}/README.md (100%) rename edc-tests/runtime/{iatp/runtime-memory-iatp-div-ih => dcp/runtime-memory-dcp-div-ih}/build.gradle.kts (97%) rename edc-tests/runtime/{iatp/runtime-memory-iatp-ih => dcp/runtime-memory-dcp-ih}/README.md (100%) rename edc-tests/runtime/{iatp/runtime-memory-iatp-ih => dcp/runtime-memory-dcp-ih}/build.gradle.kts (91%) rename edc-tests/runtime/{iatp => dcp}/runtime-memory-sts/README.md (100%) rename edc-tests/runtime/{iatp => dcp}/runtime-memory-sts/build.gradle.kts (96%) rename spi/core-spi/src/main/java/org/eclipse/tractusx/edc/{TxIatpConstants.java => TxDcpConstants.java} (97%) diff --git a/charts/tractusx-connector-memory/README.md b/charts/tractusx-connector-memory/README.md index 22281ab276..2246422e66 100644 --- a/charts/tractusx-connector-memory/README.md +++ b/charts/tractusx-connector-memory/README.md @@ -6,7 +6,7 @@ A Helm chart for Tractus-X Eclipse Data Space Connector based on memory. Please **Homepage:** -## Setting up IATP +## Setting up DCP ### Preconditions @@ -19,15 +19,15 @@ A Helm chart for Tractus-X Eclipse Data Space Connector based on memory. Please - store client secret in the HashiCorp vault using an alias. The exact procedure will depend on your deployment of HashiCorp Vault and is out of scope of this document. But by default, Tractus-X EDC expects to find the secret under `secret/client-secret`. The alias must be configured - using the `iatp.sts.oauth.client.secret_alias` Helm value. + using the `dcp.sts.oauth.client.secret_alias` Helm value. ### Configure the chart Be sure to provide the following configuration entries to your Tractus-X EDC Helm chart: -- `iatp.sts.oauth.token_url`: the token endpoint of DIV -- `iatp.sts.oauth.client.id`: the client ID of your tenant in DIV -- `iatp.sts.oauth.client.secret_alias`: alias under which you saved your DIV client secret in the vault -- `iatp.sts.div.url`: the base URL for DIV +- `dcp.sts.oauth.token_url`: the token endpoint of DIV +- `dcp.sts.oauth.client.id`: the client ID of your tenant in DIV +- `dcp.sts.oauth.client.secret_alias`: alias under which you saved your DIV client secret in the vault +- `dcp.sts.div.url`: the base URL for DIV In addition, in order to map BPNs to DIDs, a new service is required, called the BPN-DID Resolution Service, which must be configured: @@ -56,17 +56,17 @@ helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0- |-----|------|---------|-------------| | customCaCerts | object | `{}` | Add custom ca certificates to the truststore | | customLabels | object | `{}` | Add some custom labels | +| dcp.cache.enabled | bool | `true` | Whether the Verifiable Presentation cache is enabled | +| dcp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | +| dcp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | +| dcp.didService.selfRegistration.id | string | `"did:web:changeme"` | Unique id of connector to be used for register / unregister service inside did document (must be valid URI) | +| dcp.id | string | `"did:web:changeme"` | Decentralized IDentifier (DID) of the connector | +| dcp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | +| dcp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | +| dcp.sts.oauth.client.secret_alias | string | `nil` | Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access | +| dcp.sts.oauth.token_url | string | `nil` | URL where connectors can request OAuth2 access tokens for DIV access | +| dcp.trustedIssuers | list | `[]` | Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer | | fullnameOverride | string | `""` | | -| iatp.cache.enabled | bool | `true` | Whether the Verifiable Presentation cache is enabled | -| iatp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | -| iatp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | -| iatp.didService.selfRegistration.id | string | `"did:web:changeme"` | Unique id of connector to be used for register / unregister service inside did document (must be valid URI) | -| iatp.id | string | `"did:web:changeme"` | Decentralized IDentifier (DID) of the connector | -| iatp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | -| iatp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | -| iatp.sts.oauth.client.secret_alias | string | `nil` | Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access | -| iatp.sts.oauth.token_url | string | `nil` | URL where connectors can request OAuth2 access tokens for DIV access | -| iatp.trustedIssuers | list | `[]` | Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer | | imagePullSecrets | list | `[]` | Existing image pull secret to use to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) | | log4j2.config | string | `"Appenders:\n Console:\n name: CONSOLE\n JsonTemplateLayout:\n eventTemplate: |-\n {\n \"timestamp\": {\n \"$resolver\": \"timestamp\",\n \"pattern\": {\n \"format\": \"yyyy-MM-dd'T'HH:mm:ss.SSSSSSS\",\n \"timeZone\": \"UTC\"\n }\n },\n \"level\": {\n \"$resolver\": \"level\",\n \"field\": \"severity\",\n \"severity\": {\n \"field\": \"keyword\"\n }\n },\n \"message\": {\n \"$resolver\": \"message\"\n }\n }\nLoggers:\n Root:\n level: \"OFF\"\n Logger:\n name: org.eclipse.edc.monitor.logger\n level: DEBUG\n AppenderRef:\n ref: CONSOLE"` | Log4j2 configuration for json log formatting. | | log4j2.enableJsonLogs | bool | `true` | Whether to enable the json log config in log4j2.config | diff --git a/charts/tractusx-connector-memory/README.md.gotmpl b/charts/tractusx-connector-memory/README.md.gotmpl index fc0927964a..119f8fc53a 100644 --- a/charts/tractusx-connector-memory/README.md.gotmpl +++ b/charts/tractusx-connector-memory/README.md.gotmpl @@ -8,7 +8,7 @@ {{ template "chart.homepageLine" . }} -## Setting up IATP +## Setting up DCP ### Preconditions @@ -21,16 +21,16 @@ - store client secret in the HashiCorp vault using an alias. The exact procedure will depend on your deployment of HashiCorp Vault and is out of scope of this document. But by default, Tractus-X EDC expects to find the secret under `secret/client-secret`. The alias must be configured - using the `iatp.sts.oauth.client.secret_alias` Helm value. + using the `dcp.sts.oauth.client.secret_alias` Helm value. ### Configure the chart Be sure to provide the following configuration entries to your Tractus-X EDC Helm chart: -- `iatp.sts.oauth.token_url`: the token endpoint of DIV -- `iatp.sts.oauth.client.id`: the client ID of your tenant in DIV -- `iatp.sts.oauth.client.secret_alias`: alias under which you saved your DIV client secret in the vault -- `iatp.sts.div.url`: the base URL for DIV +- `dcp.sts.oauth.token_url`: the token endpoint of DIV +- `dcp.sts.oauth.client.id`: the client ID of your tenant in DIV +- `dcp.sts.oauth.client.secret_alias`: alias under which you saved your DIV client secret in the vault +- `dcp.sts.div.url`: the base URL for DIV In addition, in order to map BPNs to DIDs, a new service is required, called the BPN-DID Resolution Service, which must be configured: diff --git a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml index 84de5ee953..af1e18c961 100644 --- a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml +++ b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml @@ -146,9 +146,9 @@ spec: ## ID CONFIGURATION ## ######################## - name: EDC_PARTICIPANT_ID - value: {{ .Values.iatp.id | required ".Values.iatp.id is required" | quote }} + value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote }} - name: "EDC_IAM_ISSUER_ID" - value: {{ .Values.iatp.id | required ".Values.iatp.id is required" | quote }} + value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote }} - name: "EDC_PARTICIPANT_CONTEXT_ID" value: {{ .Values.participant.contextId | required ".Values.participant.contextId is required" | quote }} - name: "TRACTUSX_EDC_PARTICIPANT_BPN" @@ -223,21 +223,21 @@ spec: value: {{ printf "%s%s" (include "txdc.runtime.url.protocol" . ) .Values.runtime.endpoints.protocol.path | quote }} ############################# - ## IATP / STS / DIV CONFIG ## + ## DCP / STS / DIV CONFIG ## ############################# - name: "EDC_IAM_STS_OAUTH_TOKEN_URL" - value: {{ .Values.iatp.sts.oauth.token_url | required ".Values.iatp.sts.oauth.token_url is required" | quote}} + value: {{ .Values.dcp.sts.oauth.token_url | required ".Values.dcp.sts.oauth.token_url is required" | quote}} - name: "EDC_IAM_STS_OAUTH_CLIENT_ID" - value: {{ .Values.iatp.sts.oauth.client.id | required ".Values.iatp.sts.oauth.client.id is required" | quote}} + value: {{ .Values.dcp.sts.oauth.client.id | required ".Values.dcp.sts.oauth.client.id is required" | quote}} - name: "EDC_IAM_STS_OAUTH_CLIENT_SECRET_ALIAS" - value: {{ .Values.iatp.sts.oauth.client.secret_alias | required ".Values.iatp.sts.oauth.client.secret_alias is required" | quote}} + value: {{ .Values.dcp.sts.oauth.client.secret_alias | required ".Values.dcp.sts.oauth.client.secret_alias is required" | quote}} - {{- if .Values.iatp.sts.div.url }} + {{- if .Values.dcp.sts.div.url }} - name: "TX_EDC_IAM_STS_DIV_URL" - value: {{ .Values.iatp.sts.div.url | quote }} + value: {{ .Values.dcp.sts.div.url | quote }} {{- end }} - {{- range $index, $issuer := .Values.iatp.trustedIssuers }} + {{- range $index, $issuer := .Values.dcp.trustedIssuers }} {{- if eq (kindOf $issuer) "string" }} - name: "EDC_IAM_TRUSTED-ISSUER_{{$index}}-ISSUER_ID" value: {{ $issuer | quote }} @@ -251,24 +251,24 @@ spec: {{- end }} {{- end }} - name: "TX_EDC_DID_SERVICE_SELF_REGISTRATION_ENABLED" - value: {{ .Values.iatp.didService.selfRegistration.enabled | quote}} + value: {{ .Values.dcp.didService.selfRegistration.enabled | quote}} - name: "TX_EDC_DID_SERVICE_SELF_DEREGISTRATION_ENABLED" value: "false" - name: "TX_EDC_DID_SERVICE_SELF_REGISTRATION_ID" - value: {{ .Values.iatp.didService.selfRegistration.id | quote }} + value: {{ .Values.dcp.didService.selfRegistration.id | quote }} - name: "TX_EDC_DCP_CACHE_ENABLED" - value: {{ .Values.iatp.cache.enabled | quote }} + value: {{ .Values.dcp.cache.enabled | quote }} - name: "TX_EDC_DCP_CACHE_VALIDITY_SECONDS" - value: {{ .Values.iatp.cache.validity | quote }} + value: {{ .Values.dcp.cache.validity | quote }} ################# ## BDRS CLIENT ## ################# - - name: "TX_EDC_IAM_IATP_BDRS_SERVER_URL" + - name: "TX_EDC_IAM_DCP_BDRS_SERVER_URL" value: {{ .Values.runtime.bdrs.server.url | required ".Values.runtime.bdrs.server.url is required" | quote }} {{- if .Values.runtime.bdrs.cache_validity_seconds }} - - name: "TX_EDC_IAM_IATP_BDRS_CACHE_VALIDITY" + - name: "TX_EDC_IAM_DCP_BDRS_CACHE_VALIDITY" value: {{ .Values.runtime.bdrs.cache_validity_seconds | quote}} {{- end}} diff --git a/charts/tractusx-connector-memory/values.yaml b/charts/tractusx-connector-memory/values.yaml index a0e1008643..f8e40b66de 100644 --- a/charts/tractusx-connector-memory/values.yaml +++ b/charts/tractusx-connector-memory/values.yaml @@ -38,7 +38,7 @@ participant: # -- Participant Context Id - Newly introduced id for a connector instance (needed for multitenancy) contextId: "UUID CHANGEME" -iatp: +dcp: # -- Decentralized IDentifier (DID) of the connector id: "did:web:changeme" # -- Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer diff --git a/charts/tractusx-connector/README.md b/charts/tractusx-connector/README.md index 8ee56f90a2..cbaa7514e0 100644 --- a/charts/tractusx-connector/README.md +++ b/charts/tractusx-connector/README.md @@ -9,7 +9,7 @@ This chart is intended for use with an _existing_ PostgreSQL database and an _ex **Homepage:** -## Setting up IATP +## Setting up DCP ### Preconditions @@ -22,15 +22,15 @@ This chart is intended for use with an _existing_ PostgreSQL database and an _ex - store client secret in the HashiCorp vault using an alias. The exact procedure will depend on your deployment of HashiCorp Vault and is out of scope of this document. But by default, Tractus-X EDC expects to find the secret under `secret/client-secret`. The alias must be configured - using the `iatp.sts.oauth.client.secret_alias` Helm value. + using the `dcp.sts.oauth.client.secret_alias` Helm value. ### Configure the chart Be sure to provide the following configuration entries to your Tractus-X EDC Helm chart: -- `iatp.sts.oauth.token_url`: the token endpoint of DIV -- `iatp.sts.oauth.client.id`: the client ID of your tenant in DIV -- `iatp.sts.oauth.client.secret_alias`: alias under which you saved your DIV client secret in the vault -- `iatp.sts.div.url`: the base URL for DIV +- `dcp.sts.oauth.token_url`: the token endpoint of DIV +- `dcp.sts.oauth.client.id`: the client ID of your tenant in DIV +- `dcp.sts.oauth.client.secret_alias`: alias under which you saved your DIV client secret in the vault +- `dcp.sts.div.url`: the base URL for DIV In addition, in order to map BPNs to DIDs, a new service is required, called the BPN-DID Resolution Service, which must be configured: @@ -257,17 +257,17 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | dataplane.url.public | string | `""` | Explicitly declared url for reaching the public api (e.g. if ingresses not used) | | dataplane.volumeMounts | string | `nil` | declare where to mount [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) into the container | | dataplane.volumes | string | `nil` | [volume](https://kubernetes.io/docs/concepts/storage/volumes/) directories | +| dcp.cache.enabled | bool | `true` | Whether the Verifiable Presentation cache is enabled | +| dcp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | +| dcp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | +| dcp.didService.selfRegistration.id | string | `"did:web:changeme"` | Unique id of connector to be used for register / unregister service inside did document (must be valid URI) | +| dcp.id | string | `"did:web:changeme"` | Decentralized IDentifier (DID) of the connector | +| dcp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | +| dcp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | +| dcp.sts.oauth.client.secret_alias | string | `nil` | Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access | +| dcp.sts.oauth.token_url | string | `nil` | URL where connectors can request OAuth2 access tokens for DIV access | +| dcp.trustedIssuers | list | `[]` | Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer | | fullnameOverride | string | `""` | | -| iatp.cache.enabled | bool | `true` | Whether the Verifiable Presentation cache is enabled | -| iatp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | -| iatp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | -| iatp.didService.selfRegistration.id | string | `"did:web:changeme"` | Unique id of connector to be used for register / unregister service inside did document (must be valid URI) | -| iatp.id | string | `"did:web:changeme"` | Decentralized IDentifier (DID) of the connector | -| iatp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | -| iatp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | -| iatp.sts.oauth.client.secret_alias | string | `nil` | Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access | -| iatp.sts.oauth.token_url | string | `nil` | URL where connectors can request OAuth2 access tokens for DIV access | -| iatp.trustedIssuers | list | `[]` | Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer | | imagePullSecrets | list | `[]` | Existing image pull secret to use to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) | | install.postgresql | bool | `true` | Deploying a PostgreSQL instance | | install.vault | bool | `true` | Deploying a HashiCorp Vault instance | diff --git a/charts/tractusx-connector/README.md.gotmpl b/charts/tractusx-connector/README.md.gotmpl index 9e9a12b487..bdb59b24be 100644 --- a/charts/tractusx-connector/README.md.gotmpl +++ b/charts/tractusx-connector/README.md.gotmpl @@ -8,7 +8,7 @@ {{ template "chart.homepageLine" . }} -## Setting up IATP +## Setting up DCP ### Preconditions @@ -21,16 +21,16 @@ - store client secret in the HashiCorp vault using an alias. The exact procedure will depend on your deployment of HashiCorp Vault and is out of scope of this document. But by default, Tractus-X EDC expects to find the secret under `secret/client-secret`. The alias must be configured - using the `iatp.sts.oauth.client.secret_alias` Helm value. + using the `dcp.sts.oauth.client.secret_alias` Helm value. ### Configure the chart Be sure to provide the following configuration entries to your Tractus-X EDC Helm chart: -- `iatp.sts.oauth.token_url`: the token endpoint of DIV -- `iatp.sts.oauth.client.id`: the client ID of your tenant in DIV -- `iatp.sts.oauth.client.secret_alias`: alias under which you saved your DIV client secret in the vault -- `iatp.sts.div.url`: the base URL for DIV +- `dcp.sts.oauth.token_url`: the token endpoint of DIV +- `dcp.sts.oauth.client.id`: the client ID of your tenant in DIV +- `dcp.sts.oauth.client.secret_alias`: alias under which you saved your DIV client secret in the vault +- `dcp.sts.div.url`: the base URL for DIV In addition, in order to map BPNs to DIDs, a new service is required, called the BPN-DID Resolution Service, which must be configured: diff --git a/charts/tractusx-connector/templates/deployment-controlplane.yaml b/charts/tractusx-connector/templates/deployment-controlplane.yaml index 9f7b748362..0b6e1e66ba 100644 --- a/charts/tractusx-connector/templates/deployment-controlplane.yaml +++ b/charts/tractusx-connector/templates/deployment-controlplane.yaml @@ -147,9 +147,9 @@ spec: ## ID CONFIGURATION ## ######################## - name: EDC_PARTICIPANT_ID - value: {{ .Values.iatp.id | required ".Values.iatp.id is required" | quote }} + value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote }} - name: "EDC_IAM_ISSUER_ID" - value: {{ .Values.iatp.id | required ".Values.iatp.id is required" | quote }} + value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote }} - name: "EDC_PARTICIPANT_CONTEXT_ID" value: {{ .Values.participant.contextId | required ".Values.participant.contextId is required" | quote }} - name: "TRACTUSX_EDC_PARTICIPANT_BPN" @@ -223,19 +223,19 @@ spec: ############################# - ## IATP / STS / DIV CONFIG ## + ## DCP / STS / DIV CONFIG ## ############################# - name: "EDC_IAM_STS_OAUTH_TOKEN_URL" - value: {{ .Values.iatp.sts.oauth.token_url | required ".Values.iatp.sts.oauth.token_url is required" | quote}} + value: {{ .Values.dcp.sts.oauth.token_url | required ".Values.dcp.sts.oauth.token_url is required" | quote}} - name: "EDC_IAM_STS_OAUTH_CLIENT_ID" - value: {{ .Values.iatp.sts.oauth.client.id | required ".Values.iatp.sts.oauth.client.id is required" | quote}} + value: {{ .Values.dcp.sts.oauth.client.id | required ".Values.dcp.sts.oauth.client.id is required" | quote}} - name: "EDC_IAM_STS_OAUTH_CLIENT_SECRET_ALIAS" - value: {{ .Values.iatp.sts.oauth.client.secret_alias | required ".Values.iatp.sts.oauth.client.secret_alias is required" | quote}} - {{- if .Values.iatp.sts.div.url }} + value: {{ .Values.dcp.sts.oauth.client.secret_alias | required ".Values.dcp.sts.oauth.client.secret_alias is required" | quote}} + {{- if .Values.dcp.sts.div.url }} - name: "TX_EDC_IAM_STS_DIV_URL" - value: {{ .Values.iatp.sts.div.url | quote }} + value: {{ .Values.dcp.sts.div.url | quote }} {{- end }} - {{- range $index, $issuer := .Values.iatp.trustedIssuers }} + {{- range $index, $issuer := .Values.dcp.trustedIssuers }} {{- if eq (kindOf $issuer) "string" }} - name: "EDC_IAM_TRUSTED-ISSUER_{{$index}}-ISSUER_ID" value: {{ $issuer | quote }} @@ -249,24 +249,24 @@ spec: {{- end }} {{- end }} - name: "TX_EDC_DID_SERVICE_SELF_REGISTRATION_ENABLED" - value: {{ .Values.iatp.didService.selfRegistration.enabled | quote}} + value: {{ .Values.dcp.didService.selfRegistration.enabled | quote}} - name: "TX_EDC_DID_SERVICE_SELF_DEREGISTRATION_ENABLED" value: {{ and (eq (int .Values.controlplane.replicaCount) 1) (not .Values.controlplane.autoscaling.enabled) | quote }} - name: "TX_EDC_DID_SERVICE_SELF_REGISTRATION_ID" - value: {{ .Values.iatp.didService.selfRegistration.id | quote }} + value: {{ .Values.dcp.didService.selfRegistration.id | quote }} - name: "TX_EDC_DCP_CACHE_ENABLED" - value: {{ .Values.iatp.cache.enabled | quote }} + value: {{ .Values.dcp.cache.enabled | quote }} - name: "TX_EDC_DCP_CACHE_VALIDITY_SECONDS" - value: {{ .Values.iatp.cache.validity | quote }} + value: {{ .Values.dcp.cache.validity | quote }} ################# ## BDRS CLIENT ## ################# - - name: "TX_EDC_IAM_IATP_BDRS_SERVER_URL" + - name: "TX_EDC_IAM_DCP_BDRS_SERVER_URL" value: {{ .Values.controlplane.bdrs.server.url | required ".Values.controlplane.bdrs.server.url is required" | quote }} {{- if .Values.controlplane.bdrs.cache_validity_seconds }} - - name: "TX_EDC_IAM_IATP_BDRS_CACHE_VALIDITY" + - name: "TX_EDC_IAM_DCP_BDRS_CACHE_VALIDITY" value: {{ .Values.controlplane.bdrs.cache_validity_seconds | quote}} {{- end}} diff --git a/charts/tractusx-connector/templates/deployment-dataplane.yaml b/charts/tractusx-connector/templates/deployment-dataplane.yaml index 40510d5627..f55714afce 100644 --- a/charts/tractusx-connector/templates/deployment-dataplane.yaml +++ b/charts/tractusx-connector/templates/deployment-dataplane.yaml @@ -149,7 +149,7 @@ spec: - name: EDC_PARTICIPANT_CONTEXT_ID value: {{ .Values.participant.contextId | required ".Values.participant.contextId is required" | quote}} - name: "EDC_IAM_ISSUER_ID" - value: {{ .Values.iatp.id | required ".Values.iatp.id is required" | quote}} + value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote}} ########################### ## LOGGING CONFIGURATION ## @@ -222,17 +222,17 @@ spec: {{ end }} ############################# - ## IATP / STS / DIV CONFIG ## + ## DCP / STS / DIV CONFIG ## ############################# - name: "EDC_IAM_STS_OAUTH_TOKEN_URL" - value: {{ .Values.iatp.sts.oauth.token_url | required ".Values.iatp.sts.oauth.token_url is required" | quote}} + value: {{ .Values.dcp.sts.oauth.token_url | required ".Values.dcp.sts.oauth.token_url is required" | quote}} - name: "EDC_IAM_STS_OAUTH_CLIENT_ID" - value: {{ .Values.iatp.sts.oauth.client.id | required ".Values.iatp.sts.oauth.client.id is required" | quote}} + value: {{ .Values.dcp.sts.oauth.client.id | required ".Values.dcp.sts.oauth.client.id is required" | quote}} - name: "EDC_IAM_STS_OAUTH_CLIENT_SECRET_ALIAS" - value: {{ .Values.iatp.sts.oauth.client.secret_alias | required ".Values.iatp.sts.oauth.client.secret_alias is required" | quote}} - {{- if .Values.iatp.sts.div.url }} + value: {{ .Values.dcp.sts.oauth.client.secret_alias | required ".Values.dcp.sts.oauth.client.secret_alias is required" | quote}} + {{- if .Values.dcp.sts.div.url }} - name: "TX_EDC_IAM_STS_DIV_URL" - value: {{ .Values.iatp.sts.div.url | quote }} + value: {{ .Values.dcp.sts.div.url | quote }} {{- end }} ################ diff --git a/charts/tractusx-connector/values.yaml b/charts/tractusx-connector/values.yaml index 1accc39341..bbd596835c 100644 --- a/charts/tractusx-connector/values.yaml +++ b/charts/tractusx-connector/values.yaml @@ -45,7 +45,7 @@ participant: # -- Participant Context Id - Newly introduced id for a connector instance (needed for multitenancy) contextId: "UUID CHANGEME" -iatp: +dcp: # -- Decentralized IDentifier (DID) of the connector id: "did:web:changeme" # -- Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer diff --git a/docs/development/mock-edc.md b/docs/development/mock-edc.md index 94001e93d3..76a4b0fc71 100644 --- a/docs/development/mock-edc.md +++ b/docs/development/mock-edc.md @@ -209,7 +209,7 @@ POST /api/instrumentation -> adds a new RecordedRequest, JSON must be in t - A complete sample how to run a test using the Mock-Connector in a Testcontainer can be found [here](../../samples/testing-with-mocked-edc) - To test compliance with DSP, use the [TCK](https://github.com/eclipse-dataspacetck/cvf) -- A Mock-IATP runtime is planned for future releases. +- A Mock-DCP runtime is planned for future releases. ## 6. Future improvements diff --git a/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java b/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java index c1c60d59bb..675949f89b 100644 --- a/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java +++ b/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java @@ -45,13 +45,13 @@ public class BdrsClientExtension implements ServiceExtension { public static final int DEFAULT_BDRS_CACHE_VALIDITY = 15 * 60; // 15 minutes @Setting(value = "Base URL of the BDRS service", required = true) - public static final String BDRS_SERVER_URL_PROPERTY = "tx.edc.iam.iatp.bdrs.server.url"; + public static final String BDRS_SERVER_URL_PROPERTY = "tx.edc.iam.dcp.bdrs.server.url"; @Setting(value = "Base URL of the CredentialService, that belongs to this connector runtime. If not specified, the URL is resolved from this participant's DID document.") - public static final String CREDENTIAL_SERVICE_BASE_URL_PROPERTY = "tx.edc.iam.iatp.credentialservice.url"; + public static final String CREDENTIAL_SERVICE_BASE_URL_PROPERTY = "tx.edc.iam.dcp.credentialservice.url"; @Setting(value = "Validity period in seconds for the cached BPN/DID mappings. After this period a new resolution request will hit the server.", defaultValue = DEFAULT_BDRS_CACHE_VALIDITY + "") - public static final String BDRS_SERVER_CACHE_VALIDITY_PERIOD = "tx.edc.iam.iatp.bdrs.cache.validity"; + public static final String BDRS_SERVER_CACHE_VALIDITY_PERIOD = "tx.edc.iam.dcp.bdrs.cache.validity"; // this setting is already defined in IdentityAndTrustExtension public static final String CONNECTOR_DID_PROPERTY = "edc.iam.issuer.id"; diff --git a/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImpl.java b/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImpl.java index 6e33d7b3f4..65a42c24fc 100644 --- a/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImpl.java +++ b/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImpl.java @@ -30,7 +30,7 @@ import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.Result; -import org.eclipse.tractusx.edc.TxIatpConstants; +import org.eclipse.tractusx.edc.TxDcpConstants; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import java.io.IOException; @@ -188,7 +188,7 @@ private Result createMembershipPresentation() { SUBJECT, ownDid, AUDIENCE, ownDid ); - var scope = TxIatpConstants.MEMBERSHIP_SCOPE; + var scope = TxDcpConstants.MEMBERSHIP_SCOPE; return participantContextSupplier.get().map(ParticipantContext::getParticipantContextId) .flatMap(result -> { diff --git a/edc-extensions/bdrs-client/src/test/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImplExtensionTest.java b/edc-extensions/bdrs-client/src/test/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImplExtensionTest.java index 9bf4a10844..5711a2d93c 100644 --- a/edc-extensions/bdrs-client/src/test/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImplExtensionTest.java +++ b/edc-extensions/bdrs-client/src/test/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImplExtensionTest.java @@ -84,7 +84,7 @@ void createClient_whenNoCredentialServiceUrl_shouldInvokeResolver(ServiceExtensi extension.getBdrsClient(context); verify(monitor).withPrefix(anyString()); - verify(monitor).warning("No config value found for 'tx.edc.iam.iatp.credentialservice.url'. As a fallback, the credentialService URL from this connector's DID document will be resolved."); + verify(monitor).warning("No config value found for 'tx.edc.iam.dcp.credentialservice.url'. As a fallback, the credentialService URL from this connector's DID document will be resolved."); verifyNoMoreInteractions(monitor); } @@ -100,7 +100,7 @@ void createClient_whenResolverFails_expectLogError(ServiceExtensionContext conte var client = extension.getBdrsClient(context); verify(monitor).withPrefix(anyString()); - verify(monitor).warning("No config value found for 'tx.edc.iam.iatp.credentialservice.url'. As a fallback, the credentialService URL from this connector's DID document will be resolved."); + verify(monitor).warning("No config value found for 'tx.edc.iam.dcp.credentialservice.url'. As a fallback, the credentialService URL from this connector's DID document will be resolved."); // the DID url resolver is only invoked on-demand, so no eager-loading of the DID document verify(monitor, never()).severe("Resolving the credentialService URL failed. This runtime won't be able to communicate with BDRS. Error: test failure."); diff --git a/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java index b2b2bed45b..ffd40d17da 100644 --- a/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java +++ b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java @@ -29,7 +29,7 @@ import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.tractusx.edc.iam.iatp.scope.DefaultScopeExtractor; +import org.eclipse.tractusx.edc.iam.dcp.scope.DefaultScopeExtractor; import java.util.HashMap; import java.util.Map; @@ -38,8 +38,8 @@ import static java.lang.String.format; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.DSP_SCOPE_V_2025_1; -import static org.eclipse.tractusx.edc.TxIatpConstants.DEFAULT_SCOPES; -import static org.eclipse.tractusx.edc.TxIatpConstants.V08_DEFAULT_SCOPES; +import static org.eclipse.tractusx.edc.TxDcpConstants.DEFAULT_SCOPES; +import static org.eclipse.tractusx.edc.TxDcpConstants.V08_DEFAULT_SCOPES; import static org.eclipse.tractusx.edc.iam.dcp.cx.CxDcpDefaultScopeExtension.NAME; @Extension(NAME) diff --git a/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractor.java b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractor.java index b85d8cfda0..cda5d3ae50 100644 --- a/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractor.java +++ b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractor.java @@ -35,7 +35,7 @@ import java.util.Set; import static java.util.Collections.emptySet; -import static org.eclipse.tractusx.edc.TxIatpConstants.CREDENTIAL_TYPE_NAMESPACE; +import static org.eclipse.tractusx.edc.TxDcpConstants.CREDENTIAL_TYPE_NAMESPACE; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_NS; diff --git a/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtensionTest.java b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtensionTest.java index 1f7afdf0c5..8be7e32a4b 100644 --- a/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtensionTest.java +++ b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtensionTest.java @@ -27,7 +27,7 @@ import org.eclipse.edc.policy.engine.spi.PolicyEngine; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.ConfigFactory; -import org.eclipse.tractusx.edc.iam.iatp.scope.DefaultScopeExtractor; +import org.eclipse.tractusx.edc.iam.dcp.scope.DefaultScopeExtractor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -39,9 +39,9 @@ import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.DSP_SCOPE_V_2025_1; -import static org.eclipse.tractusx.edc.TxIatpConstants.DEFAULT_SCOPES; -import static org.eclipse.tractusx.edc.TxIatpConstants.V08_DEFAULT_SCOPES; -import static org.eclipse.tractusx.edc.iam.iatp.IatpDefaultScopeExtension.TX_IATP_DEFAULT_SCOPE_PREFIX; +import static org.eclipse.tractusx.edc.TxDcpConstants.DEFAULT_SCOPES; +import static org.eclipse.tractusx.edc.TxDcpConstants.V08_DEFAULT_SCOPES; +import static org.eclipse.tractusx.edc.iam.dcp.DcpDefaultScopeExtension.TX_DCP_DEFAULT_SCOPE_PREFIX; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -80,7 +80,7 @@ void initialize_withConfiguredScopes(ServiceExtensionContext context, CxDcpDefau "bar.type", "BarCredential", "bar.operation", "write" )); - when(context.getConfig(TX_IATP_DEFAULT_SCOPE_PREFIX)).thenReturn(cfg); + when(context.getConfig(TX_DCP_DEFAULT_SCOPE_PREFIX)).thenReturn(cfg); extension.initialize(context); var scopes = new HashMap>(); diff --git a/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractorTest.java b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractorTest.java index 9d0be57f2e..318fae0ce0 100644 --- a/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractorTest.java +++ b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractorTest.java @@ -49,7 +49,7 @@ import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.tractusx.edc.TxIatpConstants.CREDENTIAL_TYPE_NAMESPACE; +import static org.eclipse.tractusx.edc.TxDcpConstants.CREDENTIAL_TYPE_NAMESPACE; import static org.eclipse.tractusx.edc.iam.dcp.cx.scope.CxCredentialScopeExtractor.FRAMEWORK_AGREEMENT_LEFT_OPERAND; import static org.eclipse.tractusx.edc.policy.cx.legacy.common.AbstractDynamicCredentialConstraintFunction.ACTIVE; import static org.eclipse.tractusx.edc.policy.cx.legacy.dismantler.DismantlerCredentialConstraintFunction.DISMANTLER_LITERAL; diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenServiceTest.java b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenServiceTest.java index c3eb5e7685..ddba9b060d 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenServiceTest.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenServiceTest.java @@ -58,7 +58,7 @@ public class DivSecureTokenServiceTest { - static final String DIV_URL = "http://localhost:8080/iatp"; + static final String DIV_URL = "http://localhost:8080/dcp"; private final Monitor monitor = mock(Monitor.class); private final DivOauth2Client oauth2Client = mock(DivOauth2Client.class); private final ObjectMapper mapper = new ObjectMapper(); diff --git a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/IatpDefaultScopeExtension.java b/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtension.java similarity index 79% rename from edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/IatpDefaultScopeExtension.java rename to edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtension.java index d6bb6b8694..6a4b773c1f 100644 --- a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/IatpDefaultScopeExtension.java +++ b/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtension.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iam.iatp; +package org.eclipse.tractusx.edc.iam.dcp; import org.eclipse.edc.policy.context.request.spi.RequestCatalogPolicyContext; import org.eclipse.edc.policy.context.request.spi.RequestContractNegotiationPolicyContext; @@ -31,7 +31,7 @@ import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.Config; -import org.eclipse.tractusx.edc.iam.iatp.scope.DefaultScopeExtractor; +import org.eclipse.tractusx.edc.iam.dcp.scope.DefaultScopeExtractor; import java.util.HashMap; import java.util.Map; @@ -41,22 +41,22 @@ import static java.lang.String.format; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.DSP_SCOPE_V_2025_1; -import static org.eclipse.tractusx.edc.iam.iatp.IatpDefaultScopeExtension.NAME; +import static org.eclipse.tractusx.edc.iam.dcp.DcpDefaultScopeExtension.NAME; @Extension(NAME) -public class IatpDefaultScopeExtension implements ServiceExtension { +public class DcpDefaultScopeExtension implements ServiceExtension { - public static final String TX_IATP_DEFAULT_SCOPE_PREFIX = "tx.edc.iam.iatp.default-scopes"; + public static final String TX_DCP_DEFAULT_SCOPE_PREFIX = "tx.edc.iam.dcp.default-scopes"; - public static final String TX_IATP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS = TX_IATP_DEFAULT_SCOPE_PREFIX + ".."; + public static final String TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS = TX_DCP_DEFAULT_SCOPE_PREFIX + ".."; - @Setting(context = TX_IATP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. org.eclipse.edc.vc.type", required = true) + @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. org.eclipse.edc.vc.type", required = true) public static final String ALIAS = "alias"; - @Setting(context = TX_IATP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. MembershipCredential", required = true) + @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. MembershipCredential", required = true) public static final String TYPE = "type"; - @Setting(context = TX_IATP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. read", required = true) + @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. read", required = true) public static final String OPERATION = "operation"; static final String NAME = "Tractusx default scope extension"; @Inject @@ -81,7 +81,7 @@ public void initialize(ServiceExtensionContext context) { } private Map> defaultScopes(ServiceExtensionContext context) { - var config = context.getConfig(TX_IATP_DEFAULT_SCOPE_PREFIX); + var config = context.getConfig(TX_DCP_DEFAULT_SCOPE_PREFIX); var scopes = config.partition().map(this::createScope).collect(Collectors.toSet()); var scopesByVersion = new HashMap>(); if (!scopes.isEmpty()) { diff --git a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/scope/DefaultScopeExtractor.java b/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/scope/DefaultScopeExtractor.java similarity index 98% rename from edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/scope/DefaultScopeExtractor.java rename to edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/scope/DefaultScopeExtractor.java index ea6f33edcb..e65ac0212c 100644 --- a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/scope/DefaultScopeExtractor.java +++ b/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/scope/DefaultScopeExtractor.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iam.iatp.scope; +package org.eclipse.tractusx.edc.iam.dcp.scope; import org.eclipse.edc.policy.context.request.spi.RequestPolicyContext; import org.eclipse.edc.policy.engine.spi.PolicyValidatorRule; diff --git a/edc-extensions/dcp/tx-dcp/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dcp/tx-dcp/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index 98a37b4e5a..8e3a3544fc 100644 --- a/edc-extensions/dcp/tx-dcp/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/edc-extensions/dcp/tx-dcp/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -17,4 +17,4 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -org.eclipse.tractusx.edc.iam.iatp.IatpDefaultScopeExtension +org.eclipse.tractusx.edc.iam.dcp.DcpDefaultScopeExtension diff --git a/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/IatpDefaultScopeExtensionTest.java b/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtensionTest.java similarity index 89% rename from edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/IatpDefaultScopeExtensionTest.java rename to edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtensionTest.java index f84dd8ee6f..5d319dabf5 100644 --- a/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/IatpDefaultScopeExtensionTest.java +++ b/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtensionTest.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iam.iatp; +package org.eclipse.tractusx.edc.iam.dcp; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.policy.context.request.spi.RequestCatalogPolicyContext; @@ -28,7 +28,7 @@ import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.ConfigFactory; -import org.eclipse.tractusx.edc.iam.iatp.scope.DefaultScopeExtractor; +import org.eclipse.tractusx.edc.iam.dcp.scope.DefaultScopeExtractor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -41,7 +41,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.DSP_SCOPE_V_2025_1; -import static org.eclipse.tractusx.edc.iam.iatp.IatpDefaultScopeExtension.TX_IATP_DEFAULT_SCOPE_PREFIX; +import static org.eclipse.tractusx.edc.iam.dcp.DcpDefaultScopeExtension.TX_DCP_DEFAULT_SCOPE_PREFIX; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; @@ -51,7 +51,7 @@ import static org.mockito.Mockito.when; @ExtendWith(DependencyInjectionExtension.class) -public class IatpDefaultScopeExtensionTest { +public class DcpDefaultScopeExtensionTest { private final PolicyEngine policyEngine = mock(); @@ -61,7 +61,7 @@ void setup(ServiceExtensionContext context) { } @Test - void initialize(ServiceExtensionContext context, IatpDefaultScopeExtension extension) { + void initialize(ServiceExtensionContext context, DcpDefaultScopeExtension extension) { extension.initialize(context); verify(policyEngine, never()).registerPostValidator(eq(RequestCatalogPolicyContext.class), any()); @@ -70,7 +70,7 @@ void initialize(ServiceExtensionContext context, IatpDefaultScopeExtension exten } @Test - void initialize_withConfiguredScopes(ServiceExtensionContext context, IatpDefaultScopeExtension extension) { + void initialize_withConfiguredScopes(ServiceExtensionContext context, DcpDefaultScopeExtension extension) { var cfg = ConfigFactory.fromMap(Map.of( "foo.alias", "org.test.alias.foo", "foo.type", "FooCredential", @@ -79,7 +79,7 @@ void initialize_withConfiguredScopes(ServiceExtensionContext context, IatpDefaul "bar.type", "BarCredential", "bar.operation", "write" )); - when(context.getConfig(TX_IATP_DEFAULT_SCOPE_PREFIX)).thenReturn(cfg); + when(context.getConfig(TX_DCP_DEFAULT_SCOPE_PREFIX)).thenReturn(cfg); extension.initialize(context); var expectedScopes = Set.of("org.test.alias.foo:FooCredential:read", "org.test.alias.bar:BarCredential:write"); @@ -94,11 +94,11 @@ void initialize_withConfiguredScopes(ServiceExtensionContext context, IatpDefaul } @Test - void initialize_fails_withBadConfiguredScopes(ServiceExtensionContext context, IatpDefaultScopeExtension extension) { + void initialize_fails_withBadConfiguredScopes(ServiceExtensionContext context, DcpDefaultScopeExtension extension) { var cfg = ConfigFactory.fromMap(Map.of( "foo.alias", "org.test.alias.foo" )); - when(context.getConfig(TX_IATP_DEFAULT_SCOPE_PREFIX)).thenReturn(cfg); + when(context.getConfig(TX_DCP_DEFAULT_SCOPE_PREFIX)).thenReturn(cfg); assertThatThrownBy(() -> extension.initialize(context)).isInstanceOf(EdcException.class); } diff --git a/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/scope/DefaultScopeExtractorTest.java b/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/scope/DefaultScopeExtractorTest.java similarity index 98% rename from edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/scope/DefaultScopeExtractorTest.java rename to edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/scope/DefaultScopeExtractorTest.java index 774b31e0c9..da11078033 100644 --- a/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/scope/DefaultScopeExtractorTest.java +++ b/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/scope/DefaultScopeExtractorTest.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iam.iatp.scope; +package org.eclipse.tractusx.edc.iam.dcp.scope; import org.eclipse.edc.connector.controlplane.catalog.spi.CatalogRequestMessage; import org.eclipse.edc.policy.context.request.spi.RequestPolicyContext; diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java index 248109d90c..2d4d332130 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java @@ -29,7 +29,7 @@ import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.spi.security.Vault; import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer; -import org.eclipse.tractusx.edc.tests.participant.TractusxIatpParticipantBase; +import org.eclipse.tractusx.edc.tests.participant.TractusxDcpParticipantBase; import java.util.Base64; @@ -63,7 +63,7 @@ public static void configureParticipantContext(DataspaceIssuer issuer, IdentityH vault.storeSecret(issuer.getPrivateKeyAlias(), issuer.getPrivateKeyAsString()); } - public static void configureParticipant(TractusxIatpParticipantBase participant, DataspaceIssuer issuer, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) { + public static void configureParticipant(TractusxDcpParticipantBase participant, DataspaceIssuer issuer, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) { configureParticipantContext(participant, identityHubParticipant, identityHubRuntime); var accountService = identityHubRuntime.getService(StsAccountService.class); @@ -79,7 +79,7 @@ public static void configureParticipant(TractusxIatpParticipantBase participant, } - public static void configureParticipantContext(TractusxIatpParticipantBase participant, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) { + public static void configureParticipantContext(TractusxDcpParticipantBase participant, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) { var participantContextService = identityHubRuntime.getService(ParticipantContextService.class); var participantKey = participant.getKeyPairAsJwk(); diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipant.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipant.java index 6eeb40d840..7c77e61c7a 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipant.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipant.java @@ -22,8 +22,8 @@ import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.system.configuration.ConfigFactory; -import org.eclipse.tractusx.edc.tests.participant.IatpParticipant; -import org.eclipse.tractusx.edc.tests.participant.TractusxIatpParticipantBase; +import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; +import org.eclipse.tractusx.edc.tests.participant.TractusxDcpParticipantBase; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; import java.util.HashMap; @@ -32,12 +32,12 @@ import static org.eclipse.edc.util.io.Ports.getFreePort; -public class RemoteParticipant extends IatpParticipant { +public class RemoteParticipant extends DcpParticipant { private final List datasources = List.of("asset", "contractdefinition", "contractnegotiation", "policy", "transferprocess", "bpn", "policy-monitor", "edr", "dataplane", "accesstokendata", "dataplaneinstance"); - public Config getConfig(IatpParticipant participant, PostgresExtension postgresql) { + public Config getConfig(DcpParticipant participant, PostgresExtension postgresql) { var postgresqlConfig = postgresql.getConfig(getName()); Map settings = new HashMap<>() { @@ -101,7 +101,7 @@ private Map datasourceEnvironmentVariables(String datasourceName ); } - public static class Builder extends TractusxIatpParticipantBase.Builder { + public static class Builder extends TractusxDcpParticipantBase.Builder { protected Builder() { super(new RemoteParticipant()); diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipantExtension.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipantExtension.java index 9c89e816a9..03ea0666a1 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipantExtension.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipantExtension.java @@ -19,7 +19,7 @@ package org.eclipse.tractusx.edc.compatibility.tests.fixtures; -import org.eclipse.tractusx.edc.tests.participant.IatpParticipant; +import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; @@ -29,12 +29,12 @@ public class RemoteParticipantExtension implements BeforeAllCallback, AfterAllCallback { private final RemoteParticipant participant; - private final IatpParticipant localParticipant; + private final DcpParticipant localParticipant; private final PostgresExtension postgresql; private GenericContainer connector; - public RemoteParticipantExtension(RemoteParticipant participant, IatpParticipant localParticipant, PostgresExtension postgresql) { + public RemoteParticipantExtension(RemoteParticipant participant, DcpParticipant localParticipant, PostgresExtension postgresql) { this.participant = participant; this.localParticipant = localParticipant; this.postgresql = postgresql; diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/Runtimes.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/Runtimes.java index bacd7d6368..2633d0c1bd 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/Runtimes.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/Runtimes.java @@ -28,7 +28,7 @@ public enum Runtimes { SNAPSHOT_CONNECTOR(":edc-tests:runtime:runtime-compatibility:snapshot:connector-snapshot"), STABLE_CONNECTOR(":edc-tests:runtime:runtime-compatibility:stable:connector-stable"), - IDENTITY_HUB(":edc-tests:runtime:iatp:runtime-memory-sts"); + IDENTITY_HUB(":edc-tests:runtime:dcp:runtime-memory-sts"); private final String[] modules; private URL[] classpathEntries; diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java index 14bd4a7449..2001f2b278 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java @@ -35,8 +35,8 @@ import org.eclipse.tractusx.edc.compatibility.tests.fixtures.Runtimes; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer; -import org.eclipse.tractusx.edc.tests.participant.IatpParticipant; -import org.eclipse.tractusx.edc.tests.participant.TractusxIatpParticipantBase; +import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; +import org.eclipse.tractusx.edc.tests.participant.TractusxDcpParticipantBase; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeAll; @@ -90,7 +90,7 @@ public class TransferEndToEndTest { .trustedIssuer(ISSUER.didUrl()) .build(); - static final IatpParticipant LOCAL_PARTICIPANT = IatpParticipant.Builder.newInstance() + static final DcpParticipant LOCAL_PARTICIPANT = DcpParticipant.Builder.newInstance() .name("local") .id("local") .stsUri(IDENTITY_HUB_PARTICIPANT.getSts()) @@ -113,7 +113,7 @@ public class TransferEndToEndTest { static final RuntimeExtension LOCAL_CONNECTOR = new RuntimePerClassExtension( Runtimes.SNAPSHOT_CONNECTOR.create("local-connector") .configurationProvider(() -> POSTGRES.getConfig(LOCAL_PARTICIPANT.getName())) - .configurationProvider(LOCAL_PARTICIPANT::iatpConfig) + .configurationProvider(LOCAL_PARTICIPANT::dcpConfig) .registerServiceMock(BdrsClient.class, new BdrsClient() { @Override public String resolveDid(String bpn) { @@ -159,7 +159,7 @@ static void beforeAll() { @ParameterizedTest @ArgumentsSource(ParticipantsArgProvider.class) - void httpPullTransfer(TractusxIatpParticipantBase consumer, TractusxIatpParticipantBase provider, String protocol) { + void httpPullTransfer(TractusxDcpParticipantBase consumer, TractusxDcpParticipantBase provider, String protocol) { consumer.setProtocol(protocol); provider.setProtocol(protocol); providerDataSource.stubFor(any(anyUrl()).willReturn(ok("data"))); @@ -193,7 +193,7 @@ void httpPullTransfer(TractusxIatpParticipantBase consumer, TractusxIatpParticip @ParameterizedTest @ArgumentsSource(ParticipantsArgProvider.class) - void suspendAndResume_httpPull_dataTransfer(TractusxIatpParticipantBase consumer, TractusxIatpParticipantBase provider, String protocol) { + void suspendAndResume_httpPull_dataTransfer(TractusxDcpParticipantBase consumer, TractusxDcpParticipantBase provider, String protocol) { consumer.setProtocol(protocol); provider.setProtocol(protocol); providerDataSource.stubFor(any(anyUrl()).willReturn(ok("data"))); @@ -233,7 +233,7 @@ void suspendAndResume_httpPull_dataTransfer(TractusxIatpParticipantBase consumer providerDataSource.verify(getRequestedFor(urlPathEqualTo("/source"))); } - protected void createResourcesOnProvider(TractusxIatpParticipantBase provider, String assetId, JsonObject contractPolicy, Map dataAddressProperties) { + protected void createResourcesOnProvider(TractusxDcpParticipantBase provider, String assetId, JsonObject contractPolicy, Map dataAddressProperties) { provider.createAsset(assetId, Map.of("description", "description"), dataAddressProperties); var contractPolicyId = provider.createPolicyDefinition(contractPolicy); var noConstraintPolicyId = provider.createPolicyDefinition(noConstraintPolicy()); diff --git a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-memory-test.yaml b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-memory-test.yaml index 8d5ca26dde..8c3a043ca9 100644 --- a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-memory-test.yaml +++ b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-memory-test.yaml @@ -24,7 +24,7 @@ fullnameOverride: tx-inmem participant: id: "test-participant" contextId: "test-participant-context" -iatp: +dcp: # Decentralized IDentifier id: "did:web:changeme" sts: diff --git a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml index 9f3a8acaf5..b15477633c 100644 --- a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml +++ b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml @@ -25,7 +25,7 @@ fullnameOverride: tx-prod participant: id: "test-participant" contextId: "test-participant-context" -iatp: +dcp: # Decentralized IDentifier id: "did:web:changeme" sts: diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/IatpParticipant.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java similarity index 96% rename from edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/IatpParticipant.java rename to edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java index a9ce4ec56e..9f23e9844c 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/IatpParticipant.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java @@ -43,7 +43,7 @@ import java.util.List; import java.util.Objects; -public class IatpParticipant extends TractusxIatpParticipantBase { +public class DcpParticipant extends TractusxDcpParticipantBase { protected DidDocument didDocument; public DidDocument getDidDocument() { @@ -129,13 +129,13 @@ public KeyDescriptor createKeyDescriptor() { .build(); } - public static class Builder extends TractusxIatpParticipantBase.Builder { + public static class Builder extends TractusxDcpParticipantBase.Builder { protected Builder() { - this(new IatpParticipant()); + this(new DcpParticipant()); } - protected Builder(IatpParticipant participant) { + protected Builder(DcpParticipant participant) { super(participant); } @@ -144,7 +144,7 @@ public static Builder newInstance() { } @Override - public IatpParticipant build() { + public DcpParticipant build() { super.build(); participant.didDocument = generateDidDocument(); return participant; diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxIatpParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxDcpParticipantBase.java similarity index 91% rename from edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxIatpParticipantBase.java rename to edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxDcpParticipantBase.java index 6d3a336c02..b39a1d26be 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxIatpParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxDcpParticipantBase.java @@ -30,9 +30,9 @@ import static org.eclipse.edc.util.io.Ports.getFreePort; /** - * Specialized version of {@link TractusxParticipantBase} with IATP configurations + * Specialized version of {@link TractusxParticipantBase} with DCP configurations */ -public abstract class TractusxIatpParticipantBase extends TractusxParticipantBase { +public abstract class TractusxDcpParticipantBase extends TractusxParticipantBase { protected final LazySupplier csService = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/api/resolution")); protected LazySupplier divUri; @@ -41,7 +41,7 @@ public abstract class TractusxIatpParticipantBase extends TractusxParticipantBas protected String stsClientId; protected String trustedIssuer; - public Config iatpConfig() { + public Config dcpConfig() { var additionalSettings = Map.of( "edc.iam.sts.oauth.token.url", stsUri.get() + "/token", "edc.iam.sts.oauth.client.id", getDid(), @@ -58,7 +58,7 @@ public Config iatpConfig() { return getConfig().merge(ConfigFactory.fromMap(additionalSettings)); } - public static class Builder

> extends TractusxParticipantBase.Builder { + public static class Builder

> extends TractusxParticipantBase.Builder { protected Builder(P participant) { super(participant); diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java index 7067006b2c..0c9519109e 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java @@ -128,7 +128,7 @@ public Config getConfig() { put("edc.iam.sts.oauth.token.url", "http://sts.example.com/token"); put("edc.iam.sts.oauth.client.id", "test-clientid"); put("edc.iam.sts.oauth.client.secret.alias", "test-clientid-alias"); - put("tx.edc.iam.iatp.bdrs.server.url", "http://sts.example.com"); + put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); put("edc.dataplane.api.public.baseurl", "%s/v2/data".formatted(dataPlanePublic.get())); put("edc.policy.validation.enabled", "true"); put("edc.iam.did.web.use.https", "false"); diff --git a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/RuntimeConfig.java b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/RuntimeConfig.java index 9129f36c8d..43215cc460 100644 --- a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/RuntimeConfig.java +++ b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/RuntimeConfig.java @@ -54,7 +54,7 @@ private static Config baseConfig(LazySupplier controlApi) { put("edc.iam.sts.oauth.client.id", "test-clientid"); put("edc.iam.sts.oauth.client.secret.alias", "test-clientid-alias"); put("tx.edc.iam.sts.div.url", "http://sts.example.com"); - put("tx.edc.iam.iatp.bdrs.server.url", "http://sts.example.com"); + put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); put("edc.transfer.proxy.token.verifier.publickey.alias", "not-used-but-mandatory"); put("edc.transfer.proxy.token.signer.privatekey.alias", "not-used-but-mandatory"); } diff --git a/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java b/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java index 42cb7b7e4c..3aacaed15e 100644 --- a/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java +++ b/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java @@ -234,11 +234,11 @@ private static Config runtimeConfiguration() { put("edc.iam.sts.oauth.token.url", "https://example.com/token"); put("edc.iam.sts.oauth.client.id", "test-client-id"); put("edc.iam.sts.oauth.client.secret.alias", "test-secret-alias"); - put("tx.edc.iam.iatp.bdrs.server.url", "http://sts.example.com"); + put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); //register a default scope https://github.com/eclipse-dataspacetck/dcp-tck?tab=readme-ov-file#232-required-configuration - put("tx.edc.iam.iatp.default-scopes.holderIdentifier.alias", "org.eclipse.dspace.dcp.vc.type"); - put("tx.edc.iam.iatp.default-scopes.holderIdentifier.type", "MembershipCredential"); - put("tx.edc.iam.iatp.default-scopes.holderIdentifier.operation", "read"); + put("tx.edc.iam.dcp.default-scopes.holderIdentifier.alias", "org.eclipse.dspace.dcp.vc.type"); + put("tx.edc.iam.dcp.default-scopes.holderIdentifier.type", "MembershipCredential"); + put("tx.edc.iam.dcp.default-scopes.holderIdentifier.operation", "read"); put("tractusx.edc.participant.bpn", "bpn"); } }); diff --git a/edc-tests/e2e/iatp-tests/build.gradle.kts b/edc-tests/e2e/dcp-tests/build.gradle.kts similarity index 89% rename from edc-tests/e2e/iatp-tests/build.gradle.kts rename to edc-tests/e2e/dcp-tests/build.gradle.kts index ca838f7c3c..2cc8116abc 100644 --- a/edc-tests/e2e/iatp-tests/build.gradle.kts +++ b/edc-tests/e2e/dcp-tests/build.gradle.kts @@ -47,9 +47,9 @@ dependencies { testImplementation(libs.awaitility) testImplementation(libs.bouncyCastle.bcpkixJdk18on) - testCompileOnly(project(":edc-tests:runtime:iatp:runtime-memory-iatp-div-ih")) - testCompileOnly(project(":edc-tests:runtime:iatp:runtime-memory-iatp-ih")) - testCompileOnly(project(":edc-tests:runtime:iatp:runtime-memory-sts")) + testCompileOnly(project(":edc-tests:runtime:dcp:runtime-memory-dcp-div-ih")) + testCompileOnly(project(":edc-tests:runtime:dcp:runtime-memory-dcp-ih")) + testCompileOnly(project(":edc-tests:runtime:dcp:runtime-memory-sts")) } // do not publish diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractIatpConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java similarity index 98% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractIatpConsumerPullTest.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java index c998451717..bc9e127c1b 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractIatpConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java @@ -36,8 +36,8 @@ import org.eclipse.edc.spi.query.Criterion; import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer; -import org.eclipse.tractusx.edc.tests.transfer.iatp.harness.StatusList2021; -import org.eclipse.tractusx.edc.tests.transfer.iatp.harness.StsParticipant; +import org.eclipse.tractusx.edc.tests.transfer.dcp.harness.StatusList2021; +import org.eclipse.tractusx.edc.tests.transfer.dcp.harness.StsParticipant; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; @@ -74,7 +74,7 @@ import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public abstract class AbstractIatpConsumerPullTest extends ConsumerPullBaseTest { +public abstract class AbstractDcpConsumerPullTest extends ConsumerPullBaseTest { protected static final StsParticipant STS = StsParticipant.Builder.newInstance() .id("STS") diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java similarity index 88% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java index 0ee6a1e4cf..726bfe5219 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java @@ -37,10 +37,10 @@ import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer; -import org.eclipse.tractusx.edc.tests.participant.IatpParticipant; +import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; +import org.eclipse.tractusx.edc.tests.transfer.dcp.harness.StsParticipant; import org.eclipse.tractusx.edc.tests.transfer.extension.BdrsServerExtension; import org.eclipse.tractusx.edc.tests.transfer.extension.DidServerExtension; -import org.eclipse.tractusx.edc.tests.transfer.iatp.harness.StsParticipant; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -61,8 +61,8 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; -import static org.eclipse.tractusx.edc.tests.transfer.iatp.runtime.Runtimes.iatpRuntime; -import static org.eclipse.tractusx.edc.tests.transfer.iatp.runtime.Runtimes.stsRuntime; +import static org.eclipse.tractusx.edc.tests.transfer.dcp.runtime.Runtimes.dcpRuntime; +import static org.eclipse.tractusx.edc.tests.transfer.dcp.runtime.Runtimes.stsRuntime; @EndToEndTest public class CredentialSpoofTest { @@ -80,19 +80,19 @@ public class CredentialSpoofTest { @RegisterExtension private static final BdrsServerExtension BDRS_SERVER_EXTENSION = new BdrsServerExtension(DATASPACE_ISSUER_PARTICIPANT.didUrl()); - private static final IatpParticipant CONSUMER = participant(CONSUMER_NAME, CONSUMER_BPN); - private static final IatpParticipant PROVIDER = participant(PROVIDER_NAME, PROVIDER_BPN); - private static final IatpParticipant MALICIOUS_ACTOR = participant("MALICIOUS", "BPNL000MALICIOUS"); + private static final DcpParticipant CONSUMER = participant(CONSUMER_NAME, CONSUMER_BPN); + private static final DcpParticipant PROVIDER = participant(PROVIDER_NAME, PROVIDER_BPN); + private static final DcpParticipant MALICIOUS_ACTOR = participant("MALICIOUS", "BPNL000MALICIOUS"); @RegisterExtension - protected static final RuntimeExtension MALICIOUS_ACTOR_RUNTIME = iatpRuntime(MALICIOUS_ACTOR.getName(), MALICIOUS_ACTOR.getKeyPair(), - () -> MALICIOUS_ACTOR.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); + protected static final RuntimeExtension MALICIOUS_ACTOR_RUNTIME = dcpRuntime(MALICIOUS_ACTOR.getName(), MALICIOUS_ACTOR.getKeyPair(), + () -> MALICIOUS_ACTOR.dcpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); @RegisterExtension - protected static final RuntimeExtension CONSUMER_RUNTIME = iatpRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), - () -> CONSUMER.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); + protected static final RuntimeExtension CONSUMER_RUNTIME = dcpRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), + () -> CONSUMER.dcpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); @RegisterExtension - protected static final RuntimeExtension PROVIDER_RUNTIME = iatpRuntime(PROVIDER.getName(), PROVIDER.getKeyPair(), - () -> PROVIDER.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); + protected static final RuntimeExtension PROVIDER_RUNTIME = dcpRuntime(PROVIDER.getName(), PROVIDER.getKeyPair(), + () -> PROVIDER.dcpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); @RegisterExtension protected static final RuntimeExtension STS_RUNTIME = stsRuntime(STS.getName(), STS.getKeyPair(), () -> STS.stsConfig(CONSUMER, PROVIDER, MALICIOUS_ACTOR).merge(BDRS_SERVER_EXTENSION.getConfig())); @@ -103,8 +103,8 @@ public class CredentialSpoofTest { .options(wireMockConfig().bindAddress("localhost").port(MOCKED_CS_SERVICE_PORT)) .build(); - private static IatpParticipant participant(String name, String bpn) { - return IatpParticipant.Builder.newInstance().name(name).id(bpn) + private static DcpParticipant participant(String name, String bpn) { + return DcpParticipant.Builder.newInstance().name(name).id(bpn) .stsUri(STS.stsUri()) .bpn(bpn) .stsClientId(bpn) diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java similarity index 93% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java index 353060df2b..b160b20a55 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java @@ -39,12 +39,12 @@ import org.eclipse.edc.token.spi.TokenGenerationService; import org.eclipse.edc.transaction.spi.NoopTransactionContext; import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer; -import org.eclipse.tractusx.edc.tests.participant.IatpParticipant; +import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; import org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase; import org.eclipse.tractusx.edc.tests.runtimes.KeyPool; +import org.eclipse.tractusx.edc.tests.transfer.dcp.dispatchers.DivDispatcher; import org.eclipse.tractusx.edc.tests.transfer.extension.BdrsServerExtension; import org.eclipse.tractusx.edc.tests.transfer.extension.DidServerExtension; -import org.eclipse.tractusx.edc.tests.transfer.iatp.dispatchers.DivDispatcher; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -68,13 +68,13 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025_PATH; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; -import static org.eclipse.tractusx.edc.tests.transfer.iatp.runtime.Runtimes.divRuntime; +import static org.eclipse.tractusx.edc.tests.transfer.dcp.runtime.Runtimes.divRuntime; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @EndToEndTest -public class DivConsumerPullTest extends AbstractIatpConsumerPullTest { +public class DivConsumerPullTest extends AbstractDcpConsumerPullTest { @RegisterExtension private static final DidServerExtension DID_SERVER = new DidServerExtension(); @@ -82,7 +82,7 @@ public class DivConsumerPullTest extends AbstractIatpConsumerPullTest { private static final DataspaceIssuer DATASPACE_ISSUER_PARTICIPANT = new DataspaceIssuer(DID_SERVER.didFor("issuer")); private static final LazySupplier DIV_URI = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort())); - private static final IatpParticipant CONSUMER = IatpParticipant.Builder.newInstance() + private static final DcpParticipant CONSUMER = DcpParticipant.Builder.newInstance() .name(CONSUMER_NAME) .id(DID_SERVER.didFor(CONSUMER_NAME)) .stsUri(STS.stsUri()) @@ -93,7 +93,7 @@ public class DivConsumerPullTest extends AbstractIatpConsumerPullTest { .protocol(DSP_2025) .protocolVersionPath(DSP_2025_PATH) .build(); - private static final IatpParticipant PROVIDER = IatpParticipant.Builder.newInstance() + private static final DcpParticipant PROVIDER = DcpParticipant.Builder.newInstance() .name(PROVIDER_NAME) .id(DID_SERVER.didFor(PROVIDER_NAME)) .stsUri(STS.stsUri()) @@ -110,10 +110,10 @@ public class DivConsumerPullTest extends AbstractIatpConsumerPullTest { @RegisterExtension private static final RuntimeExtension CONSUMER_RUNTIME = divRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), - () -> CONSUMER.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); + () -> CONSUMER.dcpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); @RegisterExtension private static final RuntimeExtension PROVIDER_RUNTIME = divRuntime(PROVIDER.getName(), PROVIDER.getKeyPair(), - () -> PROVIDER.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); + () -> PROVIDER.dcpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); private static final TypeManager MAPPER = new JacksonTypeManager(); private static WireMockServer oauthServer; @@ -156,7 +156,7 @@ static void unwind() { divServer.stop(); } - private static EmbeddedSecureTokenService tokenServiceFor(TokenGenerationService tokenGenerationService, IatpParticipant participant, + private static EmbeddedSecureTokenService tokenServiceFor(TokenGenerationService tokenGenerationService, DcpParticipant participant, RuntimeExtension runtime) { StsAccountService stsAccountService = mock(); when(stsAccountService.queryAccounts(any())).thenAnswer(i -> { diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java similarity index 93% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java index 05e60e0368..a3ab55d204 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java @@ -28,7 +28,7 @@ import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.iam.ClaimToken; -import org.eclipse.tractusx.edc.tests.participant.IatpParticipant; +import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -44,7 +44,7 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025; -import static org.eclipse.tractusx.edc.tests.transfer.iatp.runtime.Runtimes.iatpRuntime; +import static org.eclipse.tractusx.edc.tests.transfer.dcp.runtime.Runtimes.dcpRuntime; /** * This test asserts that the ParticipantAgent's identity is determined by the "credentialSubject.holderIdentifier" property. @@ -54,7 +54,7 @@ public class IdentityExtractionTest { private static final LazySupplier STS_URI = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort())); - private static final IatpParticipant CONSUMER = IatpParticipant.Builder.newInstance() + private static final DcpParticipant CONSUMER = DcpParticipant.Builder.newInstance() .name(CONSUMER_NAME) .id("did:example:" + CONSUMER_NAME) .stsUri(STS_URI) @@ -64,7 +64,7 @@ public class IdentityExtractionTest { .build(); @RegisterExtension - private static final RuntimeExtension CONSUMER_RUNTIME = iatpRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), CONSUMER::getConfig); + private static final RuntimeExtension CONSUMER_RUNTIME = dcpRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), CONSUMER::getConfig); @Test void verifyCorrectParticipantAgentId_forDsp08(DataspaceProfileContextRegistry registry) { diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java similarity index 85% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java index 47a74d4650..b0f4391518 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java @@ -26,7 +26,7 @@ import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.tractusx.edc.tests.extension.VaultSeedExtension; import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer; -import org.eclipse.tractusx.edc.tests.participant.IatpParticipant; +import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; import org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase; import org.eclipse.tractusx.edc.tests.runtimes.KeyPool; import org.eclipse.tractusx.edc.tests.transfer.extension.BdrsServerExtension; @@ -42,18 +42,18 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025_PATH; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; -import static org.eclipse.tractusx.edc.tests.transfer.iatp.runtime.Runtimes.iatpRuntime; -import static org.eclipse.tractusx.edc.tests.transfer.iatp.runtime.Runtimes.stsRuntime; +import static org.eclipse.tractusx.edc.tests.transfer.dcp.runtime.Runtimes.dcpRuntime; +import static org.eclipse.tractusx.edc.tests.transfer.dcp.runtime.Runtimes.stsRuntime; @EndToEndTest -public class StsConsumerPullTest extends AbstractIatpConsumerPullTest { +public class StsConsumerPullTest extends AbstractDcpConsumerPullTest { @RegisterExtension private static final DidServerExtension DID_SERVER = new DidServerExtension(); private static final DataspaceIssuer DATASPACE_ISSUER_PARTICIPANT = new DataspaceIssuer(DID_SERVER.didFor("issuer")); - private static final IatpParticipant CONSUMER = IatpParticipant.Builder.newInstance() + private static final DcpParticipant CONSUMER = DcpParticipant.Builder.newInstance() .name(CONSUMER_NAME) .id(DID_SERVER.didFor(CONSUMER_NAME)) .stsUri(STS.stsUri()) @@ -64,7 +64,7 @@ public class StsConsumerPullTest extends AbstractIatpConsumerPullTest { .protocol(DSP_2025) .protocolVersionPath(DSP_2025_PATH) .build(); - private static final IatpParticipant PROVIDER = IatpParticipant.Builder.newInstance() + private static final DcpParticipant PROVIDER = DcpParticipant.Builder.newInstance() .name(PROVIDER_NAME) .id(DID_SERVER.didFor(PROVIDER_NAME)) .stsUri(STS.stsUri()) @@ -80,12 +80,12 @@ public class StsConsumerPullTest extends AbstractIatpConsumerPullTest { private static final BdrsServerExtension BDRS_SERVER_EXTENSION = new BdrsServerExtension(DATASPACE_ISSUER_PARTICIPANT.didUrl()); @RegisterExtension - private static final RuntimeExtension CONSUMER_RUNTIME = iatpRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), - () -> CONSUMER.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); + private static final RuntimeExtension CONSUMER_RUNTIME = dcpRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), + () -> CONSUMER.dcpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); @RegisterExtension - private static final RuntimeExtension PROVIDER_RUNTIME = iatpRuntime(PROVIDER.getName(), PROVIDER.getKeyPair(), - () -> PROVIDER.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())) + private static final RuntimeExtension PROVIDER_RUNTIME = dcpRuntime(PROVIDER.getName(), PROVIDER.getKeyPair(), + () -> PROVIDER.dcpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())) .registerSystemExtension(ServiceExtension.class, new VaultSeedExtension(Map.of("client_secret_alias", "client_secret"))); @RegisterExtension diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DivDispatcher.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/dispatchers/DivDispatcher.java similarity index 98% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DivDispatcher.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/dispatchers/DivDispatcher.java index e53881e667..db4077246f 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DivDispatcher.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/dispatchers/DivDispatcher.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.tests.transfer.iatp.dispatchers; +package org.eclipse.tractusx.edc.tests.transfer.dcp.dispatchers; import com.github.tomakehurst.wiremock.extension.ResponseTransformerV2; import com.github.tomakehurst.wiremock.http.HttpHeader; diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/harness/StatusList2021.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/harness/StatusList2021.java similarity index 97% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/harness/StatusList2021.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/harness/StatusList2021.java index 42c5342153..39bd998a01 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/harness/StatusList2021.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/harness/StatusList2021.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.tests.transfer.iatp.harness; +package org.eclipse.tractusx.edc.tests.transfer.dcp.harness; import jakarta.json.Json; import jakarta.json.JsonObject; diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/harness/StsParticipant.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/harness/StsParticipant.java similarity index 95% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/harness/StsParticipant.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/harness/StsParticipant.java index 539e411c9f..c4029879df 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/harness/StsParticipant.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/harness/StsParticipant.java @@ -17,13 +17,13 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.tests.transfer.iatp.harness; +package org.eclipse.tractusx.edc.tests.transfer.dcp.harness; import org.eclipse.edc.junit.utils.LazySupplier; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.system.configuration.ConfigFactory; -import org.eclipse.tractusx.edc.tests.participant.IatpParticipant; +import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; import org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase; import java.net.URI; @@ -45,7 +45,7 @@ public class StsParticipant extends TractusxParticipantBase { private StsParticipant() { } - public Config stsConfig(IatpParticipant... participants) { + public Config stsConfig(DcpParticipant... participants) { var additionalSettings = Map.of( "web.http.sts.port", String.valueOf(stsUri.get().getPort()), "web.http.sts.path", stsUri.get().getPath(), diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/CredentialWiper.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/CredentialWiper.java similarity index 96% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/CredentialWiper.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/CredentialWiper.java index 9f31229ff7..c96007ad1c 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/CredentialWiper.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/CredentialWiper.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.tests.transfer.iatp.runtime; +package org.eclipse.tractusx.edc.tests.transfer.dcp.runtime; import org.eclipse.edc.identityhub.spi.verifiablecredentials.store.CredentialStore; import org.eclipse.edc.spi.query.QuerySpec; diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/IatpParticipantRuntimeExtension.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/DcpParticipantRuntimeExtension.java similarity index 91% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/IatpParticipantRuntimeExtension.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/DcpParticipantRuntimeExtension.java index 4bc18735a8..fef4e0c070 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/IatpParticipantRuntimeExtension.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/DcpParticipantRuntimeExtension.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.tests.transfer.iatp.runtime; +package org.eclipse.tractusx.edc.tests.transfer.dcp.runtime; import org.eclipse.edc.junit.extensions.EmbeddedRuntime; import org.eclipse.edc.junit.extensions.RuntimePerClassExtension; @@ -35,11 +35,11 @@ import java.security.KeyPair; import java.util.concurrent.atomic.AtomicReference; -public class IatpParticipantRuntimeExtension extends RuntimePerClassExtension implements AfterEachCallback { +public class DcpParticipantRuntimeExtension extends RuntimePerClassExtension implements AfterEachCallback { private final AtomicReference wiper = new AtomicReference<>(); - public IatpParticipantRuntimeExtension(EmbeddedRuntime runtime, KeyPair keyPair) { + public DcpParticipantRuntimeExtension(EmbeddedRuntime runtime, KeyPair keyPair) { super(runtime); registerSystemExtension(ServiceExtension.class, new ServiceExtension() { diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/Runtimes.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/Runtimes.java similarity index 83% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/Runtimes.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/Runtimes.java index c19ee622fe..719e302205 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/Runtimes.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/runtime/Runtimes.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.tests.transfer.iatp.runtime; +package org.eclipse.tractusx.edc.tests.transfer.dcp.runtime; import org.eclipse.edc.iam.did.spi.resolution.DidPublicKeyResolver; import org.eclipse.edc.junit.extensions.EmbeddedRuntime; @@ -36,23 +36,23 @@ public interface Runtimes { static RuntimeExtension divRuntime(String name, KeyPair keyPair, Supplier configurationProvider) { - return genericRuntime(name, ":edc-tests:runtime:iatp:runtime-memory-iatp-div-ih", keyPair, configurationProvider) + return genericRuntime(name, ":edc-tests:runtime:dcp:runtime-memory-dcp-div-ih", keyPair, configurationProvider) .registerSystemExtension(ServiceExtension.class, new VaultSeedExtension(Map.of("client_secret_alias", "client_secret"))); } - static RuntimeExtension iatpRuntime(String name, KeyPair keyPair, Supplier configurationProvider) { - return genericRuntime(name, ":edc-tests:runtime:iatp:runtime-memory-iatp-ih", keyPair, configurationProvider) + static RuntimeExtension dcpRuntime(String name, KeyPair keyPair, Supplier configurationProvider) { + return genericRuntime(name, ":edc-tests:runtime:dcp:runtime-memory-dcp-ih", keyPair, configurationProvider) .registerSystemExtension(ServiceExtension.class, new VaultSeedExtension(Map.of("client_secret_alias", "client_secret"))); } static RuntimeExtension stsRuntime(String name, KeyPair keyPair, Supplier configurationProvider) { - return new RuntimePerClassExtension(new EmbeddedRuntime(name, ":edc-tests:runtime:iatp:runtime-memory-sts").configurationProvider(configurationProvider) + return new RuntimePerClassExtension(new EmbeddedRuntime(name, ":edc-tests:runtime:dcp:runtime-memory-sts").configurationProvider(configurationProvider) .registerSystemExtension(ServiceExtension.class, new VaultSeedExtension(Map.of("client_secret_alias", "client_secret")))) .registerServiceMock(DidPublicKeyResolver.class, keyId -> Result.success(KeyPool.forId(keyId).getPublic())); } private static RuntimeExtension genericRuntime(String name, String moduleName, KeyPair keyPair, Supplier configurationProvider) { - return new IatpParticipantRuntimeExtension( + return new DcpParticipantRuntimeExtension( new EmbeddedRuntime(name, moduleName).configurationProvider(configurationProvider), keyPair ).registerServiceMock(DidPublicKeyResolver.class, keyId -> Result.success(KeyPool.forId(keyId).getPublic())); diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/BdrsServerExtension.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/BdrsServerExtension.java similarity index 97% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/BdrsServerExtension.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/BdrsServerExtension.java index bd82116d9f..94a54e12c5 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/BdrsServerExtension.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/BdrsServerExtension.java @@ -73,7 +73,7 @@ public void afterAll(ExtensionContext context) { public Config getConfig() { return ConfigFactory.fromMap(Map.of( - "tx.edc.iam.iatp.bdrs.server.url", directoryEndpoint.get().toString() + "tx.edc.iam.dcp.bdrs.server.url", directoryEndpoint.get().toString() )); } diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/DidServerExtension.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/DidServerExtension.java similarity index 100% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/DidServerExtension.java rename to edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/extension/DidServerExtension.java diff --git a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java b/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java index 58eb8db163..e802a4b6f8 100644 --- a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java +++ b/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java @@ -115,7 +115,7 @@ private static Config runtimeConfiguration() { put("edc.iam.sts.oauth.token.url", "http://sts.example.com/token"); put("edc.iam.sts.oauth.client.id", "test-client-id"); put("edc.iam.sts.oauth.client.secret.alias", "test-clientid-alias"); - put("tx.edc.iam.iatp.bdrs.server.url", "http://sts.example.com"); + put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); put("web.http.management.auth.key", API_KEY); put("tx.edc.dpf.consumer.proxy.port", String.valueOf(DATA_PLANE_PROXY.getPort())); put("tx.edc.dpf.consumer.proxy.auth.apikey", API_KEY); diff --git a/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/RuntimeConfig.java b/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/RuntimeConfig.java index 479ba2bd46..4829963262 100644 --- a/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/RuntimeConfig.java +++ b/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/RuntimeConfig.java @@ -53,7 +53,7 @@ public Config getConfig() { put("edc.iam.sts.oauth.client.id", "test-clientid"); put("edc.iam.sts.oauth.client.secret.alias", "test-clientid-alias"); put("tx.edc.iam.sts.div.url", "http://sts.example.com"); - put("tx.edc.iam.iatp.bdrs.server.url", "http://sts.example.com"); + put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); } }; diff --git a/edc-tests/runtime/iatp/iatp-extensions/build.gradle.kts b/edc-tests/runtime/dcp/dcp-extensions/build.gradle.kts similarity index 100% rename from edc-tests/runtime/iatp/iatp-extensions/build.gradle.kts rename to edc-tests/runtime/dcp/dcp-extensions/build.gradle.kts diff --git a/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/CredentialsJsonLdExtension.java b/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/CredentialsJsonLdExtension.java similarity index 97% rename from edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/CredentialsJsonLdExtension.java rename to edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/CredentialsJsonLdExtension.java index c4e67b638a..1a9cf351b7 100644 --- a/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/CredentialsJsonLdExtension.java +++ b/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/CredentialsJsonLdExtension.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iatp; +package org.eclipse.tractusx.edc.dcp; import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.runtime.metamodel.annotation.Extension; diff --git a/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/ih/IdentityHubExtension.java b/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/IdentityHubExtension.java similarity index 97% rename from edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/ih/IdentityHubExtension.java rename to edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/IdentityHubExtension.java index 15bc0aa3eb..e40e6e92ef 100644 --- a/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/ih/IdentityHubExtension.java +++ b/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/IdentityHubExtension.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iatp.ih; +package org.eclipse.tractusx.edc.dcp.ih; import org.eclipse.edc.identityhub.spi.transformation.ScopeToCriterionTransformer; import org.eclipse.edc.runtime.metamodel.annotation.Extension; diff --git a/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/ih/TxScopeToCriterionTransformer.java b/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/TxScopeToCriterionTransformer.java similarity index 98% rename from edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/ih/TxScopeToCriterionTransformer.java rename to edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/TxScopeToCriterionTransformer.java index 379582cf2e..ca203347ef 100644 --- a/edc-tests/runtime/iatp/iatp-extensions/src/main/java/org/eclipse/tractusx/edc/iatp/ih/TxScopeToCriterionTransformer.java +++ b/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/TxScopeToCriterionTransformer.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iatp.ih; +package org.eclipse.tractusx.edc.dcp.ih; import org.eclipse.edc.identityhub.spi.transformation.ScopeToCriterionTransformer; import org.eclipse.edc.spi.query.Criterion; diff --git a/edc-tests/runtime/iatp/iatp-extensions/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-tests/runtime/dcp/dcp-extensions/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension similarity index 89% rename from edc-tests/runtime/iatp/iatp-extensions/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension rename to edc-tests/runtime/dcp/dcp-extensions/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index b76f4faafa..90a237eb13 100644 --- a/edc-tests/runtime/iatp/iatp-extensions/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/edc-tests/runtime/dcp/dcp-extensions/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -17,5 +17,5 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -org.eclipse.tractusx.edc.iatp.ih.IdentityHubExtension -org.eclipse.tractusx.edc.iatp.CredentialsJsonLdExtension +org.eclipse.tractusx.edc.dcp.ih.IdentityHubExtension +org.eclipse.tractusx.edc.dcp.CredentialsJsonLdExtension diff --git a/edc-tests/runtime/iatp/iatp-extensions/src/main/resources/cx-credentials-context.json b/edc-tests/runtime/dcp/dcp-extensions/src/main/resources/cx-credentials-context.json similarity index 100% rename from edc-tests/runtime/iatp/iatp-extensions/src/main/resources/cx-credentials-context.json rename to edc-tests/runtime/dcp/dcp-extensions/src/main/resources/cx-credentials-context.json diff --git a/edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/README.md b/edc-tests/runtime/dcp/runtime-memory-dcp-div-ih/README.md similarity index 100% rename from edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/README.md rename to edc-tests/runtime/dcp/runtime-memory-dcp-div-ih/README.md diff --git a/edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-dcp-div-ih/build.gradle.kts similarity index 97% rename from edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/build.gradle.kts rename to edc-tests/runtime/dcp/runtime-memory-dcp-div-ih/build.gradle.kts index 31c062c85f..6934b18da0 100644 --- a/edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-dcp-div-ih/build.gradle.kts @@ -35,7 +35,7 @@ dependencies { implementation(project(":edc-extensions:dcp:tx-dcp")) implementation(project(":edc-extensions:dcp:tx-dcp-sts-div")) - implementation(project(":edc-tests:runtime:iatp:iatp-extensions")) + implementation(project(":edc-tests:runtime:dcp:dcp-extensions")) // use basic (all in-mem) data plane implementation(project(":edc-dataplane:edc-dataplane-base")) { diff --git a/edc-tests/runtime/iatp/runtime-memory-iatp-ih/README.md b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/README.md similarity index 100% rename from edc-tests/runtime/iatp/runtime-memory-iatp-ih/README.md rename to edc-tests/runtime/dcp/runtime-memory-dcp-ih/README.md diff --git a/edc-tests/runtime/iatp/runtime-memory-iatp-ih/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts similarity index 91% rename from edc-tests/runtime/iatp/runtime-memory-iatp-ih/build.gradle.kts rename to edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts index 69b34cc831..463ddbae3e 100644 --- a/edc-tests/runtime/iatp/runtime-memory-iatp-ih/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts @@ -34,7 +34,7 @@ dependencies { implementation(project(":edc-extensions:dcp:cx-dcp")) implementation(project(":edc-extensions:dcp:tx-dcp")) - implementation(project(":edc-tests:runtime:iatp:iatp-extensions")) + implementation(project(":edc-tests:runtime:dcp:dcp-extensions")) // use basic (all in-mem) data plane implementation(project(":edc-dataplane:edc-dataplane-base")) { @@ -42,6 +42,12 @@ dependencies { exclude("org.eclipse.edc", "data-plane-selector-client") } + constraints { + implementation("com.networknt:json-schema-validator:3.0.0") { + because("older versions cause runtime issues") + } + } + implementation(libs.edc.core.controlplane) implementation(libs.edc.core.did) implementation(libs.edc.decentralized.claims.transform) diff --git a/edc-tests/runtime/iatp/runtime-memory-sts/README.md b/edc-tests/runtime/dcp/runtime-memory-sts/README.md similarity index 100% rename from edc-tests/runtime/iatp/runtime-memory-sts/README.md rename to edc-tests/runtime/dcp/runtime-memory-sts/README.md diff --git a/edc-tests/runtime/iatp/runtime-memory-sts/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-sts/build.gradle.kts similarity index 96% rename from edc-tests/runtime/iatp/runtime-memory-sts/build.gradle.kts rename to edc-tests/runtime/dcp/runtime-memory-sts/build.gradle.kts index f4d162928b..64f08ee199 100644 --- a/edc-tests/runtime/iatp/runtime-memory-sts/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-sts/build.gradle.kts @@ -30,7 +30,7 @@ dependencies { implementation(project(":edc-extensions:single-participant-vault")) implementation(project(":core:json-ld-core")) implementation(project(":core:json-ld-cx")) - implementation(project(":edc-tests:runtime:iatp:iatp-extensions")) + implementation(project(":edc-tests:runtime:dcp:dcp-extensions")) implementation(libs.edc.iam.mock) implementation(libs.edc.spi.keys) diff --git a/settings.gradle.kts b/settings.gradle.kts index bcf23f3194..ccd23e0222 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -144,7 +144,7 @@ include(":edc-tests:e2e:edc-dataplane-tokenrefresh-tests") include(":edc-tests:e2e:edr-api-tests") include(":edc-tests:e2e:end2end-transfer-cloud") include(":edc-tests:e2e:management-tests") -include(":edc-tests:e2e:iatp-tests") +include(":edc-tests:e2e:dcp-tests") include(":edc-tests:e2e:policy-tests") include(":edc-tests:e2e:transfer-tests") include("edc-tests:e2e:discovery-tests") @@ -153,10 +153,10 @@ include(":edc-tests:e2e:dsp-compatibility-tests") include(":edc-tests:compatibility-tests") include(":edc-tests:runtime:dataplane-cloud") include(":edc-tests:runtime:runtime-dsp") -include(":edc-tests:runtime:iatp:iatp-extensions") -include(":edc-tests:runtime:iatp:runtime-memory-iatp-div-ih") -include(":edc-tests:runtime:iatp:runtime-memory-iatp-ih") -include(":edc-tests:runtime:iatp:runtime-memory-sts") +include(":edc-tests:runtime:dcp:dcp-extensions") +include(":edc-tests:runtime:dcp:runtime-memory-dcp-div-ih") +include(":edc-tests:runtime:dcp:runtime-memory-dcp-ih") +include(":edc-tests:runtime:dcp:runtime-memory-sts") include(":edc-tests:runtime:mock-connector") include(":edc-tests:runtime:runtime-postgresql") include(":edc-tests:runtime:runtime-dcp-tck") diff --git a/spi/core-spi/src/main/java/org/eclipse/tractusx/edc/TxIatpConstants.java b/spi/core-spi/src/main/java/org/eclipse/tractusx/edc/TxDcpConstants.java similarity index 97% rename from spi/core-spi/src/main/java/org/eclipse/tractusx/edc/TxIatpConstants.java rename to spi/core-spi/src/main/java/org/eclipse/tractusx/edc/TxDcpConstants.java index 994ae363c0..50cf7150a1 100644 --- a/spi/core-spi/src/main/java/org/eclipse/tractusx/edc/TxIatpConstants.java +++ b/spi/core-spi/src/main/java/org/eclipse/tractusx/edc/TxDcpConstants.java @@ -23,7 +23,7 @@ import static java.lang.String.format; -public interface TxIatpConstants { +public interface TxDcpConstants { String CREDENTIAL_TYPE_NAMESPACE = "org.eclipse.tractusx.vc.type"; String MEMBERSHIP_CREDENTIAL = "MembershipCredential"; From edae6b2cd290489cb4fde87f11014bf04d903df2 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Wed, 15 Apr 2026 05:26:28 +0200 Subject: [PATCH 027/259] infra: Migrate helm charts to use cloud pirates postgres charts (#2693) * Migrate helm charts to use cloud pirates postgres charts Signed-off-by: Lars Geyer-Blaumeiser * Update helm docs Signed-off-by: Lars Geyer-Blaumeiser * Switch postgres enablement Signed-off-by: Lars Geyer-Blaumeiser * helm docs again Signed-off-by: Lars Geyer-Blaumeiser * Adopt dependency test helm values Signed-off-by: Lars Geyer-Blaumeiser * Harmonize vault usage with bdrs Signed-off-by: Lars Geyer-Blaumeiser * Helm Docs update Signed-off-by: Lars Geyer-Blaumeiser --------- Signed-off-by: Lars Geyer-Blaumeiser --- charts/tractusx-connector/Chart.yaml | 8 +++---- charts/tractusx-connector/README.md | 17 +++++++++------ charts/tractusx-connector/values.yaml | 21 ++++++++++++------- .../2026_06-Version_0.12.x_0.13.x.md | 16 ++++++++++++-- .../helm/tractusx-connector-test.yaml | 8 ------- 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/charts/tractusx-connector/Chart.yaml b/charts/tractusx-connector/Chart.yaml index ff4e000e0e..e5a42226c9 100644 --- a/charts/tractusx-connector/Chart.yaml +++ b/charts/tractusx-connector/Chart.yaml @@ -54,12 +54,12 @@ dependencies: # HashiCorp Vault - name: vault alias: vault - version: "0.27.0" + version: "0.28.0" repository: https://helm.releases.hashicorp.com condition: install.vault # PostgreSQL - - name: postgresql + - name: postgres alias: postgresql - version: "15.2.1" - repository: https://charts.bitnami.com/bitnami + version: "0.18.3" + repository: oci://registry-1.docker.io/cloudpirates condition: install.postgresql diff --git a/charts/tractusx-connector/README.md b/charts/tractusx-connector/README.md index cbaa7514e0..207ce32d99 100644 --- a/charts/tractusx-connector/README.md +++ b/charts/tractusx-connector/README.md @@ -56,8 +56,8 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | Repository | Name | Version | |------------|------|---------| -| https://charts.bitnami.com/bitnami | postgresql(postgresql) | 15.2.1 | -| https://helm.releases.hashicorp.com | vault(vault) | 0.27.0 | +| https://helm.releases.hashicorp.com | vault(vault) | 0.28.0 | +| oci://registry-1.docker.io/cloudpirates | postgresql(postgres) | 0.18.3 | ## Values @@ -284,11 +284,16 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | postgresql.auth.database | string | `"edc"` | | | postgresql.auth.password | string | `"password"` | | | postgresql.auth.username | string | `"user"` | | -| postgresql.image.repository | string | `"bitnamilegacy/postgresql"` | | -| postgresql.image.tag | string | `"16.2.0-debian-12-r10"` | | +| postgresql.image.registry | string | `"docker.io"` | | +| postgresql.image.repository | string | `"postgres"` | | | postgresql.jdbcUrl | string | `"jdbc:postgresql://{{ .Release.Name }}-postgresql:5432/edc"` | | -| postgresql.primary.persistence.enabled | bool | `false` | | -| postgresql.readReplicas.persistence.enabled | bool | `false` | | +| postgresql.persistence.enabled | bool | `false` | | +| postgresql.persistence.size | string | `"10Gi"` | | +| postgresql.persistence.storageClass | string | `"standard"` | | +| postgresql.resources.limits.cpu | int | `1` | | +| postgresql.resources.limits.memory | string | `"1Gi"` | | +| postgresql.resources.requests.cpu | string | `"250m"` | | +| postgresql.resources.requests.memory | string | `"256Mi"` | | | serviceAccount.annotations | object | `{}` | Annotations to add to the service account | | serviceAccount.create | bool | `true` | Specifies whether a service account should be created | | serviceAccount.imagePullSecrets | list | `[]` | Existing image pull secret bound to the service account to use to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) | diff --git a/charts/tractusx-connector/values.yaml b/charts/tractusx-connector/values.yaml index bbd596835c..fb5fdd2c6f 100644 --- a/charts/tractusx-connector/values.yaml +++ b/charts/tractusx-connector/values.yaml @@ -625,15 +625,20 @@ dataplane: postgresql: image: - repository: "bitnamilegacy/postgresql" - tag: "16.2.0-debian-12-r10" + registry: docker.io + repository: postgres jdbcUrl: "jdbc:postgresql://{{ .Release.Name }}-postgresql:5432/edc" - primary: - persistence: - enabled: false - readReplicas: - persistence: - enabled: false + persistence: + enabled: false + size: 10Gi + storageClass: standard + resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 250m + memory: 256Mi auth: database: "edc" username: "user" diff --git a/docs/migration/2026_06-Version_0.12.x_0.13.x.md b/docs/migration/2026_06-Version_0.12.x_0.13.x.md index fa465ce168..a58f9fe1f3 100644 --- a/docs/migration/2026_06-Version_0.12.x_0.13.x.md +++ b/docs/migration/2026_06-Version_0.12.x_0.13.x.md @@ -8,7 +8,9 @@ This document is not a comprehensive feature list. * [Migration Guide `0.12.x -> 0.13.x`](#migration-guide-012x---013x) - * [1. Federate Catalog removal](#2-federate-catalog-removal) + * [1. Federate Catalog removal](#1-federate-catalog-removal) + * [2. Deprecated instances](#2-deprecated-instances) + * [3. Postgres Version](#3-postgres-version) ## 1. Federate Catalog removal @@ -37,4 +39,14 @@ Please use the updated configuration parameters instead. | `edc.datasource.edr.name` | `edc.sql.store.edr.datasource` | `EDC_SQL_STORE_EDR_DATASOURCE` | -[2026_06-Version_0.12.x_0.13.x.md](2026_06-Version_0.12.x_0.13.x.md) \ No newline at end of file +[2026_06-Version_0.12.x_0.13.x.md](2026_06-Version_0.12.x_0.13.x.md) + +## 3. Postgres Version + +The new version provides Postgres version 18.0 as dependency in the helm charts referring to the Cloud Pirates +helm charts and the official Postgres docker image instead of the formerly used bitnami charts and docker images. + +As a consequence, for a Kubernetes setup done with the provided helm charts, there is no possibility to do an automatic +upgrade with the provided helm charts, as the two images are not supporting that. Instead, during update, an operator +has to follow the general +[migration guide](https://github.com/eclipse-tractusx/tutorial-resources/blob/main/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md#:~:text=GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md-,GENERIC_POSTGRESQL_MIGRATION_GUIDE,-.md) diff --git a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml index b15477633c..097522d919 100644 --- a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml +++ b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml @@ -80,14 +80,6 @@ dataplane: privatekey_alias: "key-1" verifier: publickey_alias: "key-1" -postgresql: - image: - repository: "bitnamilegacy/postgresql" - tag: "16.2.0-debian-12-r10" - jdbcUrl: jdbc:postgresql://{{ .Release.Name }}-postgresql:5432/edc - auth: - username: user - password: password vault: hashicorp: url: http://{{ .Release.Name }}-vault:8200 From 47ea85136ce3cfcbf84c0fd2bc97a4d7f88dc66e Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Wed, 15 Apr 2026 05:32:12 +0200 Subject: [PATCH 028/259] feat: Use participant context id as identifier for did document registration (#2744) * Use participant context id as identifier for did document registration Signed-off-by: Lars Geyer-Blaumeiser * Fix checkstyle issues Signed-off-by: Lars Geyer-Blaumeiser --------- Signed-off-by: Lars Geyer-Blaumeiser --- charts/tractusx-connector-memory/README.md | 1 - .../templates/deployment-runtime.yaml | 2 - charts/tractusx-connector-memory/values.yaml | 2 - charts/tractusx-connector/README.md | 1 - .../templates/deployment-controlplane.yaml | 2 - charts/tractusx-connector/values.yaml | 2 - .../build.gradle.kts | 1 + ...umentServiceSelfRegistrationExtension.java | 19 ++++- ...tServiceSelfRegistrationExtensionTest.java | 74 +++---------------- 9 files changed, 26 insertions(+), 78 deletions(-) diff --git a/charts/tractusx-connector-memory/README.md b/charts/tractusx-connector-memory/README.md index 2246422e66..400963fa2b 100644 --- a/charts/tractusx-connector-memory/README.md +++ b/charts/tractusx-connector-memory/README.md @@ -59,7 +59,6 @@ helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0- | dcp.cache.enabled | bool | `true` | Whether the Verifiable Presentation cache is enabled | | dcp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | | dcp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | -| dcp.didService.selfRegistration.id | string | `"did:web:changeme"` | Unique id of connector to be used for register / unregister service inside did document (must be valid URI) | | dcp.id | string | `"did:web:changeme"` | Decentralized IDentifier (DID) of the connector | | dcp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | | dcp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | diff --git a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml index af1e18c961..10598a4a6f 100644 --- a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml +++ b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml @@ -254,8 +254,6 @@ spec: value: {{ .Values.dcp.didService.selfRegistration.enabled | quote}} - name: "TX_EDC_DID_SERVICE_SELF_DEREGISTRATION_ENABLED" value: "false" - - name: "TX_EDC_DID_SERVICE_SELF_REGISTRATION_ID" - value: {{ .Values.dcp.didService.selfRegistration.id | quote }} - name: "TX_EDC_DCP_CACHE_ENABLED" value: {{ .Values.dcp.cache.enabled | quote }} - name: "TX_EDC_DCP_CACHE_VALIDITY_SECONDS" diff --git a/charts/tractusx-connector-memory/values.yaml b/charts/tractusx-connector-memory/values.yaml index f8e40b66de..dbd9cdc3b6 100644 --- a/charts/tractusx-connector-memory/values.yaml +++ b/charts/tractusx-connector-memory/values.yaml @@ -63,8 +63,6 @@ dcp: selfRegistration: # -- Whether Service Self Registration is enabled enabled: false - # -- Unique id of connector to be used for register / unregister service inside did document (must be valid URI) - id: "did:web:changeme" # - Configures the Verifiable Presentation Ccache cache: diff --git a/charts/tractusx-connector/README.md b/charts/tractusx-connector/README.md index 207ce32d99..cef92770ae 100644 --- a/charts/tractusx-connector/README.md +++ b/charts/tractusx-connector/README.md @@ -260,7 +260,6 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | dcp.cache.enabled | bool | `true` | Whether the Verifiable Presentation cache is enabled | | dcp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | | dcp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | -| dcp.didService.selfRegistration.id | string | `"did:web:changeme"` | Unique id of connector to be used for register / unregister service inside did document (must be valid URI) | | dcp.id | string | `"did:web:changeme"` | Decentralized IDentifier (DID) of the connector | | dcp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | | dcp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | diff --git a/charts/tractusx-connector/templates/deployment-controlplane.yaml b/charts/tractusx-connector/templates/deployment-controlplane.yaml index 0b6e1e66ba..c6f2e6f1d8 100644 --- a/charts/tractusx-connector/templates/deployment-controlplane.yaml +++ b/charts/tractusx-connector/templates/deployment-controlplane.yaml @@ -252,8 +252,6 @@ spec: value: {{ .Values.dcp.didService.selfRegistration.enabled | quote}} - name: "TX_EDC_DID_SERVICE_SELF_DEREGISTRATION_ENABLED" value: {{ and (eq (int .Values.controlplane.replicaCount) 1) (not .Values.controlplane.autoscaling.enabled) | quote }} - - name: "TX_EDC_DID_SERVICE_SELF_REGISTRATION_ID" - value: {{ .Values.dcp.didService.selfRegistration.id | quote }} - name: "TX_EDC_DCP_CACHE_ENABLED" value: {{ .Values.dcp.cache.enabled | quote }} - name: "TX_EDC_DCP_CACHE_VALIDITY_SECONDS" diff --git a/charts/tractusx-connector/values.yaml b/charts/tractusx-connector/values.yaml index fb5fdd2c6f..165aeff027 100644 --- a/charts/tractusx-connector/values.yaml +++ b/charts/tractusx-connector/values.yaml @@ -70,8 +70,6 @@ dcp: selfRegistration: # -- Whether Service Self Registration is enabled enabled: false - # -- Unique id of connector to be used for register / unregister service inside did document (must be valid URI) - id: "did:web:changeme" # - Configures the Verifiable Presentation cache cache: # -- Whether the Verifiable Presentation cache is enabled diff --git a/edc-extensions/did-document/did-document-service-self-registration/build.gradle.kts b/edc-extensions/did-document/did-document-service-self-registration/build.gradle.kts index df7f00fb2b..a013e5ed59 100644 --- a/edc-extensions/did-document/did-document-service-self-registration/build.gradle.kts +++ b/edc-extensions/did-document/did-document-service-self-registration/build.gradle.kts @@ -25,6 +25,7 @@ plugins { dependencies { implementation(project(":spi:did-document-service-spi")) implementation(libs.edc.runtime.metamodel) + implementation(libs.edc.spi.participant.context.single) implementation(libs.edc.spi.identity.did) implementation(libs.dsp.spi.http) diff --git a/edc-extensions/did-document/did-document-service-self-registration/src/main/java/org/eclipse/tractusx/edc/did/document/service/self/registration/DidDocumentServiceSelfRegistrationExtension.java b/edc-extensions/did-document/did-document-service-self-registration/src/main/java/org/eclipse/tractusx/edc/did/document/service/self/registration/DidDocumentServiceSelfRegistrationExtension.java index a4c2e9e8ad..1fabf1b1f9 100644 --- a/edc-extensions/did-document/did-document-service-self-registration/src/main/java/org/eclipse/tractusx/edc/did/document/service/self/registration/DidDocumentServiceSelfRegistrationExtension.java +++ b/edc-extensions/did-document/did-document-service-self-registration/src/main/java/org/eclipse/tractusx/edc/did/document/service/self/registration/DidDocumentServiceSelfRegistrationExtension.java @@ -20,6 +20,7 @@ package org.eclipse.tractusx.edc.did.document.service.self.registration; import org.eclipse.edc.iam.did.spi.document.Service; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; import org.eclipse.edc.protocol.dsp.http.spi.api.DspBaseWebhookAddress; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Setting; @@ -51,13 +52,15 @@ public class DidDocumentServiceSelfRegistrationExtension implements ServiceExten @Inject(required = false) private DidDocumentServiceClient didDocumentServiceClient; + @Inject + private SingleParticipantContextSupplier participantContextSupplier; + @Setting(key = TX_EDC_DID_SERVICE_SELF_REGISTRATION_ENABLED, defaultValue = "false", description = "Enable self-registration of the DID Document Service") private boolean selfRegistrationEnabled; @Setting(key = TX_EDC_DID_SERVICE_SELF_DEREGISTRATION_ENABLED, defaultValue = "false", description = "Enable self-deregistration of the DID Document Service") private boolean selfDeregistrationEnabled; - @Setting(key = TX_EDC_DID_SERVICE_SELF_REGISTRATION_ID, required = false, description = "The Id to use for service self-registration (should be valid URI)") private String serviceId; @Override @@ -78,7 +81,7 @@ public void shutdown() { private void selfRegisterDidDocumentService(@NotNull DidDocumentServiceClient client) { var wellKnownUrl = String.join("", dspBaseAddress.get(), VERSION_METADATA_ENDPOINT_PATH); - validatedServiceId(serviceId) + validatedServiceId(getServiceId()) .onFailure(failure -> monitor.severe(failure.getFailureDetail())) .map(validatedServiceId -> new Service(validatedServiceId, DATA_SERVICE_TYPE, wellKnownUrl)) .onSuccess(service -> @@ -90,7 +93,7 @@ private void selfRegisterDidDocumentService(@NotNull DidDocumentServiceClient cl private void selfUnregisterDidDocumentService(@NotNull DidDocumentServiceClient client) { - validatedServiceId(serviceId) + validatedServiceId(getServiceId()) .onSuccess(validatedServiceId -> client.deleteById(validatedServiceId) .onFailure(failure -> monitor.severe("Failed to unregister DID Document service: %s, reason: %s".formatted(failure.getFailureDetail(), failure.getReason()))) @@ -98,6 +101,16 @@ private void selfUnregisterDidDocumentService(@NotNull DidDocumentServiceClient ); } + private String getServiceId() { + if (serviceId == null) { + var participantContext = participantContextSupplier.get(); + if (participantContext != null && participantContext.succeeded()) { + serviceId = "urn:" + participantContext.getContent().getParticipantContextId(); + } + } + return serviceId; + } + private Result validatedServiceId(String serviceId) { if (serviceId == null || serviceId.isBlank()) { diff --git a/edc-extensions/did-document/did-document-service-self-registration/src/test/java/org/eclipse/tractusx/edc/did/document/service/self/registration/DidDocumentServiceSelfRegistrationExtensionTest.java b/edc-extensions/did-document/did-document-service-self-registration/src/test/java/org/eclipse/tractusx/edc/did/document/service/self/registration/DidDocumentServiceSelfRegistrationExtensionTest.java index 939196717a..505f71f24d 100644 --- a/edc-extensions/did-document/did-document-service-self-registration/src/test/java/org/eclipse/tractusx/edc/did/document/service/self/registration/DidDocumentServiceSelfRegistrationExtensionTest.java +++ b/edc-extensions/did-document/did-document-service-self-registration/src/test/java/org/eclipse/tractusx/edc/did/document/service/self/registration/DidDocumentServiceSelfRegistrationExtensionTest.java @@ -22,6 +22,8 @@ import org.eclipse.edc.boot.system.injection.ObjectFactory; import org.eclipse.edc.iam.did.spi.document.Service; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; import org.eclipse.edc.protocol.dsp.http.spi.api.DspBaseWebhookAddress; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.ServiceResult; @@ -31,9 +33,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EmptySource; -import org.junit.jupiter.params.provider.ValueSource; import java.util.Map; @@ -50,7 +49,8 @@ @ExtendWith(DependencyInjectionExtension.class) class DidDocumentServiceSelfRegistrationExtensionTest { - private static final String SERVICE_ID = "did:web:example.com:connector1"; + private static final String PARTICIPANT_CONTEXT_ID = "019d8c8d-42ed-7739-b413-eed5dfd74b41"; + private static final String SERVICE_ID = "urn:" + PARTICIPANT_CONTEXT_ID; private static final String DSP_URL = "https://protocol.edc.com/api/v1/dsp"; private final Monitor monitor = mock(Monitor.class); @@ -61,6 +61,9 @@ class DidDocumentServiceSelfRegistrationExtensionTest { void setup(ServiceExtensionContext context) { context.registerService(Monitor.class, monitor); context.registerService(DspBaseWebhookAddress.class, dspBaseAddress); + var participantContext = ParticipantContext.Builder.newInstance().participantContextId(PARTICIPANT_CONTEXT_ID) + .identity("did:web:example.com").build(); + context.registerService(SingleParticipantContextSupplier.class, () -> ServiceResult.success(participantContext)); when(dspBaseAddress.get()).thenReturn(DSP_URL); } @@ -68,8 +71,7 @@ void setup(ServiceExtensionContext context) { void start_shouldSelfRegister_whenEnabledAndClientPresent(ServiceExtensionContext context, ObjectFactory objectFactory) { var settings = Map.of("tx.edc.did.service.self.registration.enabled", "true", - "tx.edc.did.service.self.deregistration.enabled", "true", - "tx.edc.did.service.self.registration.id", SERVICE_ID); + "tx.edc.did.service.self.deregistration.enabled", "true"); when(context.getConfig()).thenReturn(ConfigFactory.fromMap(settings)); context.registerService(DidDocumentServiceClient.class, didDocumentServiceClient); when(didDocumentServiceClient.update(any(Service.class))).thenReturn(ServiceResult.success()); @@ -94,8 +96,7 @@ void start_shouldSelfRegister_whenEnabledAndClientPresent(ServiceExtensionContex void start_selfRegister_whenEnabledAndClientReturnsFailure(ServiceExtensionContext context, ObjectFactory objectFactory) { var settings = Map.of("tx.edc.did.service.self.registration.enabled", "true", - "tx.edc.did.service.self.deregistration.enabled", "true", - "tx.edc.did.service.self.registration.id", SERVICE_ID); + "tx.edc.did.service.self.deregistration.enabled", "true"); when(context.getConfig()).thenReturn(ConfigFactory.fromMap(settings)); context.registerService(DidDocumentServiceClient.class, didDocumentServiceClient); when(didDocumentServiceClient.update(any(Service.class))).thenReturn(ServiceResult.unexpected()); @@ -145,61 +146,4 @@ void start_shouldNotSelfRegister_whenDisabledAndClientPresent(ServiceExtensionCo extension.shutdown(); verify(didDocumentServiceClient, never()).deleteById(anyString()); } - - @Test - void start_shouldNotSelfRegister_whenEnabledAndServiceIdMissing(ServiceExtensionContext context, ObjectFactory objectFactory) { - - var settings = Map.of("tx.edc.did.service.self.registration.enabled", "true", "tx.edc.did.service.self.deregistration.enabled", "true"); - when(context.getConfig()).thenReturn(ConfigFactory.fromMap(settings)); - context.registerService(DidDocumentServiceClient.class, didDocumentServiceClient); - - var extension = objectFactory.constructInstance(DidDocumentServiceSelfRegistrationExtension.class); - extension.start(); - - verify(didDocumentServiceClient, never()).update(any(Service.class)); - verify(monitor).severe(contains("is missing or blank but self-registration / de-registration is enabled")); - - extension.shutdown(); - verify(didDocumentServiceClient, never()).deleteById(anyString()); - } - - @ParameterizedTest - @EmptySource - @ValueSource(strings = {" "}) - void start_shouldNotSelfRegister_whenEnabledAndServiceIdEmptyOrBlank(String serviceId, ServiceExtensionContext context, ObjectFactory objectFactory) { - - var settings = Map.of("tx.edc.did.service.self.registration.enabled", "true", - "tx.edc.did.service.self.dregistration.enabled", "true", - "tx.edc.did.service.self.registration.id", serviceId); - when(context.getConfig()).thenReturn(ConfigFactory.fromMap(settings)); - context.registerService(DidDocumentServiceClient.class, didDocumentServiceClient); - - var extension = objectFactory.constructInstance(DidDocumentServiceSelfRegistrationExtension.class); - extension.start(); - - verify(didDocumentServiceClient, never()).update(any(Service.class)); - verify(monitor).severe(contains("is missing or blank but self-registration / de-registration is enabled")); - - extension.shutdown(); - verify(didDocumentServiceClient, never()).deleteById(anyString()); - } - - @Test - void start_shouldNotSelfRegister_whenEnabledAndServiceIdInvalid(ServiceExtensionContext context, ObjectFactory objectFactory) { - - var settings = Map.of("tx.edc.did.service.self.registration.enabled", "true", - "tx.edc.did.service.self.deregistration.enabled", "true", - "tx.edc.did.service.self.registration.id", "invalid uri"); - when(context.getConfig()).thenReturn(ConfigFactory.fromMap(settings)); - context.registerService(DidDocumentServiceClient.class, didDocumentServiceClient); - - var extension = objectFactory.constructInstance(DidDocumentServiceSelfRegistrationExtension.class); - extension.start(); - - verify(didDocumentServiceClient, never()).update(any(Service.class)); - verify(monitor).severe(contains("does not contain a valid URI")); - - extension.shutdown(); - verify(didDocumentServiceClient, never()).deleteById(anyString()); - } } From 63d6e20e3883d92f2636fb1b02b401791cc8c84d Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Wed, 15 Apr 2026 08:46:01 +0200 Subject: [PATCH 029/259] Adapt participant id in helm charts (#2742) Signed-off-by: Lars Geyer-Blaumeiser --- charts/tractusx-connector-memory/README.md | 4 ++-- .../templates/deployment-runtime.yaml | 6 +++--- charts/tractusx-connector-memory/values.yaml | 8 ++++---- charts/tractusx-connector/README.md | 4 ++-- .../templates/deployment-controlplane.yaml | 6 +++--- .../templates/deployment-dataplane.yaml | 2 +- charts/tractusx-connector/values.yaml | 8 ++++---- .../resources/helm/tractusx-connector-memory-test.yaml | 5 ++--- .../src/main/resources/helm/tractusx-connector-test.yaml | 5 ++--- 9 files changed, 23 insertions(+), 25 deletions(-) diff --git a/charts/tractusx-connector-memory/README.md b/charts/tractusx-connector-memory/README.md index 400963fa2b..9450a8b681 100644 --- a/charts/tractusx-connector-memory/README.md +++ b/charts/tractusx-connector-memory/README.md @@ -59,7 +59,6 @@ helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0- | dcp.cache.enabled | bool | `true` | Whether the Verifiable Presentation cache is enabled | | dcp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | | dcp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | -| dcp.id | string | `"did:web:changeme"` | Decentralized IDentifier (DID) of the connector | | dcp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | | dcp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | | dcp.sts.oauth.client.secret_alias | string | `nil` | Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access | @@ -70,8 +69,9 @@ helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0- | log4j2.config | string | `"Appenders:\n Console:\n name: CONSOLE\n JsonTemplateLayout:\n eventTemplate: |-\n {\n \"timestamp\": {\n \"$resolver\": \"timestamp\",\n \"pattern\": {\n \"format\": \"yyyy-MM-dd'T'HH:mm:ss.SSSSSSS\",\n \"timeZone\": \"UTC\"\n }\n },\n \"level\": {\n \"$resolver\": \"level\",\n \"field\": \"severity\",\n \"severity\": {\n \"field\": \"keyword\"\n }\n },\n \"message\": {\n \"$resolver\": \"message\"\n }\n }\nLoggers:\n Root:\n level: \"OFF\"\n Logger:\n name: org.eclipse.edc.monitor.logger\n level: DEBUG\n AppenderRef:\n ref: CONSOLE"` | Log4j2 configuration for json log formatting. | | log4j2.enableJsonLogs | bool | `true` | Whether to enable the json log config in log4j2.config | | nameOverride | string | `""` | | +| participant.bpnl | string | `"BPNLCHANGEME"` | BPNL Number | | participant.contextId | string | `"UUID CHANGEME"` | Participant Context Id - Newly introduced id for a connector instance (needed for multitenancy) | -| participant.id | string | `"BPNLCHANGEME"` | BPN Number | +| participant.id | string | `"did:web:changeme"` | Participant Id, resp. the Decentralized IDentifier (DID) of the connector | | runtime.affinity | object | `{}` | [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) to configure which nodes the pods can be scheduled on | | runtime.autoscaling.enabled | bool | `false` | Enables [horizontal pod autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) | | runtime.autoscaling.maxReplicas | int | `100` | Maximum replicas if resource consumption exceeds resource threshholds | diff --git a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml index 10598a4a6f..c1ae50676c 100644 --- a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml +++ b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml @@ -146,13 +146,13 @@ spec: ## ID CONFIGURATION ## ######################## - name: EDC_PARTICIPANT_ID - value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote }} + value: {{ .Values.participant.id | required ".Values.participant.id is required" | quote }} - name: "EDC_IAM_ISSUER_ID" - value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote }} + value: {{ .Values.participant.id | required ".Values.participant.id is required" | quote }} - name: "EDC_PARTICIPANT_CONTEXT_ID" value: {{ .Values.participant.contextId | required ".Values.participant.contextId is required" | quote }} - name: "TRACTUSX_EDC_PARTICIPANT_BPN" - value: {{ .Values.participant.id | required ".Values.participant.id is required" | quote }} + value: {{ .Values.participant.bpnl | required ".Values.participant.bpnl is required" | quote }} ########################### ## LOGGING CONFIGURATION ## diff --git a/charts/tractusx-connector-memory/values.yaml b/charts/tractusx-connector-memory/values.yaml index dbd9cdc3b6..af90752eaf 100644 --- a/charts/tractusx-connector-memory/values.yaml +++ b/charts/tractusx-connector-memory/values.yaml @@ -33,14 +33,14 @@ imagePullSecrets: [] customLabels: {} participant: - # -- BPN Number - id: "BPNLCHANGEME" + # -- Participant Id, resp. the Decentralized IDentifier (DID) of the connector + id: "did:web:changeme" + # -- BPNL Number + bpnl: "BPNLCHANGEME" # -- Participant Context Id - Newly introduced id for a connector instance (needed for multitenancy) contextId: "UUID CHANGEME" dcp: - # -- Decentralized IDentifier (DID) of the connector - id: "did:web:changeme" # -- Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer trustedIssuers: [] # - id: "did:web:example1.com" diff --git a/charts/tractusx-connector/README.md b/charts/tractusx-connector/README.md index cef92770ae..39122368c1 100644 --- a/charts/tractusx-connector/README.md +++ b/charts/tractusx-connector/README.md @@ -260,7 +260,6 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | dcp.cache.enabled | bool | `true` | Whether the Verifiable Presentation cache is enabled | | dcp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | | dcp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | -| dcp.id | string | `"did:web:changeme"` | Decentralized IDentifier (DID) of the connector | | dcp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | | dcp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | | dcp.sts.oauth.client.secret_alias | string | `nil` | Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access | @@ -278,8 +277,9 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | networkPolicy.dataplane | object | `{"from":[{"namespaceSelector":{}}]}` | Configuration of the dataplane component | | networkPolicy.dataplane.from | list | `[{"namespaceSelector":{}}]` | Specify from rule network policy for dp (defaults to all namespaces) | | networkPolicy.enabled | bool | `false` | If `true` network policy will be created to restrict access to control- and dataplane | +| participant.bpnl | string | `"BPNLCHANGEME"` | BPNL Number | | participant.contextId | string | `"UUID CHANGEME"` | Participant Context Id - Newly introduced id for a connector instance (needed for multitenancy) | -| participant.id | string | `"BPNLCHANGEME"` | BPN Number | +| participant.id | string | `"did:web:changeme"` | Participant Id, resp. the Decentralized IDentifier (DID) of the connector | | postgresql.auth.database | string | `"edc"` | | | postgresql.auth.password | string | `"password"` | | | postgresql.auth.username | string | `"user"` | | diff --git a/charts/tractusx-connector/templates/deployment-controlplane.yaml b/charts/tractusx-connector/templates/deployment-controlplane.yaml index c6f2e6f1d8..6b8cb6b5e8 100644 --- a/charts/tractusx-connector/templates/deployment-controlplane.yaml +++ b/charts/tractusx-connector/templates/deployment-controlplane.yaml @@ -147,13 +147,13 @@ spec: ## ID CONFIGURATION ## ######################## - name: EDC_PARTICIPANT_ID - value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote }} + value: {{ .Values.participant.id | required ".Values.participant.id is required" | quote }} - name: "EDC_IAM_ISSUER_ID" - value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote }} + value: {{ .Values.participant.id | required ".Values.participant.id is required" | quote }} - name: "EDC_PARTICIPANT_CONTEXT_ID" value: {{ .Values.participant.contextId | required ".Values.participant.contextId is required" | quote }} - name: "TRACTUSX_EDC_PARTICIPANT_BPN" - value: {{ .Values.participant.id | required ".Values.participant.id is required" | quote }} + value: {{ .Values.participant.bpnl | required ".Values.participant.bpnl is required" | quote }} ########################### ## LOGGING CONFIGURATION ## diff --git a/charts/tractusx-connector/templates/deployment-dataplane.yaml b/charts/tractusx-connector/templates/deployment-dataplane.yaml index f55714afce..c396b3ef4c 100644 --- a/charts/tractusx-connector/templates/deployment-dataplane.yaml +++ b/charts/tractusx-connector/templates/deployment-dataplane.yaml @@ -149,7 +149,7 @@ spec: - name: EDC_PARTICIPANT_CONTEXT_ID value: {{ .Values.participant.contextId | required ".Values.participant.contextId is required" | quote}} - name: "EDC_IAM_ISSUER_ID" - value: {{ .Values.dcp.id | required ".Values.dcp.id is required" | quote}} + value: {{ .Values.participant.id | required ".Values.participant.id is required" | quote}} ########################### ## LOGGING CONFIGURATION ## diff --git a/charts/tractusx-connector/values.yaml b/charts/tractusx-connector/values.yaml index 165aeff027..469c1b878c 100644 --- a/charts/tractusx-connector/values.yaml +++ b/charts/tractusx-connector/values.yaml @@ -40,14 +40,14 @@ imagePullSecrets: [] customLabels: {} participant: - # -- BPN Number - id: "BPNLCHANGEME" + # -- Participant Id, resp. the Decentralized IDentifier (DID) of the connector + id: "did:web:changeme" + # -- BPNL Number + bpnl: "BPNLCHANGEME" # -- Participant Context Id - Newly introduced id for a connector instance (needed for multitenancy) contextId: "UUID CHANGEME" dcp: - # -- Decentralized IDentifier (DID) of the connector - id: "did:web:changeme" # -- Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer trustedIssuers: [] # - id: "did:web:example1.com" diff --git a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-memory-test.yaml b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-memory-test.yaml index 8c3a043ca9..0aa12cf0af 100644 --- a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-memory-test.yaml +++ b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-memory-test.yaml @@ -22,11 +22,10 @@ --- fullnameOverride: tx-inmem participant: - id: "test-participant" + id: "did:web:changeme" + bpnl: "test-participant" contextId: "test-participant-context" dcp: - # Decentralized IDentifier - id: "did:web:changeme" sts: div: url: "https://somewhere.div.org" diff --git a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml index 097522d919..42e74382aa 100644 --- a/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml +++ b/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml @@ -23,11 +23,10 @@ fullnameOverride: tx-prod # EDC ControlPlane + DataPlane # ################################ participant: - id: "test-participant" + id: "did:web:changeme" + bpnl: "test-participant" contextId: "test-participant-context" dcp: - # Decentralized IDentifier - id: "did:web:changeme" sts: div: url: "https://somewhere.div.org" From df83169b80b2b8b234cf13f4018b33a5093c7931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arno=20Wei=C3=9F?= <86715435+arnoweiss@users.noreply.github.com> Date: Wed, 15 Apr 2026 18:09:10 +0200 Subject: [PATCH 030/259] feat: extract BPN from BpnCredential instead of MembershipCredential (#2740) --- .../edc/policy/cx/CxPolicyExtension.java | 2 +- ...sinessPartnerNumberConstraintFunction.java | 48 +++++++++------ ...ssPartnerNumberConstraintFunctionTest.java | 60 +++++++++++++++---- .../edc/tests/MockVcIdentityService.java | 16 ++++- .../tests/participant/DataspaceIssuer.java | 26 +++++++- .../edc/tests/participant/DcpParticipant.java | 7 +-- 6 files changed, 119 insertions(+), 40 deletions(-) diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/CxPolicyExtension.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/CxPolicyExtension.java index ffd9963b8e..e3f6badc91 100644 --- a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/CxPolicyExtension.java +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/CxPolicyExtension.java @@ -181,7 +181,7 @@ public void registerFunctions(PolicyEngine engine) { engine.registerFunction(CatalogPolicyContext.class, Permission.class, withCxPolicyNsPrefix(BUSINESS_PARTNER_GROUP), new BusinessPartnerGroupConstraintFunction<>(store, bdrsClient)); engine.registerFunction(CatalogPolicyContext.class, Permission.class, - withCxPolicyNsPrefix(BUSINESS_PARTNER_NUMBER), new BusinessPartnerNumberConstraintFunction<>(bdrsClient)); + withCxPolicyNsPrefix(BUSINESS_PARTNER_NUMBER), new BusinessPartnerNumberConstraintFunction<>()); // Usage Permission Validators engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/businesspartner/BusinessPartnerNumberConstraintFunction.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/businesspartner/BusinessPartnerNumberConstraintFunction.java index 0bebc65e3c..02f6f7b893 100644 --- a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/businesspartner/BusinessPartnerNumberConstraintFunction.java +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/businesspartner/BusinessPartnerNumberConstraintFunction.java @@ -19,14 +19,15 @@ package org.eclipse.tractusx.edc.policy.cx.businesspartner; +import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential; import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; import org.eclipse.edc.policy.engine.spi.PolicyContext; import org.eclipse.edc.policy.model.Operator; import org.eclipse.edc.policy.model.Permission; import org.eclipse.edc.spi.result.Failure; import org.eclipse.edc.spi.result.Result; +import org.eclipse.tractusx.edc.core.utils.credentials.CredentialTypePredicate; import org.eclipse.tractusx.edc.policy.cx.common.ValueValidatingConstraintFunction; -import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -38,29 +39,30 @@ import static org.eclipse.edc.spi.result.Result.failure; import static org.eclipse.edc.spi.result.Result.success; -import static org.eclipse.tractusx.edc.spi.identity.mapper.BdrsConstants.DID_PREFIX; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_CREDENTIAL_NS; +import static org.eclipse.tractusx.edc.policy.cx.common.AbstractDynamicCredentialConstraintFunction.CREDENTIAL_LITERAL; +import static org.eclipse.tractusx.edc.policy.cx.common.AbstractDynamicCredentialConstraintFunction.VC_CLAIM; /** * This is a constraint function that evaluates the BusinessPartnerNumber of a participant agent. + * The BPN is extracted from the {@code bpn} claim of the participant's BpnCredential. */ public class BusinessPartnerNumberConstraintFunction extends ValueValidatingConstraintFunction { public static final String BUSINESS_PARTNER_NUMBER = "BusinessPartnerNumber"; + private static final String BPN_CREDENTIAL_TYPE = "Bpn"; + private static final String BPN_CLAIM = "bpn"; private static final List SUPPORTED_OPERATORS = Arrays.asList( Operator.IS_ANY_OF, Operator.IS_NONE_OF ); - private BdrsClient bdrsClient; - - public BusinessPartnerNumberConstraintFunction(BdrsClient bdrsClient) { + public BusinessPartnerNumberConstraintFunction() { super( Set.of(Operator.IS_ANY_OF, Operator.IS_NONE_OF), "^BPNL[0-9A-Z]{12}$", true ); - - this.bdrsClient = bdrsClient; } @Override @@ -68,19 +70,32 @@ public boolean evaluate(Operator operator, Object rightOperand, Permission permi var participantAgent = context.participantAgent(); if (!SUPPORTED_OPERATORS.contains(operator)) { - var message = "Operator %s is not supported. Supported operators: %s".formatted(operator, SUPPORTED_OPERATORS); - context.reportProblem(message); + context.reportProblem("Operator %s is not supported. Supported operators: %s".formatted(operator, SUPPORTED_OPERATORS)); return false; } - var identity = participantAgent.getIdentity(); - if (identity == null) { - context.reportProblem("Identity of the participant agent cannot be null"); + var vcListClaim = participantAgent.getClaims().get(VC_CLAIM); + if (!(vcListClaim instanceof List vcList) || vcList.isEmpty()) { + context.reportProblem("ParticipantAgent did not contain a valid '%s' claim.".formatted(VC_CLAIM)); return false; } - if (identity.startsWith(DID_PREFIX)) { - identity = bdrsClient.resolveBpn(identity); + var bpnPredicate = new CredentialTypePredicate(CX_CREDENTIAL_NS, BPN_CREDENTIAL_TYPE + CREDENTIAL_LITERAL); + var identity = vcList.stream() + .filter(VerifiableCredential.class::isInstance) + .map(VerifiableCredential.class::cast) + .filter(bpnPredicate) + .flatMap(vc -> vc.getCredentialSubject().stream()) + .flatMap(subject -> subject.getClaims().entrySet().stream()) + .filter(e -> e.getKey().endsWith(BPN_CLAIM)) + .map(Map.Entry::getValue) + .map(String.class::cast) + .findFirst() + .orElse(null); + + if (identity == null) { + context.reportProblem("Could not extract '%s' from BpnCredential".formatted(BPN_CLAIM)); + return false; } return switch (operator) { @@ -106,12 +121,11 @@ private Result checkListContains(String identity, Object rightValue, Op .map(entry -> ((Map) entry).get("@value")) .filter(value -> value instanceof Map) .map(value -> ((Map) value).get("string")) - .anyMatch(bpn -> identity.equals(bpn)); + .anyMatch(identity::equals); return success(containsBpn); } else if (rightValue instanceof String singleNumber) { - boolean containsBpn = identity.equals(singleNumber); - return success(containsBpn); + return success(identity.equals(singleNumber)); } return failure("Invalid right-value: operator '%s' requires a 'List' but got a '%s'" .formatted(operator, Optional.of(rightValue).map(Object::getClass).map(Class::getName).orElse(null))); diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/businesspartner/BusinessPartnerNumberConstraintFunctionTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/businesspartner/BusinessPartnerNumberConstraintFunctionTest.java index 62fa58321c..c673978610 100644 --- a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/businesspartner/BusinessPartnerNumberConstraintFunctionTest.java +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/businesspartner/BusinessPartnerNumberConstraintFunctionTest.java @@ -20,44 +20,67 @@ package org.eclipse.tractusx.edc.policy.cx.businesspartner; import jakarta.json.Json; +import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential; import org.eclipse.edc.participant.spi.ParticipantAgent; import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; import org.eclipse.edc.policy.model.Operator; import org.eclipse.tractusx.edc.policy.cx.TestParticipantAgentPolicyContext; -import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.junit.jupiter.api.Test; import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_CREDENTIAL_NS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; class BusinessPartnerNumberConstraintFunctionTest { + private static final String TEST_BPN = "BPNL00000000001A"; + private final ParticipantAgent participantAgent = mock(); - private final BdrsClient bdrsClient = mock(); - private final BusinessPartnerNumberConstraintFunction function = new BusinessPartnerNumberConstraintFunction<>(bdrsClient); + private final BusinessPartnerNumberConstraintFunction function = new BusinessPartnerNumberConstraintFunction<>(); private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent); @Test void evaluate() { - var identity = "BPNL00000000001A"; - var bpn1 = Map.of("string", identity); + var bpn1 = Map.of("string", TEST_BPN); var rightValue = List.of(Map.of("@value", bpn1)); - when(participantAgent.getIdentity()).thenReturn(identity); + when(participantAgent.getClaims()).thenReturn(Map.of("vc", bpnVcList(TEST_BPN))); assertThat(function.evaluate(Operator.IS_ANY_OF, rightValue, null, context)).isTrue(); } @Test - void evaluate_withDid() { - var bpn1 = Map.of("string", "BPNL00000000001A"); + void evaluate_whenIsNoneOf_andBpnNotInList() { + var bpn1 = Map.of("string", "BPNL00000000002B"); var rightValue = List.of(Map.of("@value", bpn1)); - var identity = "did:example:some-identity"; - when(participantAgent.getIdentity()).thenReturn(identity); - when(bdrsClient.resolveBpn(identity)).thenReturn("BPNL00000000001A"); - assertThat(function.evaluate(Operator.IS_ANY_OF, rightValue, null, context)).isTrue(); + when(participantAgent.getClaims()).thenReturn(Map.of("vc", bpnVcList(TEST_BPN))); + assertThat(function.evaluate(Operator.IS_NONE_OF, rightValue, null, context)).isTrue(); + } + + @Test + void evaluate_whenIsNoneOf_andBpnInList_returnsFalse() { + var bpn1 = Map.of("string", TEST_BPN); + var rightValue = List.of(Map.of("@value", bpn1)); + when(participantAgent.getClaims()).thenReturn(Map.of("vc", bpnVcList(TEST_BPN))); + assertThat(function.evaluate(Operator.IS_NONE_OF, rightValue, null, context)).isFalse(); + } + + @Test + void evaluate_whenNoVcClaim_returnsFalse() { + when(participantAgent.getClaims()).thenReturn(Map.of()); + var rightValue = List.of(Map.of("@value", Map.of("string", TEST_BPN))); + assertThat(function.evaluate(Operator.IS_ANY_OF, rightValue, null, context)).isFalse(); + assertThat(context.getProblems()).isNotEmpty(); + } + + @Test + void evaluate_whenNoBpnCredential_returnsFalse() { + when(participantAgent.getClaims()).thenReturn(Map.of("vc", List.of())); + var rightValue = List.of(Map.of("@value", Map.of("string", TEST_BPN))); + assertThat(function.evaluate(Operator.IS_ANY_OF, rightValue, null, context)).isFalse(); + assertThat(context.getProblems()).isNotEmpty(); } @Test @@ -123,4 +146,17 @@ void validate_whenInvalidBpnlFormat_thenFailure() { assertThat(result.failed()).isTrue(); assertThat(result.getFailureDetail()).contains("Invalid right-operand: "); } + + private List bpnVcList(String bpn) { + return List.of(VerifiableCredential.Builder.newInstance() + .types(List.of(CX_CREDENTIAL_NS + "VerifiableCredential", CX_CREDENTIAL_NS + "BpnCredential")) + .id("test-vc-id") + .issuer(new org.eclipse.edc.iam.verifiablecredentials.spi.model.Issuer("did:web:issuer", Map.of())) + .issuanceDate(java.time.Instant.now()) + .credentialSubject(org.eclipse.edc.iam.verifiablecredentials.spi.model.CredentialSubject.Builder.newInstance() + .id("subject-id") + .claim(CX_CREDENTIAL_NS + "bpn", bpn) + .build()) + .build()); + } } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/MockVcIdentityService.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/MockVcIdentityService.java index 4197febd99..f209ba383e 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/MockVcIdentityService.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/MockVcIdentityService.java @@ -85,7 +85,7 @@ public Result verifyJwtToken(String participantContextId, TokenRepre var claimToken = claimTokenResult.getContent(); var bpnlConsumer = claimToken.getStringClaim(BUSINESS_PARTNER_NUMBER_CLAIM); var didConsumer = claimToken.getStringClaim(ISSUER); - var credentials = List.of(membershipCredential(bpnlConsumer, didConsumer), dataExchangeGovernanceCredential(bpnlConsumer, didConsumer)); + var credentials = List.of(membershipCredential(bpnlConsumer, didConsumer), bpnCredential(bpnlConsumer, didConsumer), dataExchangeGovernanceCredential(bpnlConsumer, didConsumer)); var claimTokenWithVc = ClaimToken.Builder.newInstance() .claim(VC_CLAIM, credentials) @@ -148,4 +148,18 @@ private VerifiableCredential membershipCredential(String bpnlConsumer, String di .issuanceDate(Instant.now()) .build(); } + + private VerifiableCredential bpnCredential(String bpnlConsumer, String didConsumer) { + return VerifiableCredential.Builder.newInstance() + .type("VerifiableCredential") + .type("BpnCredential") + .credentialSubject(CredentialSubject.Builder.newInstance() + .id(didConsumer) + .claim("holderIdentifier", bpnlConsumer) + .claim("bpn", bpnlConsumer) + .build()) + .issuer(new Issuer("issuer", Map.of())) + .issuanceDate(Instant.now()) + .build(); + } } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DataspaceIssuer.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DataspaceIssuer.java index f9dde21ed5..6d94b3e7ee 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DataspaceIssuer.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DataspaceIssuer.java @@ -88,6 +88,7 @@ public VerifiableCredentialResource issueMembershipCredential(String did, String () -> CredentialSubject.Builder.newInstance() .id(did) .claim("holderIdentifier", bpn) + .claim("bpn", bpn) .build(), membershipRawVc(did, bpn) ); @@ -162,10 +163,29 @@ public List issueCredentials(String did, String bp return List.of( issueMembershipCredential(did, bpn), issueDismantlerCredential(did, bpn), - issueFrameworkCredential(did, bpn, "BpnCredential"), + issueBpnCredential(did, bpn), issueFrameworkCredential(did, bpn, "DataExchangeGovernanceCredential")); } + VerifiableCredentialResource issueBpnCredential(String did, String bpn) { + var subject = Json.createObjectBuilder() + .add("type", "BpnCredential") + .add("holderIdentifier", bpn) + .add("bpn", bpn) + .add("id", did) + .build(); + + return issueCredential( + did, bpn, "BpnCredential", + () -> CredentialSubject.Builder.newInstance() + .id(did) + .claim("holderIdentifier", bpn) + .claim("bpn", bpn) + .build(), + createVcBuilder("BpnCredential", subject) + ); + } + private VerifiableCredentialResource issueCredential(String did, String bpn, String type, Supplier credentialSubjectSupplier, JsonObjectBuilder vcBuilder) { var credential = VerifiableCredential.Builder.newInstance() .type(type) @@ -192,8 +212,8 @@ private JsonObjectBuilder createVcBuilder(String type, JsonObject subjectSupplie .add("https://w3id.org/catenax/credentials") .add("https://w3id.org/vc/status-list/2021/v1")) .add("type", Json.createArrayBuilder() - .add("VerifiableCredential") - .add(type)) + .add(type) + .add("VerifiableCredential")) .add("credentialSubject", subjectSupplier) .add("issuer", didUrl()) .add("issuanceDate", Instant.now().toString()); diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java index 9f23e9844c..9277015401 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java @@ -113,12 +113,7 @@ public void configureParticipant(DataspaceIssuer issuer, RuntimeExtension runtim } private List issueCredentials(DataspaceIssuer issuer) { - return List.of( - issuer.issueMembershipCredential(getDid(), getBpn()), - issuer.issueDismantlerCredential(getDid(), getBpn()), - issuer.issueFrameworkCredential(getDid(), getBpn(), "BpnCredential"), - issuer.issueFrameworkCredential(getDid(), getBpn(), "DataExchangeGovernanceCredential") - ); + return issuer.issueCredentials(getDid(), getBpn()); } public KeyDescriptor createKeyDescriptor() { From 99b2e90e9d458479fb39b856e5e08c757af02b82 Mon Sep 17 00:00:00 2001 From: Zead Alshukairi Date: Thu, 16 Apr 2026 12:59:49 +0200 Subject: [PATCH 031/259] Docs/edc extensions readmes (#2711) * Readme for DCP-extension Signed-off-by: Zead-Alshu22 * Readme for bdrs-client-extension Signed-off-by: Zead-Alshu22 * Readme for connector discovery-extension Signed-off-by: Zead-Alshu22 * Readme for agreements extension Signed-off-by: Zead-Alshu22 * chore: central extensions readme Signed-off-by: Zead-Alshu22 * overview README deleted Signed-off-by: Zead-Alshu22 * high-level module intent Signed-off-by: Zead-Alshu22 * revert agreements-Readme Signed-off-by: Zead-Alshu22 --------- Signed-off-by: Zead-Alshu22 --- edc-extensions/bdrs-client/README.md | 4 ++++ edc-extensions/connector-discovery/README.md | 4 ++++ edc-extensions/dcp/README.md | 3 +++ 3 files changed, 11 insertions(+) create mode 100644 edc-extensions/bdrs-client/README.md create mode 100644 edc-extensions/connector-discovery/README.md create mode 100644 edc-extensions/dcp/README.md diff --git a/edc-extensions/bdrs-client/README.md b/edc-extensions/bdrs-client/README.md new file mode 100644 index 0000000000..e3d5d52ac6 --- /dev/null +++ b/edc-extensions/bdrs-client/README.md @@ -0,0 +1,4 @@ +## Purpose +The BPN-DID Resolution Service (BDRS) Client extension provides a client for the BDRS server, which maintains mappings between Business Partner Numbers (BPNs) and Decentralized Identifiers (DIDs) in the Catena-X dataspace. +The client maintains a local cache of these mappings for efficient resolution. +For dataspaces that don't require mapping between a did and a different identifier, this extension (and the extensions injecting it) is obsolete. \ No newline at end of file diff --git a/edc-extensions/connector-discovery/README.md b/edc-extensions/connector-discovery/README.md new file mode 100644 index 0000000000..17249c18b9 --- /dev/null +++ b/edc-extensions/connector-discovery/README.md @@ -0,0 +1,4 @@ +## Purpose +The Connector Discovery extension enables participants to discover other connectors in the dataspace. +The **connector-discovery-api** module provides a REST API and default implementation for **DID-based** discovery with **Dataspace Protocol (DSP) 2025-1**. +It resolves connector endpoints from a participant’s DID document. \ No newline at end of file diff --git a/edc-extensions/dcp/README.md b/edc-extensions/dcp/README.md new file mode 100644 index 0000000000..0c3d1a1096 --- /dev/null +++ b/edc-extensions/dcp/README.md @@ -0,0 +1,3 @@ +## Purpose +The DCP extension provides implementations for the Decentralized Credential Protocol. +It handles credential scope extraction (from policies), Secure Token Service (STS) integration, and verifiable presentation caching. From 483706869c73d3bb1e219a4bab1600b3b8c9d819 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Thu, 16 Apr 2026 13:23:37 +0200 Subject: [PATCH 032/259] infra: Make upgrade base fix temporarily (#2745) * Make upgrade base fix temporarily Signed-off-by: Lars Geyer-Blaumeiser * Revert to just adding a flag to the helm call Signed-off-by: Lars Geyer-Blaumeiser --------- Signed-off-by: Lars Geyer-Blaumeiser --- .github/workflows/upgradeability-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index c5d79006a2..1d88eebae0 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -59,7 +59,7 @@ jobs: - name: "Get latest released version" id: get-version run: | - RELEASED_VERSION=$(helm search repo tractusx/tractusx-connector -l -o json | jq -r 'first | .version') + RELEASED_VERSION=$(helm search repo tractusx/tractusx-connector -l --devel -o json | jq -r 'first | .version') echo "Last official release is $RELEASED_VERSION" echo "RELEASE=$RELEASED_VERSION" >> $GITHUB_ENV exit 0 From 750d39d69245aff7987a8004ee77926bd72d3843 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 10:54:02 +0200 Subject: [PATCH 033/259] chore(deps): bump flyway from 12.3.0 to 12.4.0 (#2752) Bumps `flyway` from 12.3.0 to 12.4.0. Updates `org.flywaydb:flyway-core` from 12.3.0 to 12.4.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.3.0 to 12.4.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.4.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 87f06f413c..ffaca85170 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ azure-storage-blob = "12.33.3" bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" -flyway = "12.3.0" +flyway = "12.4.0" jackson = "2.21.2" jakarta-json = "2.1.3" junit = "6.0.3" From 4f42ca8ee2efb6db6282a7fc4e32e8fef29e1153 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 10:54:29 +0200 Subject: [PATCH 034/259] chore(deps): bump io.swagger.core.v3.swagger-gradle-plugin (#2751) Bumps io.swagger.core.v3.swagger-gradle-plugin from 2.2.47 to 2.2.48. --- updated-dependencies: - dependency-name: io.swagger.core.v3.swagger-gradle-plugin dependency-version: 2.2.48 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ffaca85170..701f4f7905 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -250,5 +250,5 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } shadow = { id = "com.gradleup.shadow", version = "9.4.1" } -swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.47" } +swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.48" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From f1ba78b4e106bf75730aa458ac2c810df43b2e82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 10:54:50 +0200 Subject: [PATCH 035/259] chore(deps): bump aws from 2.42.33 to 2.42.35 (#2750) Bumps `aws` from 2.42.33 to 2.42.35. Updates `software.amazon.awssdk:s3` from 2.42.33 to 2.42.35 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.42.33 to 2.42.35 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.42.35 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.42.35 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 701f4f7905..834b681126 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.1.6" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.42.33" +aws = "2.42.35" azure-storage-blob = "12.33.3" bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" From 52d67863e43c8cc362aafa5f7a945e9a3980e85f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 10:55:50 +0200 Subject: [PATCH 036/259] chore(deps): bump org.bouncycastle:bcpkix-jdk18on from 1.83 to 1.84 (#2747) Bumps [org.bouncycastle:bcpkix-jdk18on](https://github.com/bcgit/bc-java) from 1.83 to 1.84. - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcpkix-jdk18on dependency-version: '1.84' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 834b681126..c001d0dac6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,7 +9,7 @@ allure = "2.34.0" awaitility = "4.3.0" aws = "2.42.35" azure-storage-blob = "12.33.3" -bouncyCastle-jdk18on = "1.83" +bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" flyway = "12.4.0" From 32024af5fac2b8da27a79a0bc0c6ba62505f5209 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:17:46 +0200 Subject: [PATCH 037/259] chore(deps): bump com.networknt:json-schema-validator (#2753) Bumps [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) from 3.0.0 to 3.0.2. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/3.0.0...3.0.2) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-version: 3.0.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts index 463ddbae3e..eabd9e0265 100644 --- a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts @@ -43,7 +43,7 @@ dependencies { } constraints { - implementation("com.networknt:json-schema-validator:3.0.0") { + implementation("com.networknt:json-schema-validator:3.0.2") { because("older versions cause runtime issues") } } From ce2caf0be3c7d2c85d403b9ae0446f55dd7f20f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 15:56:18 +0200 Subject: [PATCH 038/259] chore(deps): bump org.eclipse.edc.edc-build from 1.1.6 to 1.4.0 (#2749) * chore(deps): bump org.eclipse.edc.edc-build from 1.1.6 to 1.4.0 Bumps org.eclipse.edc.edc-build from 1.1.6 to 1.4.0. --- updated-dependencies: - dependency-name: org.eclipse.edc.edc-build dependency-version: 1.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Adapt build file for new edc-build Signed-off-by: Lars Geyer-Blaumeiser --------- Signed-off-by: dependabot[bot] Signed-off-by: Lars Geyer-Blaumeiser Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lars Geyer-Blaumeiser --- build.gradle.kts | 4 ---- gradle/libs.versions.toml | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8dea41cf18..c26a6cd210 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -84,10 +84,6 @@ allprojects { scmUrl.set(txScmUrl) } swagger { - title.set((project.findProperty("apiTitle") ?: "Tractus-X REST API") as String) - description = - (project.findProperty("apiDescription") - ?: "Tractus-X REST APIs - merged by OpenApiMerger") as String outputFilename.set(project.name) outputDirectory.set(file("${rootProject.projectDir.path}/resources/openapi/yaml")) resourcePackages = setOf("org.eclipse.tractusx.edc") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c001d0dac6..8e53e381dd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ format.version = "1.1" [versions] edc = "0.15.1" edc-next = "0.16.0" -edc-build = "1.1.6" +edc-build = "1.5.0" allure = "2.34.0" awaitility = "4.3.0" aws = "2.42.35" From 7aa5ef2fdad5e245fcb717d67bb1ab88a2ebcdb0 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Tue, 21 Apr 2026 14:57:58 +0200 Subject: [PATCH 039/259] Fix version for api-hub publication for 0.10.x (#2757) Signed-off-by: Lars Geyer-Blaumeiser --- .tractusx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.tractusx b/.tractusx index 4897df1ed1..88c3d0c480 100644 --- a/.tractusx +++ b/.tractusx @@ -6,8 +6,8 @@ openApiSpecs: - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/data-plane-api/0.12.0/data-plane.yaml" - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.11.2/control-plane.yaml" - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/data-plane-api/0.11.2/data-plane.yaml" -- "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.10.2/control-plane.yaml" -- "https://eclipse-tractusx.github.io/tractusx-edc/openapi/data-plane-api/0.10.2/data-plane.yaml" +- "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.10.3/control-plane.yaml" +- "https://eclipse-tractusx.github.io/tractusx-edc/openapi/data-plane-api/0.10.3/data-plane.yaml" - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.9.0/control-plane.yaml" - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/data-plane-api/0.9.0/data-plane.yaml" - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.8.1/control-plane.yaml" From 13518f3a2527318fa11481d46c51159123894671 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Tue, 21 Apr 2026 14:58:19 +0200 Subject: [PATCH 040/259] Update bugfix version of edc build (#2756) Signed-off-by: Lars Geyer-Blaumeiser --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8e53e381dd..a726296245 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ format.version = "1.1" [versions] edc = "0.15.1" edc-next = "0.16.0" -edc-build = "1.5.0" +edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" aws = "2.42.35" From b6827956d39aa1d63f224674cb65b15fe754d5e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 07:58:32 +0200 Subject: [PATCH 041/259] chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations (#2773) Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.26.1 to 2.27.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.26.1...v2.27.0) --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations dependency-version: 2.27.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a726296245..c3be36a17b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ junit = "6.0.3" nimbus = "10.9" okhttp = "5.3.2" opentelemetry = "2.26.1" -opentelemetry-instrumentation = "2.26.1" +opentelemetry-instrumentation = "2.27.0" opentelemetry-log4j-appender = "2.26.1-alpha" postgres = "42.7.10" restAssured = "6.0.0" From 80a02ad0fce231f57b64ec073f3a163cc6a4babe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 07:59:22 +0200 Subject: [PATCH 042/259] chore(deps): bump com.github.dasniko:testcontainers-keycloak (#2770) Bumps [com.github.dasniko:testcontainers-keycloak](https://github.com/dasniko/testcontainers-keycloak) from 4.2.0 to 4.2.1. - [Release notes](https://github.com/dasniko/testcontainers-keycloak/releases) - [Commits](https://github.com/dasniko/testcontainers-keycloak/compare/v4.2.0...v4.2.1) --- updated-dependencies: - dependency-name: com.github.dasniko:testcontainers-keycloak dependency-version: 4.2.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c3be36a17b..642b1cb093 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ postgres = "42.7.10" restAssured = "6.0.0" rsApi = "4.0.0" testcontainers = "2.0.4" -testcontainers-keycloak = "4.2.0" +testcontainers-keycloak = "4.2.1" titanium = "1.7.0" log4j2 = "2.25.4" wiremock = "3.13.2" From aa14b2bf724d6fae72581713753c15bfe6bbf609 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 07:59:40 +0200 Subject: [PATCH 043/259] chore(deps): bump aws from 2.42.35 to 2.42.39 (#2769) Bumps `aws` from 2.42.35 to 2.42.39. Updates `software.amazon.awssdk:s3` from 2.42.35 to 2.42.39 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.42.35 to 2.42.39 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.42.39 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.42.39 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 642b1cb093..7de8c92504 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.42.35" +aws = "2.42.39" azure-storage-blob = "12.33.3" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" From f85412b6b4412c1c9cb0d082f44045328c40c531 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:00:34 +0200 Subject: [PATCH 044/259] chore(deps): bump tractusx/bdrs-server-memory (#2763) Bumps tractusx/bdrs-server-memory from 0.5.7 to 0.6.0. --- updated-dependencies: - dependency-name: tractusx/bdrs-server-memory dependency-version: 0.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- edc-extensions/bdrs-client/src/test/resources/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edc-extensions/bdrs-client/src/test/resources/Dockerfile b/edc-extensions/bdrs-client/src/test/resources/Dockerfile index be243a8e7d..75ddd98fe2 100644 --- a/edc-extensions/bdrs-client/src/test/resources/Dockerfile +++ b/edc-extensions/bdrs-client/src/test/resources/Dockerfile @@ -1,2 +1,2 @@ -FROM tractusx/bdrs-server-memory:0.5.7 +FROM tractusx/bdrs-server-memory:0.6.0 USER "Dummy" From 8fe1edb9e3b8e5c0786561bee39baa889a1d2aaf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:00:56 +0200 Subject: [PATCH 045/259] chore(deps): bump trufflesecurity/trufflehog from 3.94.3 to 3.95.2 (#2764) Bumps [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) from 3.94.3 to 3.95.2. - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/47e7b7cd74f578e1e3145d48f669f22fd1330ca6...17456f8c7d042d8c82c9a8ca9e937231f9f42e26) --- updated-dependencies: - dependency-name: trufflesecurity/trufflehog dependency-version: 3.95.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/secrets-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 668f09c495..d18116f5f5 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -46,7 +46,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@47e7b7cd74f578e1e3145d48f669f22fd1330ca6 + uses: trufflesecurity/trufflehog@17456f8c7d042d8c82c9a8ca9e937231f9f42e26 continue-on-error: true with: path: ./ # Scan the entire repository From 2a911820b5968eee1a6beacc5f5f5ee211d08654 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:01:12 +0200 Subject: [PATCH 046/259] chore(deps): bump aquasecurity/trivy-action from 0.35.0 to 0.36.0 (#2765) Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.35.0 to 0.36.0. - [Release notes](https://github.com/aquasecurity/trivy-action/releases) - [Commits](https://github.com/aquasecurity/trivy-action/compare/0.35.0...v0.36.0) --- updated-dependencies: - dependency-name: aquasecurity/trivy-action dependency-version: 0.36.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/trivy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 9a767e5080..0574d1fd8f 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -58,7 +58,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@0.35.0 + uses: aquasecurity/trivy-action@v0.36.0 with: scan-type: "config" # ignore-unfixed: true @@ -100,7 +100,7 @@ jobs: ## the next two steps will only execute if the image exists check was successful - name: Run Trivy vulnerability scanner if: success() && steps.imageCheck.outcome != 'failure' - uses: aquasecurity/trivy-action@0.35.0 + uses: aquasecurity/trivy-action@v0.36.0 with: image-ref: "tractusx/${{ matrix.image }}:sha-${{ needs.git-sha7.outputs.value }}" format: "sarif" From 7fb5f31630affbd600eba2eaab8359eefe1510f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 08:01:32 +0200 Subject: [PATCH 047/259] chore(deps): bump mikefarah/yq (#2766) Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.52.4 to 4.53.2. - [Release notes](https://github.com/mikefarah/yq/releases) - [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt) - [Commits](https://github.com/mikefarah/yq/compare/v4.52.4...v4.53.2) --- updated-dependencies: - dependency-name: mikefarah/yq dependency-version: 4.53.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/update-version-and-charts/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/update-version-and-charts/action.yml b/.github/actions/update-version-and-charts/action.yml index 2f9b0af1eb..3d6ce14e4a 100644 --- a/.github/actions/update-version-and-charts/action.yml +++ b/.github/actions/update-version-and-charts/action.yml @@ -42,7 +42,7 @@ runs: fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" - name: Bump version in /charts - uses: mikefarah/yq@v4.52.4 + uses: mikefarah/yq@v4.53.2 with: cmd: | find charts -name Chart.yaml -maxdepth 3 | xargs -n1 yq -i '.appVersion = "${{ steps.resolver.outputs.version }}" From e3ba99233f06cfa1a57679bb58e1c5c3c7e66275 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 09:05:39 +0200 Subject: [PATCH 048/259] chore(deps): bump testcontainers from 2.0.4 to 2.0.5 (#2767) Bumps `testcontainers` from 2.0.4 to 2.0.5. Updates `org.testcontainers:testcontainers-junit-jupiter` from 2.0.4 to 2.0.5 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/2.0.4...2.0.5) Updates `org.testcontainers:testcontainers-minio` from 2.0.4 to 2.0.5 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/2.0.4...2.0.5) Updates `org.testcontainers:testcontainers-localstack` from 2.0.4 to 2.0.5 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/2.0.4...2.0.5) Updates `org.testcontainers:testcontainers-postgresql` from 2.0.4 to 2.0.5 - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/2.0.4...2.0.5) --- updated-dependencies: - dependency-name: org.testcontainers:testcontainers-junit-jupiter dependency-version: 2.0.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:testcontainers-localstack dependency-version: 2.0.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:testcontainers-minio dependency-version: 2.0.5 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.testcontainers:testcontainers-postgresql dependency-version: 2.0.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7de8c92504..b69eab19e8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,7 +24,7 @@ opentelemetry-log4j-appender = "2.26.1-alpha" postgres = "42.7.10" restAssured = "6.0.0" rsApi = "4.0.0" -testcontainers = "2.0.4" +testcontainers = "2.0.5" testcontainers-keycloak = "4.2.1" titanium = "1.7.0" log4j2 = "2.25.4" From dcc7e0a6b934f9c1dc736c5551e1a6f246ec66a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 09:06:41 +0200 Subject: [PATCH 049/259] chore(deps): bump io.opentelemetry.javaagent:opentelemetry-javaagent (#2772) Bumps [io.opentelemetry.javaagent:opentelemetry-javaagent](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.26.1 to 2.27.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.26.1...v2.27.0) --- updated-dependencies: - dependency-name: io.opentelemetry.javaagent:opentelemetry-javaagent dependency-version: 2.27.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b69eab19e8..999a5ba7b7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,7 +18,7 @@ jakarta-json = "2.1.3" junit = "6.0.3" nimbus = "10.9" okhttp = "5.3.2" -opentelemetry = "2.26.1" +opentelemetry = "2.27.0" opentelemetry-instrumentation = "2.27.0" opentelemetry-log4j-appender = "2.26.1-alpha" postgres = "42.7.10" From cde6740b311b7577651bf7c1833ef79b0d9eff9e Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Fri, 24 Apr 2026 11:27:46 +0200 Subject: [PATCH 050/259] fix: make dependabot ignore SNAPSHOT versions (#2775) --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0979491a74..847c60c873 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -37,6 +37,8 @@ updates: ignore: - dependency-name: "org.eclipse.dataspacetck.dsp:*" - dependency-name: "org.eclipse.dataspacetck.dcp:*" + - dependency-name: "*" + versions: [ "*SNAPSHOT" ] # Github Actions - From 2391a34eb4075339f43b760b9eac465a8be7687f Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Fri, 24 Apr 2026 13:52:14 +0200 Subject: [PATCH 051/259] fix: remove snapshot maven repo (#2776) --- .github/dependabot.yml | 2 -- settings.gradle.kts | 7 ------- 2 files changed, 9 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 847c60c873..0979491a74 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -37,8 +37,6 @@ updates: ignore: - dependency-name: "org.eclipse.dataspacetck.dsp:*" - dependency-name: "org.eclipse.dataspacetck.dcp:*" - - dependency-name: "*" - versions: [ "*SNAPSHOT" ] # Github Actions - diff --git a/settings.gradle.kts b/settings.gradle.kts index ccd23e0222..cc8b93c55d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -20,23 +20,16 @@ rootProject.name = "tractusx-edc" -// this is needed to have access to snapshot builds of plugins pluginManagement { repositories { gradlePluginPortal() mavenCentral() - maven { - url = uri("https://central.sonatype.com/repository/maven-snapshots/") - } } } dependencyResolutionManagement { repositories { mavenLocal() - maven { - url = uri("https://central.sonatype.com/repository/maven-snapshots/") - } mavenCentral() } versionCatalogs { From d4d3c0083bf484b4a6810827def128d6b56b2040 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:26:50 +0200 Subject: [PATCH 052/259] chore(deps): bump aws from 2.42.39 to 2.42.40 (#2777) Bumps `aws` from 2.42.39 to 2.42.40. Updates `software.amazon.awssdk:s3` from 2.42.39 to 2.42.40 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.42.39 to 2.42.40 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.42.40 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.42.40 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 999a5ba7b7..b4ad8b867b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.42.39" +aws = "2.42.40" azure-storage-blob = "12.33.3" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" From ac3325010b912db23b01c5eae19e3f991d1c4f8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:27:11 +0200 Subject: [PATCH 053/259] chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 (#2778) Bumps [io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.26.1-alpha to 2.27.0-alpha. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/commits) --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 dependency-version: 2.27.0-alpha dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b4ad8b867b..c1584d45b1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ nimbus = "10.9" okhttp = "5.3.2" opentelemetry = "2.27.0" opentelemetry-instrumentation = "2.27.0" -opentelemetry-log4j-appender = "2.26.1-alpha" +opentelemetry-log4j-appender = "2.27.0-alpha" postgres = "42.7.10" restAssured = "6.0.0" rsApi = "4.0.0" From c82ad94b7b17a219afb0e0e0d45f355e518d3b18 Mon Sep 17 00:00:00 2001 From: Felix Gerbig <48456355+gerbigf@users.noreply.github.com> Date: Tue, 28 Apr 2026 08:52:32 +0200 Subject: [PATCH 054/259] Update 2025-09-Version_0.10.x_0.11.x.md (#2755) Added missing migraiton guide information --- docs/migration/2025-09-Version_0.10.x_0.11.x.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/migration/2025-09-Version_0.10.x_0.11.x.md b/docs/migration/2025-09-Version_0.10.x_0.11.x.md index d2be834af0..dc98d65473 100644 --- a/docs/migration/2025-09-Version_0.10.x_0.11.x.md +++ b/docs/migration/2025-09-Version_0.10.x_0.11.x.md @@ -165,3 +165,6 @@ There is an extensive documentation on contracting in Catena-X in the regulatory A recommended playground to experiment with the new policies is the Tractus-X Policy Builder which can be found here: - [Catena-X Policy Builder](https://eclipse-tractusx.github.io/tractusx-edc-dashboard/policy-builder/) + +## Removal of "dcat:endpointUrl" in catalog response +Until EDC 0.10 there were two attributes "dcat:endpointUrl" and "dcat:endpointURL" present in the catalog response. The first one presented an inconsistency with the dataspace protocol specification and thus was removed with the 0.11 release. Applications that use "dcat:endpointUrl" need to switch to "dcat:endpointURL". From e9f788653eab6799cbc7206d53f11b4e43c8c9db Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Thu, 30 Apr 2026 17:21:11 +0200 Subject: [PATCH 055/259] Security improvements (#2713) * feat: use commit SHA * feat: remove upstream action uses * feat: update dependabot to have cooldown * feat: pin Docker images by digest, not tag * feat: add runtime visibility with Harden-Runner * feat: minimize token permissions * feat: add security workflow (zizmor + poutine) * feat: replace SHA for harden-runner * feat: fox formating and zizmor finding * feat: zizmor - credential persistence through GitHub Actions artifacts * feat: zizmor - improvements * feat: correct workflow * feat: correct workflow * feat: improve some zizmor error * feat: fix secrets-inherit warning * feat: replace workflow_run with workflow_call, dependabot cooldown * feat: apply poutine suggestions (replace action from unverified creator) * feat: Report poutine findings with line annotations * feat: improvement * feat: Report poutine findings with line annotations --- .../action.yml | 2 + .../action.yml | 8 +- .github/actions/import-gpg-key/action.yml | 4 +- .../actions/publish-docker-image/action.yml | 29 +++-- .../action.yml | 6 +- .../publish-maven-artifacts/action.yml | 53 ++++++++ .../actions/run-deployment-test/action.yml | 23 +++- .github/actions/setup-helm/action.yml | 2 +- .github/actions/setup-java/action.yml | 4 +- .github/actions/setup-kubectl/action.yml | 2 +- .../update-version-and-charts/action.yml | 32 +++-- .github/dependabot.yml | 6 + .github/scripts/fix-poutine-sarif.py | 99 ++++++++++++++ .github/workflows/codeql.yaml | 14 +- .github/workflows/copy-labels.yaml | 8 +- .github/workflows/deployment-test.yaml | 25 +++- .github/workflows/draft-release.yaml | 51 ++++++-- .../generate-and-publish-dependencies.yaml | 14 +- .github/workflows/helm-lint.yaml | 14 +- .github/workflows/kics.yml | 15 ++- .github/workflows/publish-context.yaml | 15 ++- .github/workflows/publish-new-snapshot.yaml | 70 ++++++++-- .github/workflows/publish-openapi-ui.yml | 47 ++++--- .github/workflows/release.yml | 111 ++++++++++++---- .github/workflows/run-all-tests.yml | 30 ++++- .github/workflows/secrets-scan.yml | 17 ++- .github/workflows/stale-bot.yml | 9 +- .github/workflows/triage-issue.yml | 7 + .github/workflows/trigger-docker-publish.yaml | 25 +++- .github/workflows/trigger-maven-publish.yaml | 38 +++++- .github/workflows/trivy.yml | 48 ++++--- .github/workflows/upgradeability-test.yaml | 19 ++- .github/workflows/verify.yaml | 122 ++++++++++++++---- .github/workflows/workflow-security-lint.yaml | 95 ++++++++++++++ .github/zizmor.yml | 28 ++++ .../src/main/docker/Dockerfile | 2 +- resources/Dockerfile | 2 +- 37 files changed, 900 insertions(+), 196 deletions(-) create mode 100644 .github/actions/publish-maven-artifacts/action.yml create mode 100644 .github/scripts/fix-poutine-sarif.py create mode 100644 .github/workflows/workflow-security-lint.yaml create mode 100644 .github/zizmor.yml diff --git a/.github/actions/generate-and-check-dependencies/action.yml b/.github/actions/generate-and-check-dependencies/action.yml index 1ed0ef1bb7..fa193bf798 100644 --- a/.github/actions/generate-and-check-dependencies/action.yml +++ b/.github/actions/generate-and-check-dependencies/action.yml @@ -40,6 +40,8 @@ runs: - name: Run dash id: run-dash + # poutine: ignore[unpinnable_action] + # poutine: ignore[github_action_from_unverified_creator_used] uses: eclipse-tractusx/sig-infra/.github/actions/run-dash@main with: dash_input: dependency-list diff --git a/.github/actions/generate-and-publish-allure-report/action.yml b/.github/actions/generate-and-publish-allure-report/action.yml index 78415514b6..eb2ee4a627 100644 --- a/.github/actions/generate-and-publish-allure-report/action.yml +++ b/.github/actions/generate-and-publish-allure-report/action.yml @@ -35,23 +35,23 @@ runs: using: "composite" steps: - name: Download Allure results - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: ${{ inputs.allure_results }}-* merge-multiple: true path: allure-results - name: Build Allure test report - uses: simple-elf/allure-report-action@v1.13 + uses: simple-elf/allure-report-action@53ebb757a2097edc77c53ecef4d454fc2f2f774c # v1.13 with: gh_pages: gh-pages allure_results: allure-results allure_report: ${{ inputs.version }} - name: Publish Allure test report to gh-pages - uses: peaceiris/actions-gh-pages@v4 + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 with: github_token: ${{ inputs.token }} publish_dir: ./${{ inputs.version }} destination_dir: allure-reports/${{ inputs.version }} - keep_files: false \ No newline at end of file + keep_files: false diff --git a/.github/actions/import-gpg-key/action.yml b/.github/actions/import-gpg-key/action.yml index c76e7024a2..c606262876 100644 --- a/.github/actions/import-gpg-key/action.yml +++ b/.github/actions/import-gpg-key/action.yml @@ -37,10 +37,12 @@ runs: - name: Import GPG Private Key shell: bash + env: + GPG_PRIVATE_KEY: ${{ inputs.gpg-private-key }} run: | echo "use-agent" >> ~/.gnupg/gpg.conf echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf - echo -e "${{ inputs.gpg-private-key }}" | gpg --import --batch + echo -e "$GPG_PRIVATE_KEY" | gpg --import --batch for fpr in $(gpg --list-keys --with-colons | awk -F: '/fpr:/ {print $10}' | sort -u); do echo -e "5\\ny\\n" | gpg --batch --command-fd 0 --expert --edit-key $fpr trust; diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 3875f423c5..f5f9860631 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -46,25 +46,27 @@ inputs: runs: using: "composite" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false ############################################### # Enable emulation for cross-arch builds ############################################### - name: Set up QEMU - uses: docker/setup-qemu-action@v4 + uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 ############################################### # Use Docker Buildx (required for multi-arch) ############################################### - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v4 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 ##################### # Login to DockerHub ##################### - name: DockerHub login - uses: docker/login-action@v4 + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 with: username: ${{ inputs.docker_user }} password: ${{ inputs.docker_token }} @@ -75,8 +77,10 @@ runs: - uses: ./.github/actions/setup-java - name: Build Controlplane shell: bash + env: + ROOT_DIR: ${{ inputs.rootDir }} run: |- - ./gradlew -p ${{ inputs.rootDir }} shadowJar + ./gradlew -p "$ROOT_DIR" shadowJar ############################### # Set metadata of docker image @@ -84,7 +88,7 @@ runs: # Create SemVer or ref tags dependent of trigger event - name: Docker meta id: meta - uses: docker/metadata-action@v6 + uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: images: | ${{ inputs.namespace }}/${{ inputs.imagename }} @@ -101,12 +105,15 @@ runs: # Build and push the image ############################### - name: Build and push - uses: docker/build-push-action@v7 + uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 + env: + ROOT_DIR: ${{ inputs.rootDir }} + IMAGE_NAME: ${{ inputs.imagename }} with: - context: ${{ inputs.rootDir }} - file: ${{ inputs.rootDir }}/build/resources/docker/Dockerfile + context: ${{ env.ROOT_DIR }} + file: ${{ env.ROOT_DIR }}/build/resources/docker/Dockerfile build-args: | - JAR=build/libs/${{ inputs.imagename }}.jar + JAR=build/libs/${{ env.IMAGE_NAME }}.jar OTEL_JAR=build/resources/otel/opentelemetry-javaagent.jar ADDITIONAL_FILES=build/legal/* push: true @@ -119,7 +126,7 @@ runs: # https://github.com/peter-evans/dockerhub-description ############################### - name: Update Docker Hub description - uses: peter-evans/dockerhub-description@v5 + uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0 with: readme-filepath: ${{ inputs.rootDir }}/notice.md username: ${{ inputs.docker_user }} diff --git a/.github/actions/publish-latest-versioned-snapshot/action.yml b/.github/actions/publish-latest-versioned-snapshot/action.yml index 17900cc53c..c023513318 100644 --- a/.github/actions/publish-latest-versioned-snapshot/action.yml +++ b/.github/actions/publish-latest-versioned-snapshot/action.yml @@ -29,12 +29,14 @@ runs: steps: - name: Write version to latest-versioned-snapshot file shell: bash + env: + VERSION: ${{ inputs.version }} run: | mkdir -p lvs - echo "${{ inputs.version }}" > lvs/latest-versioned-snapshot.txt + echo "$VERSION" > lvs/latest-versioned-snapshot.txt - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v4 + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 with: github_token: ${{ env.GITHUB_TOKEN }} publish_dir: ./lvs diff --git a/.github/actions/publish-maven-artifacts/action.yml b/.github/actions/publish-maven-artifacts/action.yml new file mode 100644 index 0000000000..ed733cbdd6 --- /dev/null +++ b/.github/actions/publish-maven-artifacts/action.yml @@ -0,0 +1,53 @@ +################################################################################# +# Copyright (c) 2026 Cofinity-X GmbH +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + + +name: "Publish Maven Artifacts" +description: "Publish maven artifacts to central repository" + +inputs: + gpg-private-key: + description: the gpg private key used to publish + required: true + gpg-passphrase: + description: the gpg passphrase used to publish + required: true + username: + description: the username + required: true + password: + description: the password + required: true + +runs: + using: "composite" + steps: + + - uses: ./.github/actions/import-gpg-key + with: + gpg-private-key: ${{ inputs.gpg-private-key }} + + - name: Publish to maven central + shell: bash + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ inputs.username }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ inputs.password }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ inputs.gpg-private-key }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ inputs.gpg-passphrase }} + run: ./gradlew publishToMavenCentral -Psigning.gnupg.executable=gpg -Psigning.gnupg.passphrase="$ORG_GRADLE_PROJECT_signingInMemoryKeyPassword" diff --git a/.github/actions/run-deployment-test/action.yml b/.github/actions/run-deployment-test/action.yml index 264e9d3279..655dde9377 100644 --- a/.github/actions/run-deployment-test/action.yml +++ b/.github/actions/run-deployment-test/action.yml @@ -49,31 +49,38 @@ inputs: runs: using: "composite" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java - uses: ./.github/actions/setup-helm - uses: ./.github/actions/setup-kubectl - name: Create k8s Kind Cluster - uses: helm/kind-action@v1.14.0 + uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0 with: node_image: kindest/node:${{ inputs.k8sversion }} - name: Build docker images shell: bash + env: + ROOT_DIR: ${{ inputs.rootDir }} run: |- - modules=(${{ inputs.rootDir }}) + read -ra modules <<< "$ROOT_DIR" for module in "${modules[@]}" do - ./gradlew -p $module dockerize + ./gradlew -p "$module" dockerize done - name: Load images into KinD shell: bash + env: + IMAGE_NAME: ${{ inputs.imagename }} + IMAGE_TAG: ${{ inputs.image_tag }} run: | - images=(${{ inputs.imagename }}) - versioned=( "${images[@]/%/:${{ inputs.image_tag }}}" ) + read -ra images <<< "$IMAGE_NAME" + versioned=( "${images[@]/%/:$IMAGE_TAG}" ) versioned_images=$(IFS=' ' ; echo "${versioned[*]}") kind get clusters | xargs -n1 kind load docker-image $versioned_images --name @@ -83,7 +90,9 @@ runs: - name: Install Runtime shell: bash - run: ${{ inputs.helm_command }} + env: + HELM_COMMAND: ${{ inputs.helm_command }} + run: eval "$HELM_COMMAND" - name: Print logs if: failure() diff --git a/.github/actions/setup-helm/action.yml b/.github/actions/setup-helm/action.yml index 02d868f9f4..1e3b24f75e 100644 --- a/.github/actions/setup-helm/action.yml +++ b/.github/actions/setup-helm/action.yml @@ -24,6 +24,6 @@ description: "Setup Helm" runs: using: "composite" steps: - - uses: azure/setup-helm@v4 + - uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1 with: version: v3.16.1 diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index cf2d2a9f89..ccd198951b 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -26,9 +26,9 @@ runs: using: "composite" steps: - name: Setup JDK 21 - uses: actions/setup-java@v5.2.0 + uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 with: java-version: '21' distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v5 + uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2 diff --git a/.github/actions/setup-kubectl/action.yml b/.github/actions/setup-kubectl/action.yml index 369400d154..0fc88c9952 100644 --- a/.github/actions/setup-kubectl/action.yml +++ b/.github/actions/setup-kubectl/action.yml @@ -24,6 +24,6 @@ description: "Setup Kubectl" runs: using: "composite" steps: - - uses: azure/setup-kubectl@v4 + - uses: azure/setup-kubectl@776406bce94f63e41d621b960d78ee25c8b76ede # v4.0.1 with: version: v1.31.1 diff --git a/.github/actions/update-version-and-charts/action.yml b/.github/actions/update-version-and-charts/action.yml index 3d6ce14e4a..1c49933757 100644 --- a/.github/actions/update-version-and-charts/action.yml +++ b/.github/actions/update-version-and-charts/action.yml @@ -33,36 +33,46 @@ runs: - name: Resolve version id: resolver shell: bash + env: + BUMP_VERSION: ${{ inputs.bump_version }} + INPUT_VERSION: ${{ inputs.version }} run: | - if [[ "${{ inputs.bump_version }}" == "true" ]] then - IFS=.- read -r MAJOR MINOR PATCH SNAPSHOT<<<"${{ inputs.version }}" + if [[ "$BUMP_VERSION" == "true" ]] then + IFS=.- read -r MAJOR MINOR PATCH SNAPSHOT<<<"$INPUT_VERSION" VERSION="$MAJOR.$((MINOR+1)).0-SNAPSHOT" else - VERSION=${{ inputs.version }} + VERSION="$INPUT_VERSION" fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" - name: Bump version in /charts - uses: mikefarah/yq@v4.53.2 + uses: mikefarah/yq@5a7e72a743649b1b3a47d1a1d8214f3453173c51 # v4.52.4 + env: + RESOLVED_VERSION: ${{ steps.resolver.outputs.version }} with: cmd: | - find charts -name Chart.yaml -maxdepth 3 | xargs -n1 yq -i '.appVersion = "${{ steps.resolver.outputs.version }}" - | .version = "${{ steps.resolver.outputs.version }}"' + find charts -name Chart.yaml -maxdepth 3 | xargs -n1 yq -i '.appVersion = env(RESOLVED_VERSION) | .version = env(RESOLVED_VERSION)' - name: Update Chart READMEs shell: bash run: | - docker run -v ${{ github.workspace }}/charts:/helm-docs jnorwood/helm-docs helm-docs + docker run -v "${GITHUB_WORKSPACE}/charts:/helm-docs" jnorwood/helm-docs helm-docs - name: Update version in gradle.properties shell: bash + env: + RESOLVED_VERSION: ${{ steps.resolver.outputs.version }} run: |- - sed -i 's/version=.*/version=${{ steps.resolver.outputs.version }}/g' gradle.properties + sed -i 's/version=.*/version='"$RESOLVED_VERSION"'/g' gradle.properties - name: Commit changes id: make-commit shell: bash + env: + BUMP_VERSION: ${{ inputs.bump_version }} + INPUT_VERSION: ${{ inputs.version }} + RESOLVED_VERSION: ${{ steps.resolver.outputs.version }} run: | - if [[ "${{ inputs.bump_version }}" == "true" ]] then - MESSAGE="Bump to version ${{ steps.resolver.outputs.version }}" + if [[ "$BUMP_VERSION" == "true" ]] then + MESSAGE="Bump to version $RESOLVED_VERSION" else - MESSAGE="Prepare release ${{ inputs.version }}" + MESSAGE="Prepare release $INPUT_VERSION" fi git add . diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0979491a74..4378581791 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -34,6 +34,8 @@ updates: schedule: interval: "weekly" open-pull-requests-limit: 50 + cooldown: + default-days: 7 ignore: - dependency-name: "org.eclipse.dataspacetck.dsp:*" - dependency-name: "org.eclipse.dataspacetck.dcp:*" @@ -51,6 +53,8 @@ updates: schedule: interval: "weekly" open-pull-requests-limit: 50 + cooldown: + default-days: 7 # Docker - package-ecosystem: "docker" @@ -65,3 +69,5 @@ updates: schedule: interval: "weekly" open-pull-requests-limit: 50 + cooldown: + default-days: 7 diff --git a/.github/scripts/fix-poutine-sarif.py b/.github/scripts/fix-poutine-sarif.py new file mode 100644 index 0000000000..ca8cf30928 --- /dev/null +++ b/.github/scripts/fix-poutine-sarif.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +################################################################################# +# Copyright (c) 2026 Cofinity-X GmbH +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +""" +Fix and patch the poutine SARIF output: + 1. Restore empty URI locations for composite action findings. + 2. Patch artifact lengths (-1 → real file size) so GitHub Advanced Security + can correctly map findings to source lines. +""" + +import json +import os +import re + +VERIFIED_OWNERS = { + "actions", "github", "docker", "gradle", "step-security", + "aws-actions", "google-github-actions", "azure", "hashicorp", + "slsa-framework", "sigstore", "ossf", +} + +with open("results.sarif") as f: + sarif = json.load(f) + +# ── Fix 1: Restore empty URI locations for composite action findings ────────── +# poutine bug: github_action_from_unverified_creator_used in composite action.yml +# files is emitted with empty artifactLocation.uri. Reconstruct from scanned files. +scanned_files = [] +for run in sarif.get("runs", []): + for artifact in run.get("artifacts", []): + uri = artifact.get("location", {}).get("uri", "") + if uri and os.path.isfile(uri): + scanned_files.append(uri) + +unverified_locations = [] +for filepath in scanned_files: + with open(filepath) as f: + for lineno, line in enumerate(f, 1): + m = re.search(r"uses:\s*([^\s#]+)", line) + if m: + ref = m.group(1) + owner = ref.split("/")[0] if "/" in ref else "" + if owner and owner not in VERIFIED_OWNERS and not ref.startswith("."): + unverified_locations.append((filepath, lineno, ref)) + +fixed_idx = 0 +for run in sarif.get("runs", []): + for result in run.get("results", []): + if result.get("ruleId") != "github_action_from_unverified_creator_used": + continue + uri = ( + result.get("locations", [{}])[0] + .get("physicalLocation", {}) + .get("artifactLocation", {}) + .get("uri", "") + ) + if uri: + continue + if fixed_idx < len(unverified_locations): + filepath, lineno, ref = unverified_locations[fixed_idx] + result["locations"] = [{ + "physicalLocation": { + "artifactLocation": {"uri": filepath}, + "region": {"startLine": lineno, "endLine": lineno}, + } + }] + print(f"Fixed location -> {filepath}:{lineno} ({ref})") + fixed_idx += 1 + +# ── Fix 2: Patch artifact lengths (-1 → real size) ─────────────────────────── +# poutine emits length=-1 which causes GitHub Advanced Security to ignore +# startLine and show every finding at line 1 in the Security tab. +for run in sarif.get("runs", []): + for artifact in run.get("artifacts", []): + uri = artifact.get("location", {}).get("uri", "").lstrip("./") + if uri and os.path.isfile(uri): + artifact["length"] = os.path.getsize(uri) + +with open("results-fixed.sarif", "w") as f: + json.dump(sarif, f) + +print(f"Done. Fixed {fixed_idx} location(s). Written to results-fixed.sarif.") + diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 8e7aa6d0fa..e5cb0492ad 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -54,12 +54,18 @@ jobs: # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -78,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 with: - category: "/language:${{matrix.language}}" \ No newline at end of file + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index 56c4cac644..385130428e 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -22,7 +22,7 @@ name: Copy labels from closing issue to PR on: - pull_request_target: + pull_request_target: # zizmor: ignore[dangerous-triggers] types: [opened, edited] permissions: @@ -33,8 +33,12 @@ jobs: copy-labels: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Copy labels from linked issue to PR - uses: actions/github-script@v9 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: | const CLOSING_KEYWORDS = /\b(?:closes?|fixes?|resolves?)\s+#(\d+)\b/gi; diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index c737fc7a79..1b799b5859 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -27,13 +27,20 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: +permissions: + contents: read + jobs: test-prepare: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Cache ContainerD Image Layers - uses: actions/cache@v5 + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs key: ${{ runner.os }}-io.containerd.snapshotter.v1.overlayfs @@ -42,7 +49,13 @@ jobs: runs-on: ubuntu-latest needs: test-prepare steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/run-deployment-test name: "Run deployment test using KinD and Helm" with: @@ -70,8 +83,14 @@ jobs: "v1.34.3", "v1.33.7" ] steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/run-deployment-test name: "Run deployment test using KinD and Helm" with: diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 1b2260520a..7b314dbf46 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -31,24 +31,35 @@ on: description: 'The version you want to release.' required: true +permissions: + contents: read + jobs: validate-and-prepare: name: "Validate that tag does not already exist and prepare branch" runs-on: ubuntu-latest - if: ${{ github.ref_name == 'main' || github.ref_type == 'tag' }} + if: ${{ github.ref_name == 'main' || github.ref_type == 'tag' }} outputs: branch_name: ${{ steps.resolve_branch.outputs.branch_name }} is_official_release: ${{ steps.validation.outputs.is_official_release }} steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - id: validation name: "Validations" shell: bash + env: + INPUT_VERSION: ${{ inputs.version }} + REF_TYPE: ${{ github.ref_type }} run: | shopt -s nocasematch - IFS=.- read -r MAJOR_INPUT MINOR_INPUT PATCH_INPUT SNAPSHOT_INPUT<<<"${{ inputs.version }}" + IFS=.- read -r MAJOR_INPUT MINOR_INPUT PATCH_INPUT SNAPSHOT_INPUT<<<"$INPUT_VERSION" VERSION=$(grep "version" gradle.properties | awk -F= '{print $2}') IFS=.- read -r MAJOR MINOR PATCH SNAPSHOT<<<"$VERSION" @@ -62,14 +73,14 @@ jobs: # Bugfix elif [[ -z $SNAPSHOT_INPUT && $PATCH_INPUT != '0' ]] then - if [[ ${{ github.ref_type }} != 'tag' || ! -z $SNAPSHOT ]] then + if [[ $REF_TYPE != 'tag' || ! -z $SNAPSHOT ]] then echo "You want to build a bugfix, but the selected commit is neither a bugfix nor an official release" exit 1 fi # Official Release elif [[ -z $SNAPSHOT_INPUT && $PATCH_INPUT == '0' ]] then - if [[ ${{ github.ref_type }} != 'tag' || $SNAPSHOT != *rc* ]] then + if [[ $REF_TYPE != 'tag' || $SNAPSHOT != *rc* ]] then echo "You want to build an official release, but the selected commit is not a release candidate" exit 1 fi @@ -83,19 +94,22 @@ jobs: - id: check-tag name: "Check if tag exists" + env: + INPUT_VERSION: ${{ inputs.version }} run: |- - - tag=$(git tag -l ${{ inputs.version }}) - + tag=$(git tag -l "$INPUT_VERSION") + if [ ! -z $tag ]; then - echo "Tag ${{ inputs.version }} already exists! Please choose another tag." + echo "Tag $INPUT_VERSION already exists! Please choose another tag." exit 1 fi - id: resolve_branch name: "Resolve branch name" + env: + INPUT_VERSION: ${{ inputs.version }} run: | - echo "branch_name=release/${{ inputs.version }}" >> "$GITHUB_OUTPUT" + echo "branch_name=release/$INPUT_VERSION" >> "$GITHUB_OUTPUT" draft-new-release: name: "Draft a new release" @@ -106,9 +120,14 @@ jobs: packages: write pages: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # zizmor: ignore[artipacked] + with: + persist-credentials: true - name: Create Release branch - run: git checkout -b ${{ needs.validate-and-prepare.outputs.branch_name }} + env: + BRANCH_NAME: ${{ needs.validate-and-prepare.outputs.branch_name }} + run: | + git checkout -b "$BRANCH_NAME" - uses: ./.github/actions/setup-java - name: Version and Chart Updates uses: ./.github/actions/update-version-and-charts @@ -116,7 +135,9 @@ jobs: version: ${{ inputs.version }} bump_version: "false" - name: Push new branch - run: git push origin ${{ needs.validate-and-prepare.outputs.branch_name }} + env: + BRANCH_NAME: ${{ needs.validate-and-prepare.outputs.branch_name }} + run: git push origin "$BRANCH_NAME" - name: Check dependencies before release uses: ./.github/actions/generate-and-check-dependencies with: @@ -125,6 +146,8 @@ jobs: run: sed -i "s#\[DEPENDENCIES\]\(.*\)#\[DEPENDENCIES\]\(DEPENDENCIES\)#g" NOTICE.md - name: Commit DEPENDENCIES changes shell: bash + env: + BRANCH_NAME: ${{ needs.validate-and-prepare.outputs.branch_name }} run: | if git diff --quiet -- DEPENDENCIES; then echo "No changes in DEPENDENCIES, skipping commit." @@ -135,5 +158,5 @@ jobs: git config user.name "eclipse-tractusx-bot" git config user.email "tractusx-bot@eclipse.org" git commit --message "Update DEPENDENCIES file" - git push origin ${{ needs.validate-and-prepare.outputs.branch_name }} + git push origin "$BRANCH_NAME" echo "commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index 907dcee055..90679925c9 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -34,7 +34,13 @@ jobs: check-dependencies: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: true - uses: ./.github/actions/setup-java - name: Output release type id: release_type @@ -59,7 +65,7 @@ jobs: cp DEPENDENCIES public/ - name: Publish to GitHub Pages if: ${{ github.ref_name == 'main' }} - uses: peaceiris/actions-gh-pages@v4 + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: public @@ -70,6 +76,8 @@ jobs: - name: Commit DEPENDENCIES changes if: ${{ startsWith(github.ref_name, 'release/') }} shell: bash + env: + REF_NAME: ${{ github.ref_name }} run: | if git diff --quiet -- DEPENDENCIES; then echo "No changes in DEPENDENCIES, skipping commit." @@ -80,5 +88,5 @@ jobs: git config user.name "eclipse-tractusx-bot" git config user.email "tractusx-bot@eclipse.org" git commit --message "Update DEPENDENCIES file" - git push origin ${{ github.ref_name }} + git push origin "$REF_NAME" echo "commit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 7cef5f3386..1284d73be2 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -38,23 +38,31 @@ on: - '**' - '!charts/**' +permissions: + contents: read + jobs: helm-lint: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit ############## ### Set-Up ### ############## - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - uses: ./.github/actions/setup-helm - name: python (setup) - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: 3.13 - name: chart-testing (setup) - uses: helm/chart-testing-action@v2.8.0 + uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0 ##################### ### Chart Testing ### ##################### diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 3a02b17da9..6519b218f1 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -31,6 +31,9 @@ on: schedule: - cron: "0 0 * * *" +permissions: + contents: read + jobs: analyze: name: Analyze @@ -41,10 +44,16 @@ jobs: security-events: write steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: KICS scan - uses: checkmarx/kics-github-action@v2.1.20 + uses: checkmarx/kics-github-action@05aa5eb70eede1355220f4ca5238d96b397e30a6 # v2.1.20 with: path: "." fail_on: high @@ -55,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index e8f84038f4..295cec08e4 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -27,6 +27,9 @@ on: paths: - 'core/json-ld-core/src/main/resources/document/**' +permissions: + contents: write + jobs: build: runs-on: ubuntu-latest @@ -34,15 +37,21 @@ jobs: contents: write pages: write steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: copy contexts into public folder run: | mkdir -p public/context cp core/json-ld-core/src/main/resources/document/tx-auth-v1.jsonld public/context/ - name: deploy to gh-pages - uses: peaceiris/actions-gh-pages@v4 + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public - keep_files: true \ No newline at end of file + keep_files: true diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index c58f55582c..301537b99f 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -26,13 +26,30 @@ name: "Publish new snapshot" run-name: "Publish new snapshot from ${{github.ref_name}}" on: - workflow_run: - workflows: [ "Run-All-Tests" ] - branches: - - main - - release/* - types: - - completed + workflow_call: + inputs: + dated_snapshot: + type: boolean + required: false + default: false + description: 'Dated snapshot version.' + secrets: + DOCKER_HUB_USER: + required: false + DOCKER_HUB_TOKEN: + required: false + ORG_GPG_PRIVATE_KEY: + required: false + ORG_GPG_PASSPHRASE: + required: false + CENTRAL_SONATYPE_TOKEN_USERNAME: + required: false + CENTRAL_SONATYPE_TOKEN_PASSWORD: + required: false + SWAGGERHUB_API_KEY: + required: false + SWAGGERHUB_USER: + required: false workflow_dispatch: inputs: dated_snapshot: @@ -48,6 +65,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: secret-presence: runs-on: ubuntu-latest @@ -56,6 +76,10 @@ jobs: HAS_MVNCRED: ${{ steps.secret-presence.outputs.HAS_MVNCRED }} HAS_SWAGGER: ${{ steps.secret-presence.outputs.HAS_SWAGGER }} steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Check whether secrets exist id: secret-presence run: | @@ -75,14 +99,21 @@ jobs: VERSION: ${{ steps.get-version.outputs.VERSION }} DATED: ${{ steps.get-version.outputs.DATED }} steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: "Get version" id: get-version + env: + DATED_SNAPSHOT: ${{ inputs.dated_snapshot }} run: | - IFS=.- read -r RELEASE_VERSION_MAJOR RELEASE_VERSION_MINOR RELEASE_VERSION_PATCH SNAPSHOT<<<$(grep "version" gradle.properties | awk -F= '{print $2}') - if [[ "${{ github.event.workflow_run.event }}" == "schedule" || "${{ inputs.dated_snapshot }}" == "true" ]]; then + if [[ "$DATED_SNAPSHOT" == "true" ]]; then echo "VERSION=$RELEASE_VERSION_MAJOR.$RELEASE_VERSION_MINOR.$RELEASE_VERSION_PATCH-$(date +"%Y%m%d")-SNAPSHOT" >> "$GITHUB_OUTPUT" echo "DATED=true" >> "$GITHUB_OUTPUT" else @@ -97,7 +128,9 @@ jobs: permissions: contents: write uses: ./.github/workflows/trigger-docker-publish.yaml - secrets: inherit + secrets: + DOCKER_HUB_USER: ${{ secrets.DOCKER_HUB_USER }} + DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} with: docker_tag: ${{ needs.determine-version.outputs.VERSION }} @@ -110,7 +143,11 @@ jobs: if: | needs.secret-presence.outputs.HAS_MVNCRED uses: ./.github/workflows/trigger-maven-publish.yaml - secrets: inherit + secrets: + ORG_GPG_PRIVATE_KEY: ${{ secrets.ORG_GPG_PRIVATE_KEY }} + ORG_GPG_PASSPHRASE: ${{ secrets.ORG_GPG_PASSPHRASE }} + CENTRAL_SONATYPE_TOKEN_USERNAME: ${{ secrets.CENTRAL_SONATYPE_TOKEN_USERNAME }} + CENTRAL_SONATYPE_TOKEN_PASSWORD: ${{ secrets.CENTRAL_SONATYPE_TOKEN_PASSWORD }} with: version: ${{ needs.determine-version.outputs.VERSION }} @@ -120,7 +157,6 @@ jobs: contents: write needs: [ secret-presence, determine-version ] uses: ./.github/workflows/publish-openapi-ui.yml - secrets: inherit with: version: ${{ needs.determine-version.outputs.VERSION }} latest: false @@ -133,7 +169,13 @@ jobs: needs: [ determine-version ] if: ${{ needs.determine-version.outputs.DATED == 'true' }} steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/publish-latest-versioned-snapshot env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish-openapi-ui.yml b/.github/workflows/publish-openapi-ui.yml index d3b6639499..2763174efc 100644 --- a/.github/workflows/publish-openapi-ui.yml +++ b/.github/workflows/publish-openapi-ui.yml @@ -46,16 +46,21 @@ on: type: boolean default: false +permissions: + contents: read + jobs: generate-openapi-spec: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java - name: Generate openapi spec run: ./gradlew resolve - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: openapi-spec path: resources/openapi/yaml @@ -70,48 +75,58 @@ jobs: { name: "data-plane", folder: "edc-dataplane/edc-dataplane-base" } ] steps: - - uses: actions/checkout@v6 - - uses: eclipse-edc/.github/.github/actions/setup-build@main - - uses: actions/download-artifact@v8 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: ./.github/actions/setup-java + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: openapi-spec path: resources/openapi/yaml - name: Set version + env: + INPUT_VERSION: ${{ inputs.version }} run: | - if [ -z ${{ inputs.version }} ]; then - export VERSION=$(grep "version" gradle.properties | awk -F= '{print $2}') + if [ -z "$INPUT_VERSION" ]; then + VERSION=$(grep "version" gradle.properties | awk -F= '{print $2}') else - export VERSION=${{ inputs.version }} + VERSION="$INPUT_VERSION" fi echo "VERSION=$VERSION" >> "$GITHUB_ENV" - name: Download upstream API specs for ${{ matrix.apiGroup.name }} + env: + API_FOLDER: ${{ matrix.apiGroup.folder }} + API_NAME: ${{ matrix.apiGroup.name }} run: | - ./gradlew -p ${{ matrix.apiGroup.folder }} downloadOpenapi - cp ${{ matrix.apiGroup.folder }}/build/docs/openapi/* resources/openapi/yaml/${{ matrix.apiGroup.name }} + ./gradlew -p "$API_FOLDER" downloadOpenapi + cp "$API_FOLDER/build/docs/openapi/"* "resources/openapi/yaml/$API_NAME" - name: Merge API specs + env: + API_NAME: ${{ matrix.apiGroup.name }} + VERSION: ${{ env.VERSION }} run: | - ./gradlew mergeOpenApiSpec --inputDir=${PWD}/resources/openapi/yaml/${{ matrix.apiGroup.name }} --output=${{ matrix.apiGroup.name }}.yaml --infoTitle="Tractus-X EDC ${{ matrix.apiGroup.name }} API" --infoDescription="Tractus-X EDC ${{ matrix.apiGroup.name }} API Documentation" --infoVersion=${{ env.VERSION }} + ./gradlew mergeOpenApiSpec --inputDir="${PWD}/resources/openapi/yaml/$API_NAME" --output="$API_NAME.yaml" --infoTitle="Tractus-X EDC $API_NAME API" --infoDescription="Tractus-X EDC $API_NAME API Documentation" --infoVersion=$VERSION - name: Generate Swagger UI current version - uses: Legion2/swagger-ui-action@v1 + uses: Legion2/swagger-ui-action@eff65dc3f193f0a749872be82f74baa35be0797d # v1.3.0 with: output: dist/${{ env.VERSION }} spec-file: ${{ matrix.apiGroup.name }}.yaml GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate Swagger UI stable version - uses: Legion2/swagger-ui-action@v1 + uses: Legion2/swagger-ui-action@eff65dc3f193f0a749872be82f74baa35be0797d # v1.3.0 if: ${{ inputs.latest }} with: output: dist spec-file: ${{ matrix.apiGroup.name }}.yaml GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ${{ matrix.apiGroup.name }}-api path: dist @@ -122,12 +137,12 @@ jobs: permissions: contents: write steps: - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: openapi pattern: "*-api" - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@v4 + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d87232216..61a75d542d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,6 +39,9 @@ on: default: "" +permissions: + contents: read + jobs: run-all-tests: name: "Run All Tests" @@ -52,9 +55,14 @@ jobs: RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }} update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: Output release version id: release-version run: | @@ -62,8 +70,10 @@ jobs: echo "RELEASE_VERSION=$VERSION" >> $GITHUB_OUTPUT - name: Output update main branch version id: update-main + env: + RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }} run: | - IFS=.- read -r MAJOR MINOR PATCH SNAPSHOT<<<"${{ steps.release-version.outputs.RELEASE_VERSION }}" + IFS=.- read -r MAJOR MINOR PATCH SNAPSHOT<<<"$RELEASE_VERSION" if [[ $PATCH == '0' && -z $SNAPSHOT ]]; then echo "update_main_branch_version=true" >> $GITHUB_OUTPUT @@ -71,25 +81,31 @@ jobs: echo "update_main_branch_version=false" >> $GITHUB_OUTPUT fi - name: Validations + env: + REPOSITORY: ${{ github.repository }} + REF_NAME: ${{ github.ref_name }} + RELEASE_VERSION: ${{ steps.release-version.outputs.RELEASE_VERSION }} run: | - if [[ "${{ github.repository }}" != "eclipse-tractusx/tractusx-edc" ]]; then + if [[ "$REPOSITORY" != "eclipse-tractusx/tractusx-edc" ]]; then echo "This workflow can only be run on the eclipse-tractusx/tractusx-edc repository." exit 1 fi - if [[ ! "${{ github.ref_name }}" =~ ^release/ ]]; then + if [[ ! "$REF_NAME" =~ ^release/ ]]; then echo "This workflow can only be run on the branches starting with release/." exit 1 fi - if [[ "${{steps.release-version.outputs.RELEASE_VERSION}}" =~ SNAPSHOT ]]; then + if [[ "$RELEASE_VERSION" =~ SNAPSHOT ]]; then echo "This workflow can not be executed for SNAPSHOT versions." exit 1 fi - name: Validate previous_tag exists + env: + PREVIOUS_TAG: ${{ inputs.previous_tag }} run: | - git show-ref --tags --verify --quiet "refs/tags/${{ inputs.previous_tag }}" \ - || (echo "Tag '${{ inputs.previous_tag }}' not found." && exit 1) + git show-ref --tags --verify --quiet "refs/tags/$PREVIOUS_TAG" \ + || (echo "Tag '$PREVIOUS_TAG' not found." && exit 1) # Release: Maven Artifacts @@ -100,7 +116,11 @@ jobs: contents: read if: needs.validation.outputs.RELEASE_VERSION uses: ./.github/workflows/trigger-maven-publish.yaml - secrets: inherit + secrets: + ORG_GPG_PRIVATE_KEY: ${{ secrets.ORG_GPG_PRIVATE_KEY }} + ORG_GPG_PASSPHRASE: ${{ secrets.ORG_GPG_PASSPHRASE }} + CENTRAL_SONATYPE_TOKEN_USERNAME: ${{ secrets.CENTRAL_SONATYPE_TOKEN_USERNAME }} + CENTRAL_SONATYPE_TOKEN_PASSWORD: ${{ secrets.CENTRAL_SONATYPE_TOKEN_PASSWORD }} with: version: ${{ needs.validation.outputs.RELEASE_VERSION }} @@ -110,7 +130,9 @@ jobs: needs: [ validation ] if: needs.validation.outputs.RELEASE_VERSION uses: ./.github/workflows/trigger-docker-publish.yaml - secrets: inherit + secrets: + DOCKER_HUB_USER: ${{ secrets.DOCKER_HUB_USER }} + DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} with: docker_tag: ${{ needs.validation.outputs.RELEASE_VERSION }} @@ -125,11 +147,18 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: true - uses: ./.github/actions/setup-helm - name: Package helm, update index.yaml and push to gh-pages + env: + RELEASE_VERSION: ${{ needs.validation.outputs.RELEASE_VERSION }} run: | # Prepare git env git config user.name "eclipse-tractusx-bot" @@ -146,7 +175,7 @@ jobs: # Commit and push to gh-pages git add index.yaml helm-charts - git commit -s -m "Release ${{ needs.validation.outputs.RELEASE_VERSION }}" + git commit -s -m "Release $RELEASE_VERSION" git push origin gh-pages @@ -158,7 +187,13 @@ jobs: contents: write if: needs.validation.outputs.RELEASE_VERSION steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: true - name: Prepare Git Config shell: bash run: | @@ -168,23 +203,32 @@ jobs: - name: Create Release Tag id: create_release_tag shell: bash + env: + RELEASE_VERSION: ${{ needs.validation.outputs.RELEASE_VERSION }} run: | # informative git branch -a git tag # Create & push tag - git tag ${{ needs.validation.outputs.RELEASE_VERSION }} - git push origin ${{ needs.validation.outputs.RELEASE_VERSION }} + git tag "$RELEASE_VERSION" + git push origin "$RELEASE_VERSION" - name: Create GitHub Release - uses: ncipollo/release-action@v1 - with: - generateReleaseNotes: true - generateReleaseNotesPreviousTag: ${{ inputs.previous_tag }} - tag: ${{ needs.validation.outputs.RELEASE_VERSION }} - token: ${{ secrets.GITHUB_TOKEN }} - makeLatest: ${{ inputs.latest }} - removeArtifacts: true + env: + RELEASE_VERSION: ${{ needs.validation.outputs.RELEASE_VERSION }} + PREVIOUS_TAG: ${{ inputs.previous_tag }} + MAKE_LATEST: ${{ inputs.latest }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + LATEST_FLAG="" + if [[ "$MAKE_LATEST" == "true" ]]; then + LATEST_FLAG="--latest" + fi + gh release create "$RELEASE_VERSION" \ + --generate-notes \ + --notes-start-tag "$PREVIOUS_TAG" \ + --verify-tag \ + $LATEST_FLAG # Release: Publish specs to GitHub Pages publish-openapi-to-gh-pages: @@ -193,7 +237,6 @@ jobs: contents: write needs: [ validation ] uses: ./.github/workflows/publish-openapi-ui.yml - secrets: inherit with: version: ${{ needs.validation.outputs.RELEASE_VERSION }} latest: ${{ inputs.latest }} @@ -207,13 +250,22 @@ jobs: contents: write if: needs.validation.outputs.RELEASE_VERSION steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - - uses: actions/github-script@v9 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + RELEASE_VERSION: ${{ needs.validation.outputs.RELEASE_VERSION }} with: script: | const { owner, repo } = context.repo; - const version = "${{ needs.validation.outputs.RELEASE_VERSION }}"; + const version = process.env.RELEASE_VERSION; const { data: release } = await github.rest.repos.getReleaseByTag({ owner, @@ -241,11 +293,16 @@ jobs: packages: write pages: write steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Checkout main - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 ref: main + persist-credentials: true - name: Version and Chart Updates uses: ./.github/actions/update-version-and-charts with: diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 0ea3c246ee..2e7e98e623 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -42,19 +42,24 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: {} + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: verify: + permissions: + contents: read uses: ./.github/workflows/verify.yaml - secrets: inherit deployment-test: + permissions: + contents: read uses: ./.github/workflows/deployment-test.yaml - secrets: inherit upgradeability-test: + permissions: + contents: read uses: ./.github/workflows/upgradeability-test.yaml - secrets: inherit # this job really serves no other purpose than waiting for the other two test workflows # in future iterations, this could be used as a choke point to collect test data, etc. @@ -68,3 +73,22 @@ jobs: - name: 'Master test job' run: echo "all test jobs have run by now" + publish-snapshot: + name: "Publish new snapshot" + needs: [ summary ] + permissions: + contents: write + if: ${{ github.ref_name == 'main' || startsWith(github.ref_name, 'release/') }} + uses: ./.github/workflows/publish-new-snapshot.yaml + with: + dated_snapshot: ${{ github.event_name == 'schedule' }} + secrets: + DOCKER_HUB_USER: ${{ secrets.DOCKER_HUB_USER }} + DOCKER_HUB_TOKEN: ${{ secrets.DOCKER_HUB_TOKEN }} + ORG_GPG_PRIVATE_KEY: ${{ secrets.ORG_GPG_PRIVATE_KEY }} + ORG_GPG_PASSPHRASE: ${{ secrets.ORG_GPG_PASSPHRASE }} + CENTRAL_SONATYPE_TOKEN_USERNAME: ${{ secrets.CENTRAL_SONATYPE_TOKEN_USERNAME }} + CENTRAL_SONATYPE_TOKEN_PASSWORD: ${{ secrets.CENTRAL_SONATYPE_TOKEN_PASSWORD }} + SWAGGERHUB_API_KEY: ${{ secrets.SWAGGERHUB_API_KEY }} + SWAGGERHUB_USER: ${{ secrets.SWAGGERHUB_USER }} + diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index d18116f5f5..a66acbdb00 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -28,21 +28,28 @@ on: - cron: "0 0 * * *" # Once a day permissions: - actions: read contents: read - security-events: write - id-token: write - issues: write jobs: ScanSecrets: name: Scan secrets runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + id-token: write + issues: write steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Checkout Repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Ensure full clone for pull request workflows + persist-credentials: false - name: TruffleHog OSS id: trufflehog diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 2e73531417..02ddb1b9df 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -29,13 +29,20 @@ on: - cron: "30 1 * * *" # once a day (1:30 UTC) workflow_dispatch: # allow manual trigger +permissions: + contents: read + jobs: close-issues-with-assignee: runs-on: ubuntu-latest permissions: issues: write steps: - - uses: actions/stale@v10 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 with: operations-per-run: 1000 days-before-issue-stale: 32 diff --git a/.github/workflows/triage-issue.yml b/.github/workflows/triage-issue.yml index 72805dc71f..7f818177b1 100644 --- a/.github/workflows/triage-issue.yml +++ b/.github/workflows/triage-issue.yml @@ -26,12 +26,19 @@ on: - reopened - opened +permissions: + contents: read + jobs: label-issue: runs-on: ubuntu-latest permissions: issues: write steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - run: gh issue edit "$NUMBER" --add-label "$LABELS" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index 495528df0c..d51b06c389 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -45,6 +45,16 @@ on: type: string description: 'Explicitly specify the Docker tag. Note that SHA and latest are added automatically.' required: false + secrets: + DOCKER_HUB_USER: + required: false + description: 'DockerHub username' + DOCKER_HUB_TOKEN: + required: false + description: 'DockerHub token' + +permissions: + contents: read jobs: create-docker-image: @@ -58,12 +68,21 @@ jobs: { dir: edc-dataplane, img: edc-dataplane-hashicorp-vault }, { dir: edc-tests/runtime, img: mock-connector }] permissions: - contents: write + contents: read steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Log inputs + env: + INPUT_DOCKER_TAG: ${{ inputs.docker_tag }} + INPUT_NAMESPACE: ${{ inputs.namespace }} run: | - echo "Input Version: ${{ inputs.docker_tag }}, Input namespace: ${{ inputs.namespace}}" + echo "Input Version: $INPUT_DOCKER_TAG, Input namespace: $INPUT_NAMESPACE" - uses: ./.github/actions/publish-docker-image name: Publish ${{ matrix.variant.img }} with: diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 78d5a2fb71..1b30deb9da 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -34,6 +34,22 @@ on: type: string required: false description: 'a semver string denoting the version. Append -SNAPSHOT for snapshots. If omitted, the version is taken from gradle.properties' + secrets: + ORG_GPG_PRIVATE_KEY: + required: false + description: 'GPG private key for signing' + ORG_GPG_PASSPHRASE: + required: false + description: 'GPG passphrase' + CENTRAL_SONATYPE_TOKEN_USERNAME: + required: false + description: 'Sonatype token username' + CENTRAL_SONATYPE_TOKEN_PASSWORD: + required: false + description: 'Sonatype token password' + +permissions: + contents: read jobs: maven-release: @@ -42,22 +58,30 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java - - run: | - echo "Input Version: ${{ inputs.version }}" + - name: Set version + env: + INPUT_VERSION: ${{ inputs.version }} + run: | + echo "Input Version: $INPUT_VERSION" # set the input version in gradle.properties, if passed - if [ ! -z ${{ inputs.version }} ]; + if [ ! -z "$INPUT_VERSION" ]; then - sed -i 's#^version=.*#version='"${{ inputs.version }}"'#g' $(find . -name "gradle.properties") - VERSION=${{ inputs.version }} + sed -i 's#^version=.*#version='"$INPUT_VERSION"'#g' $(find . -name "gradle.properties") fi grep version gradle.properties | (echo -n "Publishing using " && cat) - - uses: eclipse-edc/.github/.github/actions/publish-maven-artifacts@main + - uses: ./.github/actions/publish-maven-artifacts with: gpg-private-key: ${{ secrets.ORG_GPG_PRIVATE_KEY }} gpg-passphrase: ${{ secrets.ORG_GPG_PASSPHRASE }} diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 0574d1fd8f..813a962a0c 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -25,17 +25,10 @@ on: schedule: - cron: "0 0 * * *" workflow_dispatch: - workflow_run: - workflows: [ "Publish Artefacts" ] - branches: - - main - - releases - - release/* - - hotfix/* - tags: - - '[0-9]+.[0-9]+.[0-9]+' - types: - - completed + workflow_call: + +permissions: + contents: read jobs: git-sha7: @@ -44,6 +37,10 @@ jobs: outputs: value: ${{ steps.git-sha7.outputs.SHA7 }} steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Resolve git 7-chars sha id: git-sha7 run: | @@ -56,9 +53,15 @@ jobs: contents: read security-events: write steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@v0.36.0 + uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 with: scan-type: "config" # ignore-unfixed: true @@ -68,7 +71,7 @@ jobs: output: "trivy-results-config.sarif" severity: "CRITICAL,HIGH" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 if: always() with: sarif_file: "trivy-results-config.sarif" @@ -88,19 +91,28 @@ jobs: - edc-controlplane-postgresql-hashicorp-vault - edc-dataplane-hashicorp-vault steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false ## This step will fail if the docker images is not found - name: "Check if image exists" id: imageCheck + env: + IMAGE: ${{ matrix.image }} + SHA7: ${{ needs.git-sha7.outputs.value }} run: | - docker buildx imagetools inspect --format '{{ json . }}' tractusx/${{ matrix.image }}:sha-${{ needs.git-sha7.outputs.value }} + docker buildx imagetools inspect --format '{{ json . }}' "tractusx/$IMAGE:sha-$SHA7" continue-on-error: true ## the next two steps will only execute if the image exists check was successful - name: Run Trivy vulnerability scanner if: success() && steps.imageCheck.outcome != 'failure' - uses: aquasecurity/trivy-action@v0.36.0 + uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 with: image-ref: "tractusx/${{ matrix.image }}:sha-${{ needs.git-sha7.outputs.value }}" format: "sarif" @@ -110,6 +122,6 @@ jobs: timeout: "10m0s" - name: Upload Trivy scan results to GitHub Security tab if: success() && steps.imageCheck.outcome != 'failure' - uses: github/codeql-action/upload-sarif@v4 + uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 with: sarif_file: "trivy-results-${{ matrix.image }}.sarif" diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 1d88eebae0..8eef2c983c 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -27,13 +27,20 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: +permissions: + contents: read + jobs: test-prepare: runs-on: ubuntu-latest steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Cache ContainerD Image Layers - uses: actions/cache@v5 + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs key: ${{ runner.os }}-io.containerd.snapshotter.v1.overlayfs @@ -42,14 +49,20 @@ jobs: runs-on: ubuntu-latest needs: [ test-prepare ] steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-helm - uses: ./.github/actions/setup-kubectl - name: Create k8s Kind Cluster - uses: helm/kind-action@v1.14.0 + uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0 - name: "Update helm repo" run: | diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index e067eafc3d..78fc7220c4 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -27,14 +27,23 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: +permissions: + contents: read + jobs: verify-helm-docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - run: | - docker run -v ${{ github.workspace }}/charts:/helm-docs jnorwood/helm-docs helm-docs + docker run -v "${GITHUB_WORKSPACE}/charts:/helm-docs" jnorwood/helm-docs helm-docs if $(git diff --quiet --exit-code); then echo "Helm chart docs up to date" @@ -47,7 +56,13 @@ jobs: verify-formatting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java - name: Run Checkstyle @@ -57,7 +72,13 @@ jobs: verify-javadoc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java - name: Run Javadoc @@ -66,7 +87,13 @@ jobs: unit-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java @@ -75,7 +102,7 @@ jobs: # uploads the jacoco report as artifact - name: Upload JaCoCo Coverage Report - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: JaCoCo coverage-report path: build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml @@ -84,7 +111,7 @@ jobs: # generates coverage-report.md - name: JaCoCo Code Coverage Report id: jacoco_reporter - uses: PavanMudigonda/jacoco-reporter@v5.1 + uses: PavanMudigonda/jacoco-reporter@e8b54bfea6a667d1a68624dae8a06ba31670667d # v5.1 with: coverage_results_path: build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml skip_check_run: true @@ -92,17 +119,22 @@ jobs: # Publish Coverage Job Summary - name: Output KPIs from JaCoCo report + env: + COVERAGE_PERCENTAGE: ${{ steps.jacoco_reporter.outputs.coverage_percentage }} + COVERED_LINES: ${{ steps.jacoco_reporter.outputs.covered_lines }} + MISSED_LINES: ${{ steps.jacoco_reporter.outputs.missed_lines }} + TOTAL_LINES: ${{ steps.jacoco_reporter.outputs.total_lines }} run: | echo "| Outcome | Value |" >> $GITHUB_STEP_SUMMARY echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY - echo "| Code Coverage % | ${{ steps.jacoco_reporter.outputs.coverage_percentage }} |" >> $GITHUB_STEP_SUMMARY - echo "| :heavy_check_mark: Number of Lines Covered | ${{ steps.jacoco_reporter.outputs.covered_lines }} |" >> $GITHUB_STEP_SUMMARY - echo "| :x: Number of Lines Missed | ${{ steps.jacoco_reporter.outputs.missed_lines }} |" >> $GITHUB_STEP_SUMMARY - echo "| Total Number of Lines | ${{ steps.jacoco_reporter.outputs.total_lines }} |" >> $GITHUB_STEP_SUMMARY + echo "| Code Coverage % | $COVERAGE_PERCENTAGE |" >> $GITHUB_STEP_SUMMARY + echo "| :heavy_check_mark: Number of Lines Covered | $COVERED_LINES |" >> $GITHUB_STEP_SUMMARY + echo "| :x: Number of Lines Missed | $MISSED_LINES |" >> $GITHUB_STEP_SUMMARY + echo "| Total Number of Lines | $TOTAL_LINES |" >> $GITHUB_STEP_SUMMARY # uploads the coverage-report.md artifact - name: Upload Code Coverage Markdown Report - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: code-coverage-report-markdown path: "*/coverage-results.md" @@ -111,7 +143,13 @@ jobs: integration-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java @@ -123,7 +161,13 @@ jobs: api-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java @@ -135,7 +179,13 @@ jobs: outputs: matrix: ${{ steps.outputStep.outputs.matrix }} steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: get api groups and create matrix for next job id: outputStep run: | @@ -149,21 +199,31 @@ jobs: fail-fast: false matrix: ${{ fromJson(needs.prepare-end-to-end-tests.outputs.matrix) }} steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java - name: Run E2E tests (${{ matrix.dir }}) + env: + E2E_DIR: ${{ matrix.dir }} run: | ./gradlew compileJava compileTestJava - ./gradlew -p edc-tests/e2e/${{ matrix.dir }} test -DincludeTags="EndToEndTest" -PverboseTest=true --no-build-cache + ./gradlew -p "edc-tests/e2e/$E2E_DIR" test -DincludeTags="EndToEndTest" -PverboseTest=true --no-build-cache - name: Set sanitized artifact name + env: + E2E_DIR: ${{ matrix.dir }} run: | - SANITIZED_NAME=$(echo "edc-tests/e2e/${{ matrix.dir }}" | tr '/' '-') + SANITIZED_NAME=$(echo "edc-tests/e2e/$E2E_DIR" | tr '/' '-') echo "ARTIFACT_NAME=${SANITIZED_NAME}" >> $GITHUB_ENV - name: Upload test artifacts - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: allure-results-${{ env.ARTIFACT_NAME }} path: edc-tests/e2e/${{ matrix.dir }}/build/allure-results @@ -171,7 +231,13 @@ jobs: postgres-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java - name: Run Postgresql E2E tests @@ -180,7 +246,13 @@ jobs: compatibility-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: ./.github/actions/setup-java - name: Build docker images @@ -194,8 +266,14 @@ jobs: needs: end-to-end-tests if: ${{ github.ref_name == 'main' || startsWith(github.ref_name, 'release/') }} steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - name: Output report version id: release-version diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml new file mode 100644 index 0000000000..52b72e895b --- /dev/null +++ b/.github/workflows/workflow-security-lint.yaml @@ -0,0 +1,95 @@ +################################################################################# +# Copyright (c) 2026 Cofinity-X GmbH +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +--- +name: "Workflow Security Lint" + +on: + push: + branches: [ main ] + paths: + - '.github/workflows/**' + - '.github/actions/**' + pull_request: + paths: + - '.github/workflows/**' + - '.github/actions/**' + schedule: + - cron: "0 0 * * 1" # every Monday at 00:00 UTC + workflow_dispatch: + +permissions: + contents: read + +jobs: + zizmor: + name: "zizmor" + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write # required to upload SARIF to GitHub Advanced Security + steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: Run zizmor + uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 + with: + version: "1.23.1" + advanced-security: "true" + token: ${{ secrets.GITHUB_TOKEN }} + config: .github/zizmor.yml + + poutine: + name: "poutine" + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write # required to upload SARIF to GitHub Advanced Security + steps: + - name: Harden Runner + uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: Run poutine + uses: boostsecurityio/poutine-action@84c0a0d32e8d57ae12651222be1eb15351429228 # v0.15.2 + + - name: Fix and patch poutine SARIF + if: always() + run: python3 .github/scripts/fix-poutine-sarif.py + + - name: Upload poutine SARIF to GitHub Advanced Security + uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 + if: always() + with: + sarif_file: results-fixed.sarif + category: poutine diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000000..fd33965d6f --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,28 @@ +################################################################################# +# Copyright (c) 2026 Cofinity-X GmbH +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +rules: + unpinned-uses: + config: + policies: + # eclipse-tractusx/sig-infra has no release tags and is a first-party + # Eclipse Tractus-X org repo — ref-pin (branch reference) is acceptable. + "eclipse-tractusx/*": ref-pin + # everything else must be fully hash-pinned + "*": hash-pin diff --git a/edc-tests/runtime/runtime-compatibility/stable/connector-stable/src/main/docker/Dockerfile b/edc-tests/runtime/runtime-compatibility/stable/connector-stable/src/main/docker/Dockerfile index 08121bdd85..5567531bf4 100644 --- a/edc-tests/runtime/runtime-compatibility/stable/connector-stable/src/main/docker/Dockerfile +++ b/edc-tests/runtime/runtime-compatibility/stable/connector-stable/src/main/docker/Dockerfile @@ -1,5 +1,5 @@ # -buster is required to have apt available -FROM eclipse-temurin:24.0.2_12-jre-alpine +FROM eclipse-temurin:25-jre-alpine@sha256:f10d6259d0798c1e12179b6bf3b63cea0d6843f7b09c9f9c9c422c50e44379ec # Optional JVM arguments, such as memory settings ARG JVM_ARGS="" diff --git a/resources/Dockerfile b/resources/Dockerfile index 077b219a41..950687497d 100644 --- a/resources/Dockerfile +++ b/resources/Dockerfile @@ -19,7 +19,7 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -FROM eclipse-temurin:25-jre-alpine +FROM eclipse-temurin:25-jre-alpine@sha256:f10d6259d0798c1e12179b6bf3b63cea0d6843f7b09c9f9c9c422c50e44379ec RUN apk update && apk upgrade --no-cache ARG JAR From 966f24c096e232d2b186e23f89629847ffdd9f89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:04:25 +0200 Subject: [PATCH 056/259] chore(deps): bump mikefarah/yq (#2794) Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.52.4 to 4.53.2. - [Release notes](https://github.com/mikefarah/yq/releases) - [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt) - [Commits](https://github.com/mikefarah/yq/compare/5a7e72a743649b1b3a47d1a1d8214f3453173c51...751d8ad57b84f1794661bc70c0afb92a22ad7b3c) --- updated-dependencies: - dependency-name: mikefarah/yq dependency-version: 4.53.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/update-version-and-charts/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/update-version-and-charts/action.yml b/.github/actions/update-version-and-charts/action.yml index 1c49933757..b17e580357 100644 --- a/.github/actions/update-version-and-charts/action.yml +++ b/.github/actions/update-version-and-charts/action.yml @@ -45,7 +45,7 @@ runs: fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" - name: Bump version in /charts - uses: mikefarah/yq@5a7e72a743649b1b3a47d1a1d8214f3453173c51 # v4.52.4 + uses: mikefarah/yq@751d8ad57b84f1794661bc70c0afb92a22ad7b3c # v4.53.2 env: RESOLVED_VERSION: ${{ steps.resolver.outputs.version }} with: From e4909db0e3abc1fa0659c4f7ec72cd6235c3fe5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:05:04 +0200 Subject: [PATCH 057/259] chore(deps): bump azure/setup-kubectl in /.github/actions/setup-kubectl (#2793) Bumps [azure/setup-kubectl](https://github.com/azure/setup-kubectl) from 4.0.1 to 5.1.0. - [Release notes](https://github.com/azure/setup-kubectl/releases) - [Changelog](https://github.com/Azure/setup-kubectl/blob/main/CHANGELOG.md) - [Commits](https://github.com/azure/setup-kubectl/compare/776406bce94f63e41d621b960d78ee25c8b76ede...829323503d1be3d00ca8346e5391ca0b07a9ab0d) --- updated-dependencies: - dependency-name: azure/setup-kubectl dependency-version: 5.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-kubectl/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-kubectl/action.yml b/.github/actions/setup-kubectl/action.yml index 0fc88c9952..3163749f05 100644 --- a/.github/actions/setup-kubectl/action.yml +++ b/.github/actions/setup-kubectl/action.yml @@ -24,6 +24,6 @@ description: "Setup Kubectl" runs: using: "composite" steps: - - uses: azure/setup-kubectl@776406bce94f63e41d621b960d78ee25c8b76ede # v4.0.1 + - uses: azure/setup-kubectl@829323503d1be3d00ca8346e5391ca0b07a9ab0d # v5.1.0 with: version: v1.31.1 From ed6c7f8c394ee303baf22649d41d97d9b8228bd8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:05:40 +0200 Subject: [PATCH 058/259] chore(deps): bump gradle/actions in /.github/actions/setup-java (#2792) Bumps [gradle/actions](https://github.com/gradle/actions) from 5.0.2 to 6.1.0. - [Release notes](https://github.com/gradle/actions/releases) - [Commits](https://github.com/gradle/actions/compare/0723195856401067f7a2779048b490ace7a47d7c...50e97c2cd7a37755bbfafc9c5b7cafaece252f6e) --- updated-dependencies: - dependency-name: gradle/actions dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-java/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index ccd198951b..637050c67e 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -31,4 +31,4 @@ runs: java-version: '21' distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2 + uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0 From b3ab9fd08d79356f5fce89dd3ddf83d3a9cc421d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:06:13 +0200 Subject: [PATCH 059/259] chore(deps): bump docker/build-push-action (#2790) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.0.0 to 7.1.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/d08e5c354a6adb9ed34480a06d141179aa583294...bcafcacb16a39f128d818304e6c9c0c18556b85f) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-version: 7.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index f5f9860631..9a42651117 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -105,7 +105,7 @@ runs: # Build and push the image ############################### - name: Build and push - uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 env: ROOT_DIR: ${{ inputs.rootDir }} IMAGE_NAME: ${{ inputs.imagename }} From cd465cfabc4cd8d2e0262cb212c63f7e8b3aa831 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:06:32 +0200 Subject: [PATCH 060/259] chore(deps): bump docker/login-action (#2789) Bumps [docker/login-action](https://github.com/docker/login-action) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/b45d80f862d83dbcd57f89517bcf500b2ab88fb2...4907a6ddec9925e35a0a9e82d7399ccc52663121) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 9a42651117..7c86e823a8 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -66,7 +66,7 @@ runs: # Login to DockerHub ##################### - name: DockerHub login - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 with: username: ${{ inputs.docker_user }} password: ${{ inputs.docker_token }} From e3558190e632eef0bc625ece6f7655f1cc7cc227 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:06:58 +0200 Subject: [PATCH 061/259] chore(deps): bump actions/checkout from 4.2.2 to 6.0.2 (#2788) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.2 to 6.0.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.2.2...de0fac2e4500dabe0009e67214ff5f5447ce83dd) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/workflow-security-lint.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 52b72e895b..93e1ae65ef 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -51,7 +51,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -76,7 +76,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false From c2602e8221135a8899caa9f55547a592e87ab9d7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:07:32 +0200 Subject: [PATCH 062/259] chore(deps): bump actions/cache from 5.0.4 to 5.0.5 (#2787) Bumps [actions/cache](https://github.com/actions/cache) from 5.0.4 to 5.0.5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/668228422ae6a00e4ad889ee87cd7109ec5666a7...27d5ce7f107fe9357f9df03efb73ab90386fccae) --- updated-dependencies: - dependency-name: actions/cache dependency-version: 5.0.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deployment-test.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 1b799b5859..aa38d8af2e 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -40,7 +40,7 @@ jobs: with: egress-policy: audit - name: Cache ContainerD Image Layers - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs key: ${{ runner.os }}-io.containerd.snapshotter.v1.overlayfs diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 8eef2c983c..756206960c 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -40,7 +40,7 @@ jobs: with: egress-policy: audit - name: Cache ContainerD Image Layers - uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs key: ${{ runner.os }}-io.containerd.snapshotter.v1.overlayfs From 42da577a189f1052747be240a6ea2b567a5c566d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:07:49 +0200 Subject: [PATCH 063/259] chore(deps): bump actions/github-script from 8.0.0 to 9.0.0 (#2780) Bumps [actions/github-script](https://github.com/actions/github-script) from 8.0.0 to 9.0.0. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/ed597411d8f924073f98dfc5c65a23a2325f34cd...3a2844b7e9c422d3c10d287c895573f7108da1b3) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: 9.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index 385130428e..81eac0bd68 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -38,7 +38,7 @@ jobs: with: egress-policy: audit - name: Copy labels from linked issue to PR - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: script: | const CLOSING_KEYWORDS = /\b(?:closes?|fixes?|resolves?)\s+#(\d+)\b/gi; diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 61a75d542d..f6af3a05c8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -259,7 +259,7 @@ jobs: with: persist-credentials: false - - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: RELEASE_VERSION: ${{ needs.validation.outputs.RELEASE_VERSION }} with: From a08e9a30897688da388986d24d1e79faddf099d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:07:57 +0200 Subject: [PATCH 064/259] chore(deps): bump boostsecurityio/poutine-action from 0.15.2 to 1.1.4 (#2785) Bumps [boostsecurityio/poutine-action](https://github.com/boostsecurityio/poutine-action) from 0.15.2 to 1.1.4. - [Release notes](https://github.com/boostsecurityio/poutine-action/releases) - [Commits](https://github.com/boostsecurityio/poutine-action/compare/84c0a0d32e8d57ae12651222be1eb15351429228...e240ebd3eff8b2db5a8e5f6b28f58739d7db2247) --- updated-dependencies: - dependency-name: boostsecurityio/poutine-action dependency-version: 1.1.4 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/workflow-security-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 93e1ae65ef..2ae6d2238d 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -81,7 +81,7 @@ jobs: persist-credentials: false - name: Run poutine - uses: boostsecurityio/poutine-action@84c0a0d32e8d57ae12651222be1eb15351429228 # v0.15.2 + uses: boostsecurityio/poutine-action@e240ebd3eff8b2db5a8e5f6b28f58739d7db2247 # v1.1.4 - name: Fix and patch poutine SARIF if: always() From 21cddf8ff6d504e297f786ca26de10e9179c44b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:08:23 +0200 Subject: [PATCH 065/259] chore(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 (#2783) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-openapi-ui.yml | 4 ++-- .github/workflows/verify.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish-openapi-ui.yml b/.github/workflows/publish-openapi-ui.yml index 2763174efc..1c48ead0ef 100644 --- a/.github/workflows/publish-openapi-ui.yml +++ b/.github/workflows/publish-openapi-ui.yml @@ -60,7 +60,7 @@ jobs: - name: Generate openapi spec run: ./gradlew resolve - - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: openapi-spec path: resources/openapi/yaml @@ -126,7 +126,7 @@ jobs: spec-file: ${{ matrix.apiGroup.name }}.yaml GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: ${{ matrix.apiGroup.name }}-api path: dist diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 78fc7220c4..4ba2ddf9d9 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -102,7 +102,7 @@ jobs: # uploads the jacoco report as artifact - name: Upload JaCoCo Coverage Report - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: JaCoCo coverage-report path: build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml @@ -134,7 +134,7 @@ jobs: # uploads the coverage-report.md artifact - name: Upload Code Coverage Markdown Report - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: code-coverage-report-markdown path: "*/coverage-results.md" @@ -223,7 +223,7 @@ jobs: echo "ARTIFACT_NAME=${SANITIZED_NAME}" >> $GITHUB_ENV - name: Upload test artifacts - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: allure-results-${{ env.ARTIFACT_NAME }} path: edc-tests/e2e/${{ matrix.dir }}/build/allure-results From 9473ddd2aeac61a719baeb4230545dbcd9a8e18f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:08:27 +0200 Subject: [PATCH 066/259] chore(deps): bump zizmorcore/zizmor-action from 0.5.2 to 0.5.3 (#2786) Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.5.2 to 0.5.3. - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/71321a20a9ded102f6e9ce5718a2fcec2c4f70d8...b1d7e1fb5de872772f31590499237e7cce841e8e) --- updated-dependencies: - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/workflow-security-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 2ae6d2238d..274b62f13f 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -56,7 +56,7 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 + uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 with: version: "1.23.1" advanced-security: "true" From 5651c175b23cb9fe95f951b27420dc6146a15fb8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:09:23 +0200 Subject: [PATCH 067/259] chore(deps): bump github/codeql-action from 4.34.1 to 4.35.2 (#2784) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.34.1 to 4.35.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/38697555549f1db7851b81482ff19f1fa5c4fedc...95e58e9a2cdfd71adc6e0353d5c52f41a045d225) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 4 ++-- .github/workflows/kics.yml | 2 +- .github/workflows/trivy.yml | 4 ++-- .github/workflows/workflow-security-lint.yaml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index e5cb0492ad..fed368b2a9 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 + uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 + uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 6519b218f1..668f4cb982 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 + uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 813a962a0c..d6b9e124e0 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -71,7 +71,7 @@ jobs: output: "trivy-results-config.sarif" severity: "CRITICAL,HIGH" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 + uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 if: always() with: sarif_file: "trivy-results-config.sarif" @@ -122,6 +122,6 @@ jobs: timeout: "10m0s" - name: Upload Trivy scan results to GitHub Security tab if: success() && steps.imageCheck.outcome != 'failure' - uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 + uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 with: sarif_file: "trivy-results-${{ matrix.image }}.sarif" diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 274b62f13f..ab56a322b0 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -88,7 +88,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 + uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 if: always() with: sarif_file: results-fixed.sarif From 0ca5cd37e41887b12b60d06e541d8d714e24da0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:09:45 +0200 Subject: [PATCH 068/259] chore(deps): bump aquasecurity/trivy-action from 0.35.0 to 0.36.0 (#2782) Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.35.0 to 0.36.0. - [Release notes](https://github.com/aquasecurity/trivy-action/releases) - [Commits](https://github.com/aquasecurity/trivy-action/compare/57a97c7e7821a5776cebc9bb87c984fa69cba8f1...ed142fd0673e97e23eac54620cfb913e5ce36c25) --- updated-dependencies: - dependency-name: aquasecurity/trivy-action dependency-version: 0.36.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/trivy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index d6b9e124e0..a1bb401569 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -61,7 +61,7 @@ jobs: with: persist-credentials: false - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 with: scan-type: "config" # ignore-unfixed: true @@ -112,7 +112,7 @@ jobs: ## the next two steps will only execute if the image exists check was successful - name: Run Trivy vulnerability scanner if: success() && steps.imageCheck.outcome != 'failure' - uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # 0.35.0 + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 with: image-ref: "tractusx/${{ matrix.image }}:sha-${{ needs.git-sha7.outputs.value }}" format: "sarif" From 2071482efbb2fb31cfd26858c47106f3d2709d7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:10:29 +0200 Subject: [PATCH 069/259] chore(deps): bump step-security/harden-runner from 2.16.0 to 2.19.0 (#2781) Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.16.0 to 2.19.0. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594...8d3c67de8e2fe68ef647c8db1e6a09f647780f40) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.19.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 2 +- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/deployment-test.yaml | 6 ++--- .github/workflows/draft-release.yaml | 2 +- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 2 +- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 6 ++--- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/stale-bot.yml | 2 +- .github/workflows/triage-issue.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/trivy.yml | 6 ++--- .github/workflows/upgradeability-test.yaml | 4 ++-- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 4 ++-- 19 files changed, 41 insertions(+), 41 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index fed368b2a9..59218dc185 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -55,7 +55,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index 81eac0bd68..87d549bae5 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Copy labels from linked issue to PR diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index aa38d8af2e..efa1559876 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: test-prepare steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -84,7 +84,7 @@ jobs: "v1.33.7" ] steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 7b314dbf46..e5fff6e5ad 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -44,7 +44,7 @@ jobs: is_official_release: ${{ steps.validation.outputs.is_official_release }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index 90679925c9..8213edb385 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 1284d73be2..5826f2917e 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit ############## diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 668f4cb982..f0cd532b4c 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index 295cec08e4..99e34c76f0 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -38,7 +38,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index 301537b99f..17f5fa0e82 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -77,7 +77,7 @@ jobs: HAS_SWAGGER: ${{ steps.secret-presence.outputs.HAS_SWAGGER }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Check whether secrets exist @@ -100,7 +100,7 @@ jobs: DATED: ${{ steps.get-version.outputs.DATED }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -170,7 +170,7 @@ jobs: if: ${{ needs.determine-version.outputs.DATED == 'true' }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f6af3a05c8..68709314f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,7 +56,7 @@ jobs: update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -148,7 +148,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -188,7 +188,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -251,7 +251,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit @@ -294,7 +294,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Checkout main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index a66acbdb00..4b6793e772 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -42,7 +42,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Checkout Repository diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 02ddb1b9df..330c243729 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -39,7 +39,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 diff --git a/.github/workflows/triage-issue.yml b/.github/workflows/triage-issue.yml index 7f818177b1..a090002360 100644 --- a/.github/workflows/triage-issue.yml +++ b/.github/workflows/triage-issue.yml @@ -36,7 +36,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - run: gh issue edit "$NUMBER" --add-label "$LABELS" diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index d51b06c389..0cfad95d07 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -71,7 +71,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 1b30deb9da..28b4025e35 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index a1bb401569..785c46fb02 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -38,7 +38,7 @@ jobs: value: ${{ steps.git-sha7.outputs.SHA7 }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Resolve git 7-chars sha @@ -54,7 +54,7 @@ jobs: security-events: write steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -92,7 +92,7 @@ jobs: - edc-dataplane-hashicorp-vault steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 756206960c..8c558c21bf 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: [ test-prepare ] steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 4ba2ddf9d9..2e4f96ca2a 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -57,7 +57,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -73,7 +73,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -88,7 +88,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -144,7 +144,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -162,7 +162,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -180,7 +180,7 @@ jobs: matrix: ${{ steps.outputStep.outputs.matrix }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -200,7 +200,7 @@ jobs: matrix: ${{ fromJson(needs.prepare-end-to-end-tests.outputs.matrix) }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -232,7 +232,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -247,7 +247,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -267,7 +267,7 @@ jobs: if: ${{ github.ref_name == 'main' || startsWith(github.ref_name, 'release/') }} steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index ab56a322b0..00cfdfeed7 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -46,7 +46,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit @@ -71,7 +71,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@fa2e9d605c4eeb9fcad4c99c224cee0c6c7f3594 # v2.16.0 + uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 with: egress-policy: audit From 10e9cd4249d6d152f0e6dd6afd9bb3989633e02e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:11:20 +0200 Subject: [PATCH 070/259] chore(deps): bump eclipse-temurin in /resources (#2779) Bumps eclipse-temurin from `f10d625` to `5fcc275`. --- updated-dependencies: - dependency-name: eclipse-temurin dependency-version: 25-jre-alpine dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- resources/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/Dockerfile b/resources/Dockerfile index 950687497d..229885ada1 100644 --- a/resources/Dockerfile +++ b/resources/Dockerfile @@ -19,7 +19,7 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -FROM eclipse-temurin:25-jre-alpine@sha256:f10d6259d0798c1e12179b6bf3b63cea0d6843f7b09c9f9c9c422c50e44379ec +FROM eclipse-temurin:25-jre-alpine@sha256:5fcc27581b238efbfda93da3a103f59e0b5691fe522a7ac03fe8057b0819c888 RUN apk update && apk upgrade --no-cache ARG JAR From 032516a1bb4bbb625408dfa07aaed43d852221db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 09:23:43 +0200 Subject: [PATCH 071/259] chore(deps): bump azure/setup-helm in /.github/actions/setup-helm (#2791) Bumps [azure/setup-helm](https://github.com/azure/setup-helm) from 4.3.1 to 5.0.0. - [Release notes](https://github.com/azure/setup-helm/releases) - [Changelog](https://github.com/Azure/setup-helm/blob/main/CHANGELOG.md) - [Commits](https://github.com/azure/setup-helm/compare/1a275c3b69536ee54be43f2070a358922e12c8d4...dda3372f752e03dde6b3237bc9431cdc2f7a02a2) --- updated-dependencies: - dependency-name: azure/setup-helm dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-helm/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-helm/action.yml b/.github/actions/setup-helm/action.yml index 1e3b24f75e..33ef49ded8 100644 --- a/.github/actions/setup-helm/action.yml +++ b/.github/actions/setup-helm/action.yml @@ -24,6 +24,6 @@ description: "Setup Helm" runs: using: "composite" steps: - - uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1 + - uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5.0.0 with: version: v3.16.1 From 8e8daf017b4345c0117309e954558d21b7e8ee0e Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Mon, 4 May 2026 10:01:14 +0200 Subject: [PATCH 072/259] fix: add write permission for allure (#2796) --- .github/workflows/run-all-tests.yml | 2 +- .github/workflows/verify.yaml | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 2e7e98e623..8e5ab4d98d 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -48,7 +48,7 @@ permissions: {} jobs: verify: permissions: - contents: read + contents: write uses: ./.github/workflows/verify.yaml deployment-test: diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 2e4f96ca2a..2dc879db13 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -27,13 +27,13 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: -permissions: - contents: read +permissions: {} jobs: - verify-helm-docs: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 @@ -55,6 +55,8 @@ jobs: verify-formatting: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 @@ -70,6 +72,8 @@ jobs: ./gradlew checkstyleMain checkstyleTest verify-javadoc: + permissions: + contents: read runs-on: ubuntu-latest steps: - name: Harden Runner @@ -85,6 +89,8 @@ jobs: run: ./gradlew javadoc unit-tests: + permissions: + contents: read runs-on: ubuntu-latest steps: - name: Harden Runner @@ -142,6 +148,8 @@ jobs: integration-tests: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 @@ -160,6 +168,8 @@ jobs: api-tests: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 @@ -178,6 +188,8 @@ jobs: runs-on: ubuntu-latest outputs: matrix: ${{ steps.outputStep.outputs.matrix }} + permissions: + contents: read steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 @@ -198,6 +210,8 @@ jobs: strategy: fail-fast: false matrix: ${{ fromJson(needs.prepare-end-to-end-tests.outputs.matrix) }} + permissions: + contents: read steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 @@ -230,6 +244,8 @@ jobs: postgres-tests: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 @@ -245,6 +261,8 @@ jobs: compatibility-tests: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 @@ -265,6 +283,8 @@ jobs: runs-on: ubuntu-latest needs: end-to-end-tests if: ${{ github.ref_name == 'main' || startsWith(github.ref_name, 'release/') }} + permissions: + contents: write steps: - name: Harden Runner uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 From 02fab2e98bb9ceab257db8c1679279679b30953c Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Mon, 4 May 2026 11:11:12 +0200 Subject: [PATCH 073/259] fix: remove concurrency for publish-new-snapshot (#2797) --- .github/workflows/publish-new-snapshot.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index 17f5fa0e82..e286156623 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -60,11 +60,6 @@ on: # periodic build triggers are defined in run-all-tests.yml, which triggers this workflow -concurrency: - # cancel older running jobs on the same branch - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - permissions: contents: read From 52fd8551688680d5514e3e3d99789c2974a4f9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Barbosa?= <107394742+MDSBarbosa@users.noreply.github.com> Date: Wed, 6 May 2026 16:52:45 +0100 Subject: [PATCH 074/259] feat: remove validation from UsagePurposeConstraintFunction (#2798) * feat: remove validation from UsagePurposeConstraintFunction * feat: ensure only isAnyOf operator is valid for UsagePurposeConstraint --- .../usage/UsagePurposeConstraintFunction.java | 44 ++++--------------- .../UsagePurposeConstraintFunctionTest.java | 35 +++++---------- 2 files changed, 21 insertions(+), 58 deletions(-) diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/usage/UsagePurposeConstraintFunction.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/usage/UsagePurposeConstraintFunction.java index 892ed167c6..c648c14bd4 100644 --- a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/usage/UsagePurposeConstraintFunction.java +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/usage/UsagePurposeConstraintFunction.java @@ -22,7 +22,8 @@ import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; import org.eclipse.edc.policy.model.Operator; import org.eclipse.edc.policy.model.Permission; -import org.eclipse.tractusx.edc.policy.cx.common.ValueValidatingConstraintFunction; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.tractusx.edc.policy.cx.common.BaseConstraintFunction; import java.util.Set; @@ -30,44 +31,17 @@ * This is a placeholder constraint function for UsagePurpose. It always returns true but allows * the validation of policies to be strictly enforced. */ -public class UsagePurposeConstraintFunction extends ValueValidatingConstraintFunction { +public class UsagePurposeConstraintFunction extends BaseConstraintFunction { public static final String USAGE_PURPOSE = "UsagePurpose"; public UsagePurposeConstraintFunction() { super( - Set.of(Operator.IS_ANY_OF), - Set.of( - "cx.core.legalRequirementForThirdparty:1", - "cx.core.industrycore:1", - "cx.core.qualityNotifications:1", - "cx.core.digitalTwinRegistry:1", - "cx.pcf.base:1", - "cx.quality.base:1", - "cx.dcm.base:1", - "cx.puris.base:1", - "cx.circular.dpp:1", - "cx.circular.smc:1", - "cx.circular.marketplace:1", - "cx.circular.materialaccounting:1", - "cx.bpdm.gate.upload:1", - "cx.bpdm.gate.download:1", - "cx.bpdm.pool:1", - "cx.bpdm.vas.countryrisk:1", - "cx.bpdm.vas.dataquality.upload:1", - "cx.bpdm.vas.dataquality.download:1", - "cx.bpdm.vas.bdv.upload:1", - "cx.bpdm.vas.bdv.download:1", - "cx.bpdm.vas.fpd.upload:1", - "cx.bpdm.vas.fpd.download:1", - "cx.bpdm.vas.swd.upload:1", - "cx.bpdm.vas.swd.download:1", - "cx.bpdm.vas.nps.upload:1", - "cx.bpdm.vas.nps.download:1", - "cx.ccm.base:1", - "cx.bpdm.poolAll:1", - "cx.logistics.base:1" - ), - true + Set.of(Operator.IS_ANY_OF) ); } + + @Override + protected Result validateRightOperand(Object rightValue) { + return Result.success(); + } } diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/usage/UsagePurposeConstraintFunctionTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/usage/UsagePurposeConstraintFunctionTest.java index 51e74035d4..a99ba64812 100644 --- a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/usage/UsagePurposeConstraintFunctionTest.java +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/usage/UsagePurposeConstraintFunctionTest.java @@ -19,18 +19,15 @@ package org.eclipse.tractusx.edc.policy.cx.usage; -import jakarta.json.Json; import org.eclipse.edc.participant.spi.ParticipantAgent; import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; import org.eclipse.edc.policy.model.Operator; import org.eclipse.tractusx.edc.policy.cx.TestParticipantAgentPolicyContext; import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.Map; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.mockito.Mockito.mock; class UsagePurposeConstraintFunctionTest { @@ -39,29 +36,21 @@ class UsagePurposeConstraintFunctionTest { private final UsagePurposeConstraintFunction function = new UsagePurposeConstraintFunction<>(); private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent); - @Test - void evaluate() { - assertThat(function.evaluate(Operator.IS_ANY_OF, List.of("cx.core.legalRequirementForThirdparty:1", "cx.core.industrycore:1"), null, context)).isTrue(); - } - - @Test - void validate_whenOperatorAndRightOperandAreValid_thenSuccess() { - var legalRequirementForThirdparty = Json.createValue("cx.core.legalRequirementForThirdparty:1"); - var industrycore = Json.createValue("cx.core.industrycore:1"); - var rightValue = List.of(Map.of("@value", legalRequirementForThirdparty), Map.of("@value", industrycore)); - var result = function.validate(Operator.IS_ANY_OF, rightValue, null); - assertThat(result).isSucceeded(); + @ParameterizedTest + @EnumSource(value = Operator.class, names = "IS_ANY_OF", mode = EnumSource.Mode.EXCLUDE) + void validate_shouldReturnFalse_forAllOperatorsExceptIsAnyOf(Operator operator) { + var result = function.validate(operator, "someValue", null); + assertThat(result.succeeded()).isFalse(); } @Test - void validate_whenInvalidOperator_thenFailure() { - var result = function.validate(Operator.EQ, List.of("cx.core.legalRequirementForThirdparty:1", "cx.core.industrycore:1"), null); - assertThat(result).isFailed().detail().contains("Invalid operator"); + void validate_shouldReturnTrue_forIsAnyOfOperator() { + var result = function.validate(Operator.IS_ANY_OF, "someValue", null); + assertThat(result.succeeded()).isTrue(); } @Test - void validate_whenInvalidValue_thenFailure() { - var result = function.validate(Operator.IS_ANY_OF, List.of("BPNL00000000001A"), null); - assertThat(result).isFailed().detail().contains("Invalid right-operand: "); + void evaluate_shouldReturnTrue_withAnyRightValue() { + assertThat(function.evaluate(Operator.IS_ANY_OF, "anyValue", null, context)).isTrue(); } } From 711b58e166a1484f21e757a9db60fc629aea5967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arno=20Wei=C3=9F?= <86715435+arnoweiss@users.noreply.github.com> Date: Thu, 7 May 2026 15:25:55 +0200 Subject: [PATCH 075/259] feat: move additional headers decoration to dataplane (#2759) * feat: move additional headers provisioning to dataplane Assisted-by: claude-sonnet-4-6 * chore: prefix monitor with class name Co-authored-by: Lars Geyer-Blaumeiser * fix: unit tests * fix: readd null check --------- Co-authored-by: Lars Geyer-Blaumeiser --- .../edc-controlplane-base/build.gradle.kts | 1 - .../edc-dataplane-base/build.gradle.kts | 1 + .../defaults/InMemoryAgreementsBpnsStore.java | 6 + .../store/AgreementsBpnsStoreTestBase.java | 22 ++++ .../bpns/spi/store/AgreementsBpnsStore.java | 4 + .../bpns-evaluation-store-sql/docs/schema.sql | 3 +- .../sql/SqlAgreementsBpnsStatements.java | 4 + .../store/sql/SqlAgreementsBpnsStore.java | 21 ++++ .../build.gradle.kts | 1 + .../flow/TxDataFlowPropertiesProvider.java | 58 +++++++-- ...TxDataFlowPropertiesProviderExtension.java | 11 +- ...taFlowPropertiesProviderExtensionTest.java | 7 +- .../TxDataFlowPropertiesProviderTest.java | 91 +++++++++----- .../build.gradle.kts | 5 +- ...va => AdditionalHeadersDeprovisioner.java} | 36 +++--- .../AdditionalHeadersProvisioner.java | 58 ++++----- .../AdditionalHeadersResourceDefinition.java | 83 ------------- ...nalHeadersResourceDefinitionGenerator.java | 56 ++++----- .../ProvisionAdditionalHeadersExtension.java | 33 +++-- ...itionalHeadersProvisionedResourceTest.java | 51 -------- .../AdditionalHeadersProvisionerTest.java | 66 ++++------ ...eadersResourceDefinitionGeneratorTest.java | 113 ++++-------------- ...ditionalHeadersResourceDefinitionTest.java | 49 -------- ...ovisionAdditionalHeadersExtensionTest.java | 21 ++-- .../fixtures/IdentityHubParticipant.java | 4 + .../tests/transfer/TransferEndToEndTest.java | 6 +- .../tests/transfer/ProviderPushBaseTest.java | 2 +- .../tck/dsp/EdcCompatibilityPostgresTest.java | 32 ++++- resources/java.header | 4 +- .../tractusx/edc/edr/spi/CoreConstants.java | 3 + 30 files changed, 353 insertions(+), 499 deletions(-) rename edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/{AdditionalHeadersProvisionedResource.java => AdditionalHeadersDeprovisioner.java} (54%) delete mode 100644 edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinition.java delete mode 100644 edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResourceTest.java delete mode 100644 edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionTest.java diff --git a/edc-controlplane/edc-controlplane-base/build.gradle.kts b/edc-controlplane/edc-controlplane-base/build.gradle.kts index a2eb22205c..3748567758 100644 --- a/edc-controlplane/edc-controlplane-base/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-base/build.gradle.kts @@ -54,7 +54,6 @@ dependencies { implementation(project(":edc-extensions:dcp:verifiable-presentation-cache")) implementation(project(":edc-extensions:edr:edr-api-v2")) implementation(project(":edc-extensions:edr:edr-callback")) - implementation(project(":edc-extensions:provision-additional-headers")) implementation(project(":edc-extensions:tokenrefresh-handler")) implementation(project(":edc-extensions:validators:empty-asset-selector")) implementation(project(":edc-extensions:connector-discovery:connector-discovery-api")) diff --git a/edc-dataplane/edc-dataplane-base/build.gradle.kts b/edc-dataplane/edc-dataplane-base/build.gradle.kts index 8c105884cc..fa69a9e5a1 100644 --- a/edc-dataplane/edc-dataplane-base/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-base/build.gradle.kts @@ -41,6 +41,7 @@ dependencies { implementation(project(":edc-extensions:tokenrefresh-handler")) implementation(project(":edc-extensions:event-subscriber")) implementation(project(":edc-extensions:non-finite-provider-push:non-finite-provider-push-core")) + implementation(project(":edc-extensions:provision-additional-headers")) implementation(project(":edc-extensions:dataplane:dataflow:dataflow-api")) implementation(project(":edc-extensions:dataplane:dataflow:dataflow-service")) diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-core/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/defaults/InMemoryAgreementsBpnsStore.java b/edc-extensions/agreements-bpns/bpns-evaluation-core/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/defaults/InMemoryAgreementsBpnsStore.java index 3b265e1dcc..5aeaab40bc 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-core/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/defaults/InMemoryAgreementsBpnsStore.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-core/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/defaults/InMemoryAgreementsBpnsStore.java @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2025 Cofinity-X GmbH + * Copyright (c) 2026 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -42,4 +43,9 @@ public StoreResult save(AgreementsBpnsEntry agreementsBpnsEntry) { cache.put(agreementsBpnsEntry.getAgreementId(), agreementsBpnsEntry); return StoreResult.success(); } + + @Override + public AgreementsBpnsEntry findByAgreementId(String agreementId) { + return cache.get(agreementId); + } } diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-core/src/testFixtures/java/org/eclipse/tractusx/edc/agreements/bpns/store/AgreementsBpnsStoreTestBase.java b/edc-extensions/agreements-bpns/bpns-evaluation-core/src/testFixtures/java/org/eclipse/tractusx/edc/agreements/bpns/store/AgreementsBpnsStoreTestBase.java index be1c60efdf..5acf45a627 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-core/src/testFixtures/java/org/eclipse/tractusx/edc/agreements/bpns/store/AgreementsBpnsStoreTestBase.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-core/src/testFixtures/java/org/eclipse/tractusx/edc/agreements/bpns/store/AgreementsBpnsStoreTestBase.java @@ -23,6 +23,7 @@ import org.eclipse.tractusx.edc.agreements.bpns.spi.types.AgreementsBpnsEntry; import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.eclipse.tractusx.edc.agreements.bpns.spi.store.AgreementsBpnsStore.ALREADY_EXISTS_TEMPLATE; @@ -39,6 +40,27 @@ void save_whenExists() { .detail().isEqualTo(ALREADY_EXISTS_TEMPLATE.formatted(agreementId)); } + @Test + void findByAgreementId_whenExists() { + var agreementId = "test-agreement-id"; + var entry = createAgreementsBpnsEntry(agreementId, "providerBpn", "consumerBpn"); + getStore().save(entry); + + var found = getStore().findByAgreementId(agreementId); + + assertThat(found).isNotNull(); + assertThat(found.getAgreementId()).isEqualTo(agreementId); + assertThat(found.getProviderBpn()).isEqualTo("providerBpn"); + assertThat(found.getConsumerBpn()).isEqualTo("consumerBpn"); + } + + @Test + void findByAgreementId_whenNotExists() { + var found = getStore().findByAgreementId("unknown-agreement-id"); + + assertThat(found).isNull(); + } + private AgreementsBpnsEntry createAgreementsBpnsEntry(String agreementId, String providerBpn, String consumerBpn) { return AgreementsBpnsEntry.Builder.newInstance() .withAgreementId(agreementId) diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-spi/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/spi/store/AgreementsBpnsStore.java b/edc-extensions/agreements-bpns/bpns-evaluation-spi/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/spi/store/AgreementsBpnsStore.java index 0b93691965..537d075772 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-spi/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/spi/store/AgreementsBpnsStore.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-spi/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/spi/store/AgreementsBpnsStore.java @@ -22,10 +22,14 @@ import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; import org.eclipse.edc.spi.result.StoreResult; import org.eclipse.tractusx.edc.agreements.bpns.spi.types.AgreementsBpnsEntry; +import org.jetbrains.annotations.Nullable; @ExtensionPoint public interface AgreementsBpnsStore { String ALREADY_EXISTS_TEMPLATE = "Contract Agreement %s already exists."; StoreResult save(AgreementsBpnsEntry agreementsBpnsEntry); + + @Nullable + AgreementsBpnsEntry findByAgreementId(String agreementId); } diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/docs/schema.sql b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/docs/schema.sql index 1882b44df4..3309b3a14b 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/docs/schema.sql +++ b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/docs/schema.sql @@ -27,7 +27,8 @@ CREATE TABLE IF NOT EXISTS edc_contract_agreement INSERT INTO edc_contract_agreement (id, provider_agent_id, consumer_agent_id, signing_date, start_date, end_date, asset_id, policy_id, serialized_policy) VALUES - ('test-agreement-id', 'default-provider-agent', 'default-consumer-agent', 0, 0, 0, 'default-asset', 'default-policy-id', '{}'); + ('test-agreement-id', 'default-provider-agent', 'default-consumer-agent', 0, 0, 0, 'default-asset', 'default-policy-id', '{}') +ON CONFLICT DO NOTHING; CREATE TABLE IF NOT EXISTS edc_contract_agreement_bpns ( diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/sql/SqlAgreementsBpnsStatements.java b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/sql/SqlAgreementsBpnsStatements.java index 8e39d2513b..dd4ca7ca42 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/sql/SqlAgreementsBpnsStatements.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/sql/SqlAgreementsBpnsStatements.java @@ -43,4 +43,8 @@ default String getTable() { } String insertWithOnConflict(); + + default String findByAgreementIdTemplate() { + return "SELECT * FROM %s WHERE %s = ?".formatted(getTable(), getAgreementIdColumn()); + } } diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/sql/SqlAgreementsBpnsStore.java b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/sql/SqlAgreementsBpnsStore.java index 0bd6c3555f..ca805679e6 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/sql/SqlAgreementsBpnsStore.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/sql/SqlAgreementsBpnsStore.java @@ -29,6 +29,7 @@ import org.eclipse.tractusx.edc.agreements.bpns.spi.store.AgreementsBpnsStore; import org.eclipse.tractusx.edc.agreements.bpns.spi.types.AgreementsBpnsEntry; +import java.sql.ResultSet; import java.sql.SQLException; import java.util.Objects; @@ -66,4 +67,24 @@ public StoreResult save(AgreementsBpnsEntry agreementsBpnsEntry) { } }); } + + @Override + public AgreementsBpnsEntry findByAgreementId(String agreementId) { + return transactionContext.execute(() -> { + try (var connection = getConnection()) { + return queryExecutor.single(connection, false, this::mapRow, + statements.findByAgreementIdTemplate(), agreementId); + } catch (SQLException e) { + throw new EdcPersistenceException(e); + } + }); + } + + private AgreementsBpnsEntry mapRow(ResultSet rs) throws SQLException { + return AgreementsBpnsEntry.Builder.newInstance() + .withAgreementId(rs.getString(statements.getAgreementIdColumn())) + .withProviderBpn(rs.getString(statements.getProviderBpnColumn())) + .withConsumerBpn(rs.getString(statements.getConsumerBpnColumn())) + .build(); + } } diff --git a/edc-extensions/data-flow-properties-provider/build.gradle.kts b/edc-extensions/data-flow-properties-provider/build.gradle.kts index 1bb930aa9f..63ec8a74bc 100644 --- a/edc-extensions/data-flow-properties-provider/build.gradle.kts +++ b/edc-extensions/data-flow-properties-provider/build.gradle.kts @@ -26,6 +26,7 @@ dependencies { implementation(libs.edc.spi.transfer) implementation(project(":spi:core-spi")) implementation(project(":spi:bdrs-client-spi")) + implementation(project(":edc-extensions:agreements-bpns:bpns-evaluation-spi")) testImplementation(libs.edc.junit) } diff --git a/edc-extensions/data-flow-properties-provider/src/main/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProvider.java b/edc-extensions/data-flow-properties-provider/src/main/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProvider.java index 1a107c460f..46a76bab38 100644 --- a/edc-extensions/data-flow-properties-provider/src/main/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProvider.java +++ b/edc-extensions/data-flow-properties-provider/src/main/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProvider.java @@ -1,6 +1,7 @@ /******************************************************************************** * Copyright (c) 2025 Cofinity-X GmbH * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -17,48 +18,83 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.flow; import org.eclipse.edc.connector.controlplane.transfer.spi.flow.DataFlowPropertiesProvider; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess; import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.response.StatusResult; import org.eclipse.edc.spi.types.domain.transfer.DataFlowStartMessage; +import org.eclipse.tractusx.edc.agreements.bpns.spi.store.AgreementsBpnsStore; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import java.util.Map; import static org.eclipse.edc.spi.response.ResponseStatus.FATAL_ERROR; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AUDIENCE_PROPERTY; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PREFIX; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; import static org.eclipse.tractusx.edc.spi.identity.mapper.BdrsConstants.DID_PREFIX; + /** * Extension of {@link DataFlowPropertiesProvider} which provides additional properties in the {@link DataFlowStartMessage} - * like the DID of the counter-party BPN. The resolution is made with the {@link BdrsClient} + * such as the consumer DID (audience) and the consumer BPN. Both values are resolved locally without a BDRS call: + * the DID comes directly from {@code policy.getAssignee()} and the BPN is looked up from {@link AgreementsBpnsStore}. */ public class TxDataFlowPropertiesProvider implements DataFlowPropertiesProvider { + private final AgreementsBpnsStore agreementsBpnsStore; private final BdrsClient bdrsClient; + private final Monitor monitor; - public TxDataFlowPropertiesProvider(BdrsClient bdrsClient) { + public TxDataFlowPropertiesProvider(AgreementsBpnsStore agreementsBpnsStore, BdrsClient bdrsClient, Monitor monitor) { + this.agreementsBpnsStore = agreementsBpnsStore; this.bdrsClient = bdrsClient; + this.monitor = monitor.withPrefix(getClass().getSimpleName()); } @Override public StatusResult> propertiesFor(TransferProcess transferProcess, Policy policy) { - try { - if (policy.getAssignee().startsWith(DID_PREFIX)) { - return StatusResult.success(Map.of(AUDIENCE_PROPERTY, policy.getAssignee())); + + if (isDsp2025(policy)) { + var entry = agreementsBpnsStore.findByAgreementId(transferProcess.getContractId()); + if (entry == null) { + return StatusResult.failure(FATAL_ERROR, + "No BPN entry found for agreement %s".formatted(transferProcess.getContractId())); } - - var did = bdrsClient.resolveDid(policy.getAssignee()); + return StatusResult.success(Map.of( + AUDIENCE_PROPERTY, policy.getAssignee(), + BPN_PROPERTY, entry.getConsumerBpn() + )); + } else if (isDsp08(policy)) { + var bpn = policy.getAssignee(); + var did = bdrsClient.resolveDid(bpn); if (did == null) { - return StatusResult.failure(FATAL_ERROR, "Failed to fetch did for BPN %s".formatted(policy.getAssignee())); + return StatusResult.failure(FATAL_ERROR, "Could not resolve DID for BPN '%s'".formatted(bpn)); } - return StatusResult.success(Map.of(AUDIENCE_PROPERTY, did)); - } catch (Exception e) { - return StatusResult.failure(FATAL_ERROR, "Failed to fetch did for BPN %s: %s".formatted(policy.getAssignee(), e.getMessage())); + return StatusResult.success(Map.of( + AUDIENCE_PROPERTY, did, + BPN_PROPERTY, bpn + )); + } else { + monitor.warning("Policy's Assignee is neither a did nor a BPN and was '%s'. This is only ok for test scenarios like the DSP TCK.".formatted(policy.getAssignee())); + return StatusResult.success(Map.of( + AUDIENCE_PROPERTY, policy.getAssignee(), + BPN_PROPERTY, policy.getAssignee() + )); } + + } + + private boolean isDsp08(Policy policy) { + return policy.getAssignee().startsWith(BPN_PREFIX); + } + + private boolean isDsp2025(Policy policy) { + return policy.getAssignee().startsWith(DID_PREFIX); } } diff --git a/edc-extensions/data-flow-properties-provider/src/main/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderExtension.java b/edc-extensions/data-flow-properties-provider/src/main/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderExtension.java index 8493b1a128..48014e7401 100644 --- a/edc-extensions/data-flow-properties-provider/src/main/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderExtension.java +++ b/edc-extensions/data-flow-properties-provider/src/main/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderExtension.java @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -23,7 +24,9 @@ import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; +import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.tractusx.edc.agreements.bpns.spi.store.AgreementsBpnsStore; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import static org.eclipse.tractusx.edc.flow.TxDataFlowPropertiesProviderExtension.NAME; @@ -33,11 +36,17 @@ public class TxDataFlowPropertiesProviderExtension implements ServiceExtension { protected static final String NAME = "Tractus-X Data flow properties provider extension"; + @Inject + private AgreementsBpnsStore agreementsBpnsStore; + @Inject private BdrsClient bdrsClient; + @Inject + private Monitor monitor; + @Provider public DataFlowPropertiesProvider dataFlowPropertiesProvider() { - return new TxDataFlowPropertiesProvider(bdrsClient); + return new TxDataFlowPropertiesProvider(agreementsBpnsStore, bdrsClient, monitor); } } diff --git a/edc-extensions/data-flow-properties-provider/src/test/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderExtensionTest.java b/edc-extensions/data-flow-properties-provider/src/test/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderExtensionTest.java index 11e095ba6e..7a0d4bc292 100644 --- a/edc-extensions/data-flow-properties-provider/src/test/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderExtensionTest.java +++ b/edc-extensions/data-flow-properties-provider/src/test/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderExtensionTest.java @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -22,6 +23,8 @@ import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.tractusx.edc.agreements.bpns.spi.store.AgreementsBpnsStore; +import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -37,10 +40,12 @@ class TxDataFlowPropertiesProviderExtensionTest { @BeforeEach void setup(ServiceExtensionContext context) { context.registerService(Monitor.class, monitor); + context.registerService(AgreementsBpnsStore.class, mock()); + context.registerService(BdrsClient.class, mock()); } @Test void createMapper(TxDataFlowPropertiesProviderExtension extension) { assertThat(extension.dataFlowPropertiesProvider()).isInstanceOf(TxDataFlowPropertiesProvider.class); } -} \ No newline at end of file +} diff --git a/edc-extensions/data-flow-properties-provider/src/test/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderTest.java b/edc-extensions/data-flow-properties-provider/src/test/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderTest.java index c49df85655..ed990e6a26 100644 --- a/edc-extensions/data-flow-properties-provider/src/test/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderTest.java +++ b/edc-extensions/data-flow-properties-provider/src/test/java/org/eclipse/tractusx/edc/flow/TxDataFlowPropertiesProviderTest.java @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -16,78 +17,102 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.flow; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess; import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.agreements.bpns.spi.store.AgreementsBpnsStore; +import org.eclipse.tractusx.edc.agreements.bpns.spi.types.AgreementsBpnsEntry; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AUDIENCE_PROPERTY; -import static org.mockito.ArgumentMatchers.any; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; +import static org.mockito.Mockito.RETURNS_SELF; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class TxDataFlowPropertiesProviderTest { - private final BdrsClient bdrsClient = mock(); - private final TxDataFlowPropertiesProvider provider = new TxDataFlowPropertiesProvider(bdrsClient); + private static final String CONTRACT_ID = "test-contract-id"; + private static final String CONSUMER_DID = "did:web:consumer"; + private static final String CONSUMER_BPN = "BPNL000000000001"; + + private final AgreementsBpnsStore store = mock(); + private final BdrsClient bdrs = mock(); + private final TxDataFlowPropertiesProvider provider = new TxDataFlowPropertiesProvider(store, bdrs, mock(Monitor.class, RETURNS_SELF)); @Test - void shouldReturnProperties_whenIdIsBpn() { - var bpn = "bpn"; - var did = "did"; - when(bdrsClient.resolveDid(bpn)).thenReturn(did); + void shouldReturnProperties_whenAssigneeIsDidAndEntryFound() { + var entry = AgreementsBpnsEntry.Builder.newInstance() + .withAgreementId(CONTRACT_ID) + .withProviderBpn("BPNL000000000002") + .withConsumerBpn(CONSUMER_BPN) + .build(); + when(store.findByAgreementId(CONTRACT_ID)).thenReturn(entry); - var result = provider.propertiesFor(createTransferProcess(), createPolicy(bpn)); + var result = provider.propertiesFor(createTransferProcess(CONTRACT_ID), createPolicy(CONSUMER_DID)); assertThat(result).isSucceeded().satisfies(properties -> { - assertThat(properties).containsEntry(AUDIENCE_PROPERTY, did); + assertThat(properties).containsEntry(AUDIENCE_PROPERTY, CONSUMER_DID); + assertThat(properties).containsEntry(BPN_PROPERTY, CONSUMER_BPN); }); } - + @Test - void shouldReturnProperties_whenIdIsDid() { - var did = "did:abc"; - - var result = provider.propertiesFor(createTransferProcess(), createPolicy(did)); - + void shouldReturnFatalError_whenAssigneeIsDidAndEntryNotFound() { + when(store.findByAgreementId(CONTRACT_ID)).thenReturn(null); + + var result = provider.propertiesFor(createTransferProcess(CONTRACT_ID), createPolicy(CONSUMER_DID)); + + assertThat(result).isFailed() + .detail().isEqualTo("No BPN entry found for agreement %s".formatted(CONTRACT_ID)); + } + + @Test + void shouldReturnProperties_whenAssigneeIsBpn() { + when(bdrs.resolveDid(CONSUMER_BPN)).thenReturn(CONSUMER_DID); + + var result = provider.propertiesFor(createTransferProcess(CONTRACT_ID), createPolicy(CONSUMER_BPN)); + assertThat(result).isSucceeded().satisfies(properties -> { - assertThat(properties).containsEntry(AUDIENCE_PROPERTY, did); + assertThat(properties).containsEntry(AUDIENCE_PROPERTY, CONSUMER_DID); + assertThat(properties).containsEntry(BPN_PROPERTY, CONSUMER_BPN); }); - verify(bdrsClient, never()).resolveDid(any()); } @Test - void shouldReturnFailure_whenResolutionFails() { - var bpn = "bpn"; - when(bdrsClient.resolveDid(bpn)).thenReturn(null); + void shouldReturnFatalError_whenAssigneeIsBpnAndDidNotResolved() { + when(bdrs.resolveDid(CONSUMER_BPN)).thenReturn(null); - var result = provider.propertiesFor(createTransferProcess(), createPolicy(bpn)); + var result = provider.propertiesFor(createTransferProcess(CONTRACT_ID), createPolicy(CONSUMER_BPN)); - assertThat(result).isFailed().detail().isEqualTo("Failed to fetch did for BPN %s".formatted(bpn)); + assertThat(result).isFailed() + .detail().isEqualTo("Could not resolve DID for BPN '%s'".formatted(CONSUMER_BPN)); } @Test - void shouldReturnFailure_whenResolutionThrowsException() { - var bpn = "bpn"; - when(bdrsClient.resolveDid(bpn)).thenThrow(new RuntimeException("exception")); + void shouldReturnProperties_whenAssigneeIsNeitherDidNorBpn() { + var assignee = "some-unknown-identifier"; - var result = provider.propertiesFor(createTransferProcess(), createPolicy(bpn)); + var result = provider.propertiesFor(createTransferProcess(CONTRACT_ID), createPolicy(assignee)); - assertThat(result).isFailed().detail().contains("exception"); + assertThat(result).isSucceeded().satisfies(properties -> { + assertThat(properties).containsEntry(AUDIENCE_PROPERTY, assignee); + assertThat(properties).containsEntry(BPN_PROPERTY, assignee); + }); } - private TransferProcess createTransferProcess() { - return TransferProcess.Builder.newInstance().build(); + private TransferProcess createTransferProcess(String contractId) { + return TransferProcess.Builder.newInstance().contractId(contractId).build(); } - private Policy createPolicy(String bpn) { - return Policy.Builder.newInstance().assignee(bpn).build(); + private Policy createPolicy(String assignee) { + return Policy.Builder.newInstance().assignee(assignee).build(); } } diff --git a/edc-extensions/provision-additional-headers/build.gradle.kts b/edc-extensions/provision-additional-headers/build.gradle.kts index 8c9059eb57..f45163663d 100644 --- a/edc-extensions/provision-additional-headers/build.gradle.kts +++ b/edc-extensions/provision-additional-headers/build.gradle.kts @@ -23,11 +23,10 @@ plugins { } dependencies { - implementation(project(":spi:bdrs-client-spi")) + implementation(project(":spi:core-spi")) - implementation(libs.edc.spi.controlplane) implementation(libs.edc.spi.core) - implementation(libs.edc.spi.transfer) + implementation(libs.edc.spi.dataplane.dataplane) implementation(libs.edc.spi.dataplane.http) testImplementation(libs.edc.junit) diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResource.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersDeprovisioner.java similarity index 54% rename from edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResource.java rename to edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersDeprovisioner.java index f6d3a67516..aac4b2c769 100644 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResource.java +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersDeprovisioner.java @@ -17,28 +17,32 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.provision.additionalheaders; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ProvisionedContentResource; +import org.eclipse.edc.connector.dataplane.spi.provision.DeprovisionedResource; +import org.eclipse.edc.connector.dataplane.spi.provision.Deprovisioner; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.spi.response.StatusResult; -@JsonDeserialize(builder = AdditionalHeadersProvisionedResource.Builder.class) -class AdditionalHeadersProvisionedResource extends ProvisionedContentResource { +import java.util.concurrent.CompletableFuture; - @JsonPOJOBuilder(withPrefix = "") - public static class Builder - extends ProvisionedContentResource.Builder { +class AdditionalHeadersDeprovisioner implements Deprovisioner { - private Builder() { - super(new AdditionalHeadersProvisionedResource()); - } + private final String type; - @JsonCreator - public static Builder newInstance() { - return new Builder(); - } + AdditionalHeadersDeprovisioner(String type) { + this.type = type; + } + + @Override + public String supportedType() { + return type; + } + + @Override + public CompletableFuture> deprovision(ProvisionResource resource) { + return CompletableFuture.completedFuture(StatusResult.success(DeprovisionedResource.Builder.from(resource).build())); } } diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java index 8b8254a126..3b1303a0bd 100644 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java @@ -17,60 +17,44 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.provision.additionalheaders; -import org.eclipse.edc.connector.controlplane.transfer.spi.provision.Provisioner; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.DeprovisionedResource; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ProvisionResponse; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ProvisionedResource; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ResourceDefinition; import org.eclipse.edc.connector.dataplane.http.spi.HttpDataAddress; -import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionedResource; +import org.eclipse.edc.connector.dataplane.spi.provision.Provisioner; import org.eclipse.edc.spi.response.StatusResult; -import java.util.UUID; import java.util.concurrent.CompletableFuture; -public class AdditionalHeadersProvisioner implements Provisioner { +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; - @Override - public boolean canProvision(ResourceDefinition resourceDefinition) { - return resourceDefinition instanceof AdditionalHeadersResourceDefinition; +public class AdditionalHeadersProvisioner implements Provisioner { + + private final String type; + + public AdditionalHeadersProvisioner(String type) { + this.type = type; } @Override - public boolean canDeprovision(ProvisionedResource provisionedResource) { - return provisionedResource instanceof AdditionalHeadersProvisionedResource; + public String supportedType() { + return type; } @Override - public CompletableFuture> provision(AdditionalHeadersResourceDefinition resourceDefinition, Policy policy) { - - var address = - HttpDataAddress.Builder.newInstance() - .copyFrom(resourceDefinition.getDataAddress()) - .addAdditionalHeader("Edc-Contract-Agreement-Id", resourceDefinition.getContractId()) - .addAdditionalHeader("Edc-Bpn", resourceDefinition.getBpn()) - .build(); + public CompletableFuture> provision(ProvisionResource resource) { + var addressBuilder = resource.getDataAddress().toBuilder(); + addressBuilder.property(HttpDataAddress.ADDITIONAL_HEADER + "Edc-Contract-Agreement-Id", (String) resource.getProperty(AGREEMENT_ID_PROPERTY)); + addressBuilder.property(HttpDataAddress.ADDITIONAL_HEADER + "Edc-Bpn", (String) resource.getProperty(BPN_PROPERTY)); - var provisioned = AdditionalHeadersProvisionedResource.Builder.newInstance() - .id(UUID.randomUUID().toString()) - .resourceDefinitionId(resourceDefinition.getId()) - .transferProcessId(resourceDefinition.getTransferProcessId()) - .dataAddress(address) - .resourceName(UUID.randomUUID().toString()) - .hasToken(false) + var provisioned = ProvisionedResource.Builder.from(resource) + .dataAddress(addressBuilder.build()) .build(); - var response = ProvisionResponse.Builder.newInstance().resource(provisioned).build(); - var result = StatusResult.success(response); - return CompletableFuture.completedFuture(result); - } - - @Override - public CompletableFuture> deprovision( - AdditionalHeadersProvisionedResource resource, Policy policy) { - return CompletableFuture.completedFuture(StatusResult.success(DeprovisionedResource.Builder.newInstance().provisionedResourceId(resource.getId()).build())); // nothing to deprovision + return CompletableFuture.completedFuture(StatusResult.success(provisioned)); } } diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinition.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinition.java deleted file mode 100644 index 3b2536fd6f..0000000000 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinition.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonTypeName; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ResourceDefinition; -import org.eclipse.edc.spi.types.domain.DataAddress; - -@JsonDeserialize(builder = AdditionalHeadersResourceDefinition.Builder.class) -@JsonTypeName("dataspaceconnector:additionalheadersresourcedefinition") -class AdditionalHeadersResourceDefinition extends ResourceDefinition { - - private String contractId; - private DataAddress dataAddress; - private String bpn; - - @Override - public Builder toBuilder() { - return initializeBuilder(new Builder()); - } - - public DataAddress getDataAddress() { - return dataAddress; - } - - public String getContractId() { - return contractId; - } - - public String getBpn() { - return bpn; - } - - @JsonPOJOBuilder(withPrefix = "") - public static class Builder - extends ResourceDefinition.Builder { - - protected Builder() { - super(new AdditionalHeadersResourceDefinition()); - } - - @JsonCreator - public static Builder newInstance() { - return new Builder(); - } - - public Builder contractId(String contractId) { - resourceDefinition.contractId = contractId; - return this; - } - - public Builder dataAddress(DataAddress dataAddress) { - resourceDefinition.dataAddress = dataAddress; - return this; - } - - public Builder bpn(String bpn) { - resourceDefinition.bpn = bpn; - return this; - } - } -} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java index 4883876e86..c3dff33df3 100644 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java @@ -17,55 +17,39 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.provision.additionalheaders; -import org.eclipse.edc.connector.controlplane.contract.spi.types.agreement.ContractAgreement; -import org.eclipse.edc.connector.controlplane.services.spi.contractagreement.ContractAgreementService; -import org.eclipse.edc.connector.controlplane.transfer.spi.provision.ProviderResourceDefinitionGenerator; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ResourceDefinition; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess; -import org.eclipse.edc.policy.model.Policy; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; +import org.eclipse.edc.connector.dataplane.spi.DataFlow; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGenerator; import org.jetbrains.annotations.Nullable; -import java.util.Optional; -import java.util.UUID; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; -import static org.eclipse.tractusx.edc.spi.identity.mapper.BdrsConstants.DID_PREFIX; +class AdditionalHeadersResourceDefinitionGenerator implements ResourceDefinitionGenerator { -class AdditionalHeadersResourceDefinitionGenerator implements ProviderResourceDefinitionGenerator { + private final String type; - private final ContractAgreementService contractAgreementService; - private final BdrsClient bdrsClient; - - AdditionalHeadersResourceDefinitionGenerator(ContractAgreementService contractAgreementService, BdrsClient bdrsClient) { - this.contractAgreementService = contractAgreementService; - this.bdrsClient = bdrsClient; + AdditionalHeadersResourceDefinitionGenerator(String type) { + this.type = type; } @Override - public @Nullable ResourceDefinition generate(TransferProcess transferProcess, DataAddress dataAddress, Policy policy) { - var identity = Optional.of(transferProcess.getContractId()) - .map(contractAgreementService::findById) - .map(ContractAgreement::getConsumerId) - .orElse(null); - - if (identity != null && identity.startsWith(DID_PREFIX)) { - identity = bdrsClient.resolveBpn(identity); - } - - return AdditionalHeadersResourceDefinition.Builder.newInstance() - .id(UUID.randomUUID().toString()) - .dataAddress(dataAddress) - .contractId(transferProcess.getContractId()) - .bpn(identity) - .build(); + public String supportedType() { + return type; } @Override - public boolean canGenerate(TransferProcess transferProcess, DataAddress dataAddress, Policy policy) { - return "HttpData".equals(dataAddress.getType()); + public @Nullable ProvisionResource generate(DataFlow dataFlow) { + return ProvisionResource.Builder.newInstance() + .flowId(dataFlow.getId()) + .type(type) + .dataAddress(dataFlow.getSource()) + .property(AGREEMENT_ID_PROPERTY, dataFlow.getAgreementId()) + .property(BPN_PROPERTY, dataFlow.getProperties().get(BPN_PROPERTY)) + .build(); } } diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java index 59110d0d32..f54baf3a36 100644 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java @@ -17,39 +17,34 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.provision.additionalheaders; -import org.eclipse.edc.connector.controlplane.services.spi.contractagreement.ContractAgreementService; -import org.eclipse.edc.connector.controlplane.transfer.spi.provision.ProvisionManager; -import org.eclipse.edc.connector.controlplane.transfer.spi.provision.ResourceManifestGenerator; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionerManager; +import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGeneratorManager; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; -public class ProvisionAdditionalHeadersExtension implements ServiceExtension { - - @Inject - private ResourceManifestGenerator resourceManifestGenerator; +import static org.eclipse.edc.dataaddress.httpdata.spi.HttpDataAddressSchema.HTTP_DATA_TYPE; +import static org.eclipse.tractusx.edc.proxy.ProxyHttpDataAddressSchema.PROXY_HTTP_DATA_TYPE; - @Inject - private ProvisionManager provisionManager; +public class ProvisionAdditionalHeadersExtension implements ServiceExtension { @Inject - private TypeManager typeManager; + private ResourceDefinitionGeneratorManager resourceDefinitionGeneratorManager; @Inject - private ContractAgreementService contractAgreementService; - - @Inject - private BdrsClient bdrsClient; + private ProvisionerManager provisionerManager; @Override public void initialize(ServiceExtensionContext context) { - typeManager.registerTypes(AdditionalHeadersResourceDefinition.class, AdditionalHeadersProvisionedResource.class); - resourceManifestGenerator.registerGenerator(new AdditionalHeadersResourceDefinitionGenerator(contractAgreementService, bdrsClient)); - provisionManager.register(new AdditionalHeadersProvisioner()); + resourceDefinitionGeneratorManager.registerProviderGenerator(new AdditionalHeadersResourceDefinitionGenerator(HTTP_DATA_TYPE)); + resourceDefinitionGeneratorManager.registerProviderGenerator(new AdditionalHeadersResourceDefinitionGenerator(PROXY_HTTP_DATA_TYPE)); + provisionerManager.register(new AdditionalHeadersProvisioner(HTTP_DATA_TYPE)); + provisionerManager.register(new AdditionalHeadersProvisioner(PROXY_HTTP_DATA_TYPE)); + provisionerManager.register(new AdditionalHeadersDeprovisioner(HTTP_DATA_TYPE)); + provisionerManager.register(new AdditionalHeadersDeprovisioner(PROXY_HTTP_DATA_TYPE)); } } diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResourceTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResourceTest.java deleted file mode 100644 index 9272f7e736..0000000000 --- a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResourceTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.json.JacksonTypeManager; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.junit.jupiter.api.Test; - -import java.util.UUID; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -class AdditionalHeadersProvisionedResourceTest { - - @Test - void serdes() { - var typeManager = new JacksonTypeManager(); - var resource = - AdditionalHeadersProvisionedResource.Builder.newInstance() - .id(UUID.randomUUID().toString()) - .resourceDefinitionId(UUID.randomUUID().toString()) - .transferProcessId(UUID.randomUUID().toString()) - .hasToken(false) - .resourceName("name") - .dataAddress(DataAddress.Builder.newInstance().type("type").build()) - .build(); - - var json = typeManager.writeValueAsString(resource); - var deserialized = typeManager.readValue(json, AdditionalHeadersProvisionedResource.class); - - assertThat(deserialized).usingRecursiveComparison().isEqualTo(resource); - } -} diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java index fa930d83bb..c4a319d790 100644 --- a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java +++ b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java @@ -17,82 +17,56 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.provision.additionalheaders; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ProvisionResponse; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ProvisionedDataAddressResource; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ProvisionedResource; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ResourceDefinition; import org.eclipse.edc.connector.dataplane.http.spi.HttpDataAddress; -import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionedResource; import org.eclipse.edc.spi.response.StatusResult; import org.junit.jupiter.api.Test; -import java.util.UUID; - import static java.util.concurrent.TimeUnit.SECONDS; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.InstanceOfAssertFactories.map; import static org.assertj.core.api.InstanceOfAssertFactories.type; -import static org.mockito.Mockito.mock; +import static org.eclipse.edc.dataaddress.httpdata.spi.HttpDataAddressSchema.HTTP_DATA_TYPE; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; class AdditionalHeadersProvisionerTest { - private final AdditionalHeadersProvisioner provisioner = new AdditionalHeadersProvisioner(); - - @Test - void canProvisionAdditionalHeadersResourceDefinition() { - assertThat(provisioner.canProvision(mock(AdditionalHeadersResourceDefinition.class))).isTrue(); - assertThat(provisioner.canProvision(mock(ResourceDefinition.class))).isFalse(); - } + private final AdditionalHeadersProvisioner provisioner = new AdditionalHeadersProvisioner(HTTP_DATA_TYPE); @Test - void cannotDeprovisionAdditionalHeadersResourceDefinition() { - assertThat(provisioner.canDeprovision(mock(AdditionalHeadersProvisionedResource.class))).isTrue(); - assertThat(provisioner.canDeprovision(mock(ProvisionedResource.class))).isFalse(); + void supportedType_shouldReturnHttpData() { + assertThat(provisioner.supportedType()).isEqualTo(HTTP_DATA_TYPE); } @Test void shouldAddAdditionalHeaders() { var address = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); - var resourceDefinition = - AdditionalHeadersResourceDefinition.Builder.newInstance() - .id(UUID.randomUUID().toString()) - .transferProcessId(UUID.randomUUID().toString()) - .contractId("contractId") - .bpn("bpn") - .dataAddress(address) - .build(); + var resource = ProvisionResource.Builder.newInstance() + .flowId("flowId") + .type("HttpData") + .dataAddress(address) + .property(AGREEMENT_ID_PROPERTY, "contractId") + .property(BPN_PROPERTY, "bpn") + .build(); + + var result = provisioner.provision(resource); - var result = provisioner.provision(resourceDefinition, Policy.Builder.newInstance().build()); assertThat(result) .succeedsWithin(5, SECONDS) .matches(StatusResult::succeeded) .extracting(StatusResult::getContent) - .extracting(ProvisionResponse::getResource) - .asInstanceOf(type(AdditionalHeadersProvisionedResource.class)) - .extracting(ProvisionedDataAddressResource::getDataAddress) + .asInstanceOf(type(ProvisionedResource.class)) + .extracting(ProvisionedResource::getDataAddress) .extracting(a -> HttpDataAddress.Builder.newInstance().copyFrom(a).build()) .extracting(HttpDataAddress::getAdditionalHeaders) .asInstanceOf(map(String.class, String.class)) .containsEntry("Edc-Contract-Agreement-Id", "contractId") .containsEntry("Edc-Bpn", "bpn"); } - - @Test - void shouldDeprovision() { - var address = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); - var resource = AdditionalHeadersProvisionedResource.Builder.newInstance() - .dataAddress(address).id("id") - .transferProcessId("transferProcessId") - .resourceDefinitionId("definitionId") - .resourceName("name") - .build(); - - var result = provisioner.deprovision(resource, Policy.Builder.newInstance().build()); - assertThat(result) - .succeedsWithin(5, SECONDS) - .matches(StatusResult::succeeded); - } } diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java index af519d0368..39fef95580 100644 --- a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java +++ b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java @@ -17,117 +17,50 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.provision.additionalheaders; -import org.eclipse.edc.connector.controlplane.contract.spi.types.agreement.ContractAgreement; -import org.eclipse.edc.connector.controlplane.services.spi.contractagreement.ContractAgreementService; -import org.eclipse.edc.connector.controlplane.transfer.spi.provision.ProviderResourceDefinitionGenerator; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess; import org.eclipse.edc.connector.dataplane.http.spi.HttpDataAddress; -import org.eclipse.edc.policy.model.Policy; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; +import org.eclipse.edc.connector.dataplane.spi.DataFlow; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; import org.junit.jupiter.api.Test; -import java.util.UUID; +import java.util.Map; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.InstanceOfAssertFactories.type; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; class AdditionalHeadersResourceDefinitionGeneratorTest { - private final ContractAgreementService contractAgreementService = mock(); - private final BdrsClient bdrsClient = mock(); - private final ProviderResourceDefinitionGenerator generator = new AdditionalHeadersResourceDefinitionGenerator(contractAgreementService, bdrsClient); - - private static ContractAgreement contractAgreementWithConsumerId(String bpn) { - return ContractAgreement.Builder.newInstance() - .id(UUID.randomUUID().toString()) - .consumerId(bpn) - .providerId("providerId") - .assetId("assetId") - .policy(Policy.Builder.newInstance().build()) - .build(); - } + private final AdditionalHeadersResourceDefinitionGenerator generator = new AdditionalHeadersResourceDefinitionGenerator("HttpData"); @Test - void canGenerate_shouldReturnFalseForNotHttpDataAddresses() { - var dataAddress = DataAddress.Builder.newInstance().type("any").build(); - var build = Policy.Builder.newInstance().build(); - var transferProcess = TransferProcess.Builder.newInstance().build(); - - var result = generator.canGenerate(transferProcess, dataAddress, build); - - assertThat(result).isFalse(); + void supportedType_shouldReturnHttpData() { + assertThat(generator.supportedType()).isEqualTo("HttpData"); } @Test - void canGenerate_shouldReturnTrueForHttpDataAddresses() { - var dataAddress = DataAddress.Builder.newInstance().type("HttpData").build(); - var build = Policy.Builder.newInstance().build(); - var transferProcess = TransferProcess.Builder.newInstance().build(); - - var result = generator.canGenerate(transferProcess, dataAddress, build); - - assertThat(result).isTrue(); - } - - @Test - void shouldCreateResourceDefinitionWithDataAddress() { - var dataAddress = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); - var build = Policy.Builder.newInstance().build(); - when(contractAgreementService.findById(any())).thenReturn(contractAgreementWithConsumerId("bpn")); - var transferProcess = TransferProcess.Builder.newInstance() - .dataDestination(dataAddress) - .contractId("contractId") + void shouldCreateResourceDefinitionWithDataAddressAndProperties() { + var source = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); + var dataFlow = DataFlow.Builder.newInstance() + .id("flowId") + .source(source) + .properties(Map.of(BPN_PROPERTY, "bpn", AGREEMENT_ID_PROPERTY, "contractId")) .build(); - var result = generator.generate(transferProcess, dataAddress, build); + var result = generator.generate(dataFlow); assertThat(result) - .asInstanceOf(type(AdditionalHeadersResourceDefinition.class)) - .satisfies(resourceDefinition -> { - assertThat(resourceDefinition.getDataAddress()) - .extracting(address -> HttpDataAddress.Builder.newInstance().copyFrom(address).build()) - .extracting(HttpDataAddress::getBaseUrl) - .isEqualTo("http://any"); - assertThat(resourceDefinition.getContractId()).isEqualTo("contractId"); - assertThat(resourceDefinition.getBpn()).isEqualTo("bpn"); - }); - verify(contractAgreementService).findById("contractId"); - } - - @Test - void whenIdIsDid_shouldCallBdrsClientAndCreateResourceDefinitionWithDataAddress() { - var bpn = "bpn"; - var did = "did:web:abc"; - - var dataAddress = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); - var build = Policy.Builder.newInstance().build(); - when(contractAgreementService.findById(any())).thenReturn(contractAgreementWithConsumerId(did)); - when(bdrsClient.resolveBpn(did)).thenReturn(bpn); - var transferProcess = TransferProcess.Builder.newInstance() - .dataDestination(dataAddress) - .contractId("contractId") - .build(); - - var result = generator.generate(transferProcess, dataAddress, build); - - assertThat(result) - .asInstanceOf(type(AdditionalHeadersResourceDefinition.class)) - .satisfies(resourceDefinition -> { - assertThat(resourceDefinition.getDataAddress()) - .extracting(address -> HttpDataAddress.Builder.newInstance().copyFrom(address).build()) - .extracting(HttpDataAddress::getBaseUrl) - .isEqualTo("http://any"); - assertThat(resourceDefinition.getContractId()).isEqualTo("contractId"); - assertThat(resourceDefinition.getBpn()).isEqualTo(bpn); + .asInstanceOf(type(ProvisionResource.class)) + .satisfies(resource -> { + assertThat(resource.getFlowId()).isEqualTo("flowId"); + assertThat(resource.getType()).isEqualTo("HttpData"); + assertThat(resource.getDataAddress()).isNotNull(); + assertThat(resource.getProperty(AGREEMENT_ID_PROPERTY)).isEqualTo("contractId"); + assertThat(resource.getProperty(BPN_PROPERTY)).isEqualTo("bpn"); }); - verify(contractAgreementService).findById("contractId"); } } diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionTest.java deleted file mode 100644 index a549ab00cf..0000000000 --- a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.json.JacksonTypeManager; -import org.eclipse.edc.spi.types.domain.DataAddress; -import org.junit.jupiter.api.Test; - -import java.util.UUID; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -class AdditionalHeadersResourceDefinitionTest { - - @Test - void serdes() { - var typeManager = new JacksonTypeManager(); - var definition = - AdditionalHeadersResourceDefinition.Builder.newInstance() - .id(UUID.randomUUID().toString()) - .transferProcessId(UUID.randomUUID().toString()) - .dataAddress(DataAddress.Builder.newInstance().type("type").build()) - .contractId(UUID.randomUUID().toString()) - .build(); - - var json = typeManager.writeValueAsString(definition); - var deserialized = typeManager.readValue(json, AdditionalHeadersResourceDefinition.class); - - assertThat(deserialized).usingRecursiveComparison().isEqualTo(definition); - } -} diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java index b05713cee0..964180c132 100644 --- a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java +++ b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java @@ -17,11 +17,12 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ +// Some portions generated by claude-sonnet-4.6 package org.eclipse.tractusx.edc.provision.additionalheaders; -import org.eclipse.edc.connector.controlplane.transfer.spi.provision.ProvisionManager; -import org.eclipse.edc.connector.controlplane.transfer.spi.provision.ResourceManifestGenerator; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionerManager; +import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGeneratorManager; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.junit.jupiter.api.BeforeEach; @@ -30,25 +31,27 @@ import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @ExtendWith(DependencyInjectionExtension.class) class ProvisionAdditionalHeadersExtensionTest { - private final ResourceManifestGenerator resourceManifestGenerator = mock(); - private final ProvisionManager provisionManager = mock(); + private final ResourceDefinitionGeneratorManager resourceDefinitionGeneratorManager = mock(); + private final ProvisionerManager provisionerManager = mock(); @BeforeEach void setUp(ServiceExtensionContext context) { - context.registerService(ResourceManifestGenerator.class, resourceManifestGenerator); - context.registerService(ProvisionManager.class, provisionManager); + context.registerService(ResourceDefinitionGeneratorManager.class, resourceDefinitionGeneratorManager); + context.registerService(ProvisionerManager.class, provisionerManager); } @Test - void initializeShouldRegisterProvisioner(ProvisionAdditionalHeadersExtension extension, ServiceExtensionContext context) { + void initializeShouldRegisterGeneratorAndProvisioners(ProvisionAdditionalHeadersExtension extension, ServiceExtensionContext context) { extension.initialize(context); - verify(resourceManifestGenerator).registerGenerator(isA(AdditionalHeadersResourceDefinitionGenerator.class)); - verify(provisionManager).register(isA(AdditionalHeadersProvisioner.class)); + verify(resourceDefinitionGeneratorManager, times(2)).registerProviderGenerator(isA(AdditionalHeadersResourceDefinitionGenerator.class)); + verify(provisionerManager, times(2)).register(isA(AdditionalHeadersProvisioner.class)); + verify(provisionerManager, times(2)).register(isA(AdditionalHeadersDeprovisioner.class)); } } diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java index 84c97973b0..0b719a5237 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java @@ -77,6 +77,10 @@ public String didFor(String participantId) { return "did:web:" + URLEncoder.encode(didUri.getHost() + ":" + didUri.getPort(), StandardCharsets.UTF_8) + ":" + participantId; } + public String bpnFor(String participant) { + return "BPNL0" + participant; + } + public static class Builder { protected final IdentityHubParticipant participant; diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java index 2001f2b278..62a4954678 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java @@ -84,7 +84,7 @@ public class TransferEndToEndTest { protected static final RemoteParticipant REMOTE_PARTICIPANT = RemoteParticipant.Builder.newInstance() .name("remote") - .id("remote") + .id(IDENTITY_HUB_PARTICIPANT.bpnFor("remote")) .stsUri(IDENTITY_HUB_PARTICIPANT.getSts()) .did(IDENTITY_HUB_PARTICIPANT.didFor("remote")) .trustedIssuer(ISSUER.didUrl()) @@ -92,10 +92,10 @@ public class TransferEndToEndTest { static final DcpParticipant LOCAL_PARTICIPANT = DcpParticipant.Builder.newInstance() .name("local") - .id("local") + .id(IDENTITY_HUB_PARTICIPANT.bpnFor("local")) .stsUri(IDENTITY_HUB_PARTICIPANT.getSts()) .did(IDENTITY_HUB_PARTICIPANT.didFor("local")) - .bpn("local") + .bpn(IDENTITY_HUB_PARTICIPANT.bpnFor("local")) .trustedIssuer(ISSUER.didUrl()) .build(); diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java index 5af9f2628d..a2afc171e7 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java @@ -171,7 +171,7 @@ void httpPushNonFiniteDataTransfer() { consumer().terminateTransfer(consumerTransferProcessId); consumer().awaitTransferToBeInState(consumerTransferProcessId, TransferProcessStates.TERMINATED); await().atMost(ASYNC_TIMEOUT) - .untilAsserted(() -> dataFlowIsInState(providerTransferProcessId, DataFlowStates.TERMINATED)); + .untilAsserted(() -> dataFlowIsInState(providerTransferProcessId, DataFlowStates.DEPROVISIONED)); } private void waitAndAssert(Duration duration, Runnable... assertions) { diff --git a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java b/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java index e802a4b6f8..f2450f2114 100644 --- a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java +++ b/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java @@ -28,8 +28,11 @@ import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; import org.eclipse.edc.protocol.spi.ParticipantIdExtractionFunction; import org.eclipse.edc.spi.monitor.ConsoleMonitor; +import org.eclipse.edc.spi.result.StoreResult; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.system.configuration.ConfigFactory; +import org.eclipse.tractusx.edc.agreements.bpns.spi.store.AgreementsBpnsStore; +import org.eclipse.tractusx.edc.agreements.bpns.spi.types.AgreementsBpnsEntry; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.eclipse.tractusx.edc.tests.MockBdrsClient; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; @@ -51,6 +54,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.util.io.Ports.getFreePort; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PREFIX; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @@ -66,9 +70,26 @@ public class EdcCompatibilityPostgresTest { private static final URI DATA_PLANE_PROXY = URI.create("http://localhost:" + getFreePort()); private static final URI DATA_PLANE_PUBLIC = URI.create("http://localhost:" + getFreePort() + "/public"); private static final String CONNECTOR_UNDER_TEST = "participantContextId"; - + private static final String BPN = BPN_PREFIX + CONNECTOR_UNDER_TEST; + private static final DataspaceProfileContextRegistry DATASPACE_PROFILE_CONTEXT_REGISTRY_SPY = spy(DataspaceProfileContextRegistryImpl.class); + private static final AgreementsBpnsStore AGREEMENTS_BPNS_STORE = new AgreementsBpnsStore() { + @Override + public StoreResult save(AgreementsBpnsEntry entry) { + return StoreResult.success(); + } + + @Override + public AgreementsBpnsEntry findByAgreementId(String agreementId) { + return AgreementsBpnsEntry.Builder.newInstance() + .withAgreementId(agreementId) + .withProviderBpn(BPN) + .withConsumerBpn(BPN) + .build(); + } + }; + @RegisterExtension @Order(0) private static final PostgresExtension POSTGRES = new PostgresExtension(CONNECTOR_UNDER_TEST); @@ -77,11 +98,12 @@ public class EdcCompatibilityPostgresTest { private static final RuntimeExtension RUNTIME = new RuntimePerClassExtension(new EmbeddedRuntime(CONNECTOR_UNDER_TEST, ":edc-tests:runtime:runtime-dsp", ":edc-extensions:single-participant-vault") .registerServiceMock(BdrsClient.class, new MockBdrsClient(s -> s, s -> s)) + .registerServiceMock(AgreementsBpnsStore.class, AGREEMENTS_BPNS_STORE) .registerServiceMock(DataspaceProfileContextRegistry.class, DATASPACE_PROFILE_CONTEXT_REGISTRY_SPY) .configurationProvider(() -> EdcCompatibilityPostgresTest.runtimeConfiguration().merge(POSTGRES.getConfig(CONNECTOR_UNDER_TEST)))); private static final GenericContainer TCK_CONTAINER = new TckContainer<>("eclipsedataspacetck/dsp-tck-runtime:1.0.0-RC4"); - + @BeforeEach void setUp() { ParticipantIdExtractionFunction function = ct -> ct.getStringClaim("client_id"); @@ -91,7 +113,7 @@ void setUp() { private static Config runtimeConfiguration() { return ConfigFactory.fromMap(new HashMap<>() { { - put("edc.participant.id", CONNECTOR_UNDER_TEST); + put("edc.participant.id", BPN); put("edc.participant.context.id", CONNECTOR_UNDER_TEST + "_context"); put("web.http.port", "8080"); put("web.http.path", "/api"); @@ -113,7 +135,7 @@ private static Config runtimeConfiguration() { put("edc.policy.validation.enabled", "true"); put("edc.iam.issuer.id", "did:web:" + CONNECTOR_UNDER_TEST); put("edc.iam.sts.oauth.token.url", "http://sts.example.com/token"); - put("edc.iam.sts.oauth.client.id", "test-client-id"); + put("edc.iam.sts.oauth.client.id", BPN); put("edc.iam.sts.oauth.client.secret.alias", "test-clientid-alias"); put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); put("web.http.management.auth.key", API_KEY); @@ -126,7 +148,7 @@ private static Config runtimeConfiguration() { put("web.http.public.path", DATA_PLANE_PUBLIC.getPath()); put("web.http.public.port", String.valueOf(DATA_PLANE_PUBLIC.getPort())); put("edc.dataplane.api.public.baseurl", "%s/v2/data".formatted(DATA_PLANE_PUBLIC)); - put("tractusx.edc.participant.bpn", CONNECTOR_UNDER_TEST); + put("tractusx.edc.participant.bpn", BPN); } }); } diff --git a/resources/java.header b/resources/java.header index 8ff72fff09..da5ccc67e5 100644 --- a/resources/java.header +++ b/resources/java.header @@ -15,6 +15,4 @@ ^ \* under the License\.$ ^ \*$ ^ \* SPDX-License-Identifier: Apache\-2\.0$ -^ \*+/$ -^$ -package .* \ No newline at end of file +^ \*+/$ \ No newline at end of file diff --git a/spi/core-spi/src/main/java/org/eclipse/tractusx/edc/edr/spi/CoreConstants.java b/spi/core-spi/src/main/java/org/eclipse/tractusx/edc/edr/spi/CoreConstants.java index 7257b1be9f..24d87e9d5d 100644 --- a/spi/core-spi/src/main/java/org/eclipse/tractusx/edc/edr/spi/CoreConstants.java +++ b/spi/core-spi/src/main/java/org/eclipse/tractusx/edc/edr/spi/CoreConstants.java @@ -42,7 +42,10 @@ public final class CoreConstants { public static final String EDR_PROPERTY_REFRESH_ENDPOINT = TX_AUTH_NS + "refreshEndpoint"; public static final String EDR_PROPERTY_REFRESH_AUDIENCE = TX_AUTH_NS + "refreshAudience"; public static final String AUDIENCE_PROPERTY = TX_AUTH_NS + "audience"; + public static final String BPN_PROPERTY = CX_CREDENTIAL_NS + "bpn"; + public static final String AGREEMENT_ID_PROPERTY = "agreementId"; public static final String EDR_PROPERTY_EXPIRES_IN = TX_AUTH_NS + "expiresIn"; + public static final String BPN_PREFIX = "BPNL"; private CoreConstants() { } From b81dafc310188b05d47be765004c89007305aca9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 08:54:26 +0200 Subject: [PATCH 076/259] chore(deps): bump gradle-wrapper from 9.4.1 to 9.5.0 (#2810) Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.4.1 to 9.5.0. - [Release notes](https://github.com/gradle/gradle/releases) - [Commits](https://github.com/gradle/gradle/compare/v9.4.1...v9.5.0) --- updated-dependencies: - dependency-name: gradle-wrapper dependency-version: 9.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.jar | Bin 48966 -> 48462 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++- gradlew | 2 +- gradlew.bat | 31 ++++++++--------------- 4 files changed, 14 insertions(+), 23 deletions(-) mode change 100755 => 100644 gradlew.bat diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d997cfc60f4cff0e7451d19d49a82fa986695d07..b1b8ef56b44f16b14dc800fa8103a6d89abb526f 100644 GIT binary patch delta 39760 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 e(*aw}>J`&Ep$5$o2mVP)i30-M3~u@DBh0 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 delta 40115 zcmXV%Q+QqN*Y%q=&W^QX+qP|^v2A-dHg{~BZLG#@Y};vUetrJ$cd`!F*}CSOW8U}p zjWzl5b?D=3y%REMd38|-8Qy^Zu()|mV!mA+wfMNA46Czj#TqxuEX}M1)`V!F<%-^p@5zZ#zK3v1!%Twk#AfK(j(D~g%G)1wvnIq8OF~L7?k0+oGmA81 zTNa^TfZQ1UR18{GD#XxwYlDgr@y$#z*v;V_$-=XmV<%aevua^h4}Kt39J%8 z01n7S1|v};gKz6GLFQ^}is&jB`r*w0`*1k~iK`%P11mW>35O<%ZWJbRi5Lo$7^X6| z@RJ_5(u@qW*u>9iqAQJ9>FI%|bI&LA?g(FK8#ynYS61J;rm0oSfcN)@Z$12}IGaTH z{7l^{HhLTAsinyn?oy*Pl^a&Ll#hV5F)lj=!wPMF8DAXEDK zEW%lnet{1f$Ong_!u|Xs$?aU5BrOZJCX1tCW@A98mQnx=V1JAImQg>m=j2PuG!& z+x>zNl!Fl@KPf6~ZxqNyH?Y zgzvFL#QEOI`NKFF03>De3R@Hoe2uXUZ~YMJc8;M58@pq<0bDZYQaGmWP#rFI8__>v z%IOj*27usU$K5DrT!U!tq$8w@5kHKAB&m1tKX9Cb=*jR#RbQoutpHHBp&tcHQW`Jlro>kEh7FGfGGAU;z<0vB|C+GeBXqf5CW1{Jko72_Lr`~dxDw1OR zYFy0;ZPw}@$9BT_b>YkaBZQxHJ8*>XE{on)I_}0Gj=oeP+$xTXP?J$B-qNY8(zUqj z{Pw=TDd8a+gQfvB2i|6|XX~AEx+DZz@CAA&3GPbe2`-6Ut$vPeR;wmcPu%cB`HoNw z=8=}QRKP#NJWx{3Yv@qpt_Wv=m#)@nG_we`q6LRbHi^nv6COJSVch+*!m?U+68vbm zlE5U;B3wu>bspSw;96NULIncfV#|JNGe`p@mT2RyGTFMCW0bCmekexPOg z)pLM`G7s%(Zm==0+U9|8=eF|+MsuOZl_rTZVyHrj?MG1ph`^{ldYpC`}`&LK2r^$xC> zPG>xZp_<}2HY@zeM|*{C;u+>*^6slSSBxypdd~!8t!bQbC9-gEFUnrCzr`2Ms*b)W zt1qhQ!$EOttzzGr6zgJ)JM{-7$LrwlqqGD9WpHU@H+jioEn*tEPk56WEv&erfnm~S zl&&eusI$+G=}%D)Tr!`bgwzT@5pkpZFP=-C8jf^}Az704gjm!@2~0>oIXy$h4S9Kf zHO3{#d)yfIE)dczjb~13L^wz2K3{74x%SPB^2z%Ik)MSSiJmk4*Jz7!B(l0-VJth4 zt>c_Fia^W6VvX~Otv5q`aVfh!8kaDM0$ys#-y79&v5=Z%(m;powSoEg5sy`Uk|(08 z45BY+c3N)Ueqy^)41CRM_HslQ*k~(}Qvz(BlYiE)(?DDPUz{Mga18i;J?gH+Yn=SQ zFKf8VE~L#@SMq80Gq*W%H(T&%h_upy^-2cK?LYQ(y;aB7$O=qWSE(#G(Y$#7NT1 zjB4v!hI*W1aNvMI^Sq9Y#tYAFW6HWbMCC^m=KDL8*1v#gxLv za4W1r5E51)-unT7gTZMh$Rc%nr*;S%One^p3q6u|SaP8dlD2o|W5vZ&r9;hf5zcJ% z*OBOuKDLzp%aj``JQvRj?Gynb!D)#NAp-~~wx)62TJDD!6T7V6A+mV}``+tzs;D~w zgxq(i5NQ?!98koJx<}a( z&eEl-bX1hYbqiqaSX1n1Dy6XdJSA$kD!JkpyKFH}a0)c8PXU|Bby*|@o6Td6&f_p~ zEJnUz?ZtM}PhS_K8ar3M?jzk0oo~Q1qz2Jon9J{?^%oFyiWf4C1BdHgaRgjDFuXE% z%-;YjE_V;KN&~No6uF=jmf$TQ+AsDiYu=g6Zh4r$f_0F;I;fbtHyUaC5K-@D_`$~< z13s@o*OH&BJ^!AMws&qAfA64@-FR-XHZsm}eGJH+?h4XsBkqxT6Y{shPuu~?jxg2z zj??eZR6ju??;!;@HB&&P@aYlPyE-!c(z1p>MR&N9T{^>FJZ9H~*yFB$bt*ul?_2@j z`%~i2(&4_}>Trs6R@L<#*Ukw&mkKyuu7mOc13JBl&^nh6pC~@lQyQGqfp3VR9t6w zI4h?2@LD~r#O`wZ6!u*qO5jvD_LW2%A;zA|%5d$zWw>m~y-kbXdL{c|s;zu=nnGu( zn}-~CeC?d52)Pz?Jp(f02DYf;^v~<}%Sx$giY7Q9s2#^`@1$Rd@0yYdUYMyV*4wLd z5uhSjBqb*2Mgmob#mI*52d>fgn{*LwioVa0_u|Zvg|}gz6enW!an8!9Qic4T#yY8) zkjl~}gJVJUD?p3-`uQWJX>XUM9|K-d+v6vN^%9J34fWw8 zw~-^`VoG|OXY5B+hiIr$Zz4yi+=#t${&zy}o)m4&M)6A(CB=OG-mvViP`#fdnP3u6 zcfSm6(E+wZYP4eMP_kZHD+4^8L|3$x5C@CUA|u_qLcxL-GyQ(MlSX@gS{v?Kvt#Dj zFkjW)rZD&Ru4Yh`t#7lSCvG^#6Rsi`l6Co@rjWXwT75}~A*}~Bwc`lO;;Tw{4(^4R z0w!&}t{6q-{wV}vfcm(GaBx_x3+8-1T-Je&5Z#=t=jy1PY_UF+K4KeerVsB*60*pi z&m5{YodqqfcD&E#>9%^9OdSpDy8UU~TrEjRDJ?r`wGn9UW+%a%T%DawI=F$YjGdo4 zL&r(G*PpJSihFE5>s-b255j^qBJxga9@!q`qYr6s63s&^XumL`<8SN{2Y(DF&a4NM z@Ex%!{P!$m&T2M%T){waK-dcyKJ$X{yL4~GxN~B>$`JwKL4L)t=JZSkQiS?Y4m^e^ zFnvBpcnH)?851H6DapW>aM>Lpvk|Db2aQDFgv6n>i(x97nmp+zq({1?lma_q!-yEa z2Zu8{M`xm4j$23X`*tj<-aB*Au?=~DzXSWq;5ca3 zsoX5vG79|{KNAajig)6m(E1|R!ldkPM^e0Gd*f1!FUD{!M3-p=_lD<|M;mm>%k!Jn zH*-T7J8VMC^DS9B88F3Vo8R?gR3yHNuHqdS(W)@eF59QnYP8xkb0$~kMFZ1heNUApov~(>x<{0N z?_iiCr}cgxC48go)`)f7UdtYhyUw1zio*Zt{^WpJYvO6_X02ljKME|*=^Z^Kc3 zhF}#TZPW2eSBP-%66mX2Tn!g?OW=*&73QM(<53{`8h&(`~To4Eb{EPnOjr|Oj*L)?7j z8{I*cT)X{gMD4L7`pn)rcct6 z@h2go%-&5L@y)?RE~jd1q?);MxIv3@GbDn3SFioUuk9xLt8;s=-w0zR#>GJ2n&LS& z`oOox?`o01KKgK)(snq1<0(HlLVE59)Y|TleI1Ilq#Zjcif^6VHX~d@v4;PIiE_3- zI{e@PD2nO!DATjYFHamXIC`fg zZiaIJ%6}ibj9qQdW24QnK|}_S<8{ui)i?zoR!pe?`2oW1$Qg6KbB(Bs=Q}Ky7={_ zZ@){1ohh+`E8A4(&6ZqGdFhbM?&R-f8TO~*ldFq>(gCRG=G!>Vh13G6k8*)}q2eG5 zX4qH0s_C^o!)l5tXkTBS5uz5CCTD%wx zJA3ax&0hJ*B?zI^ZWrXockqMQ|L7ZEgz7WRYkIcgMO7{~AjW$Fs1{q-YF(?kMVIqg zwlCfE)9`l~xg2Ixq}LKfA>$fHJD7qJOcH-LxLH;hYnvGQ=6y3AX?b%nilU061D*yL zEuH_+tu4=}RnvVGh?lF9k)85Ji8A`gKo28tTZvQy0hencq(pnE#qL4U4qL@B^kR!j z>cG@2DVJ9WWSVN!&s?&cW5NEY0JOjxtp4(k#?BH_WDaB~bXpf6(J+t_CyEfXh6RaO zIKe(;-Sr%Hd7C+2qHinVY`-+N28j9~rpJ>@!B<4TG>izc4)WqJ%nhTpP#)W(pJb7L zx?y_$OL8OjHMd&3B_1@T>Xdlcp9cB2m9+4=wc=CiuHRWhZ%B_Y%}HX=TQ4HIngzqJ zZD+jKQ3zLaVJ}o>w%GdIM^uuw)|4d9J2*4ZOvp$u6-!J~3HP^ROPDdMhof6pGpxZ) zGaa+Ugx2u|>*@^sv_s5;H-=Tsv^6wNOacRa_oQEc#h4a`5Sd;;=`lk|K2Oj9afvGL zT>ts7c%7_mD!p7|1(3!o6@$%;3hQ_Na{q#CQ@CxO>V!9aas7$9D}R`V&ooQ|E7qs5 z$zKdn*}9jE2JryMjIIBA%{G`lU;gWtFKJ-oTmo=2xgIFGxlvBU;efOljh%cMjTr4s zthA&5XMG37FWnHJH%eYFkxeUk=F=C!&u-TYw%?y`Pf$h}u7JGw zIL)6#3#3b)p|<5}mE9$!8eRM6-#H&^lB#$p#84PR8Ct1ES|9^cM5V_$;5M*li?l;5VWgmc zWs*EBC?OgF5*JjzpYAr9BZNgJv9p!#hcU3W+nXQC#r5l(Mkc4W-G#(pKLlmF618>; zYx-XxKs5nQDkqotPjPVXKQW-)Pr`b5Hd;y9CX_*!j=BbZ$4Cz~P7uCBE)1a59fd;P zE}y6U4r)>>KoQa-&;~sk0!2a&65d3GoftoT6{v$BppBtken*FBdMr)<_sT!Fq0QDp z^L<;d6nu%3Jdm9>53PpSsuaLQ1K%FG>y&rc8@&s`OLi>6)Kt5FD0flvRMjz1rRjIi zUk>{2zi_HGJ?x}}|CDr8{M{qu%vW8T!fmDHTwYN&pw-O#!wrKrH|!eHIjorv7Cx6H zq}6!+SiYc@%q@=>UE=E~Y_93HheZpmN9Hb`a~Zeemx!_o>#{`sdGhD$8Ay@+RB93@J*2t80Vp91R- z4G9VJjbq_G#a|y4IoJ#sPEJ)SE2NwP4*#GBN7!5-@3eQXpS%voorY?Sewo)(Xn-n? zg>_Atao7 zf(&*o;#DwI$NsJB8D`5oe2CBiu~Y7<59$$K-)J2yj! z>vzDn9$znt?bDkZ-A^eLQx`>EM2{ddjA|&E#5C0ca46C(Da9coji?-b+)UVLdXlT| z0p~IZr{HHJR`U0BQykgL1{_D@_NIxp($Bg8b(+Bt0@J53vDu7yammw|6*!!65X+V! zsAUsbEfW&^mKd@zT*4gfg%lIcOE;Z<3{Vf@*}6au)$0-PIl{d%jkGo z1>y8->ZDUpqG*nU)HM!8EtCSp1hT5!qlz%7W{vOr4{xveFsw$X`3{&aFem$4hnm#` z%SA$WhY}@v{mfs)3;Vs_&>r4lqOR5{V2`hYo-m#pfE>e~i(mpioHqYP&szSzlRL6n zdQ2VzP5*doCZm}wd`)lpL!hZdXB>3=i4uB9Ugjk>zJNJKOzcA5)zj*koPk05XdMpS zk;M%<6M`4d?KW43hY@P&xCK@Gl#zGTl)%(?j_#v;kN?%{Ufc4f5PU&n22w&7!4Q~R zbg0mkL(qo8)K^}ewKr9_>v*Oe3loFM26iEt?`uo;YCH*e_M3Y@WT7pn%pOrmvA$8Is*S*jXVf! z+$)H5V#NL1bK``_?nP8Fp#J*Hu+rVfrF4KxR0zdOCoEnys{= zWW=!QJZTg!GhdIpbmJ0ULaxbq51D42H4SIfP<{+O)x`dJ3`QdziGYwXK-&nBIrAS) zTQINmi4RiRr_KADh}K8~^DZmA;fhMUv4f~>(-Q4rL&C6zo@x1;?`N?iUugoo!yA== zckcv0mUFcHwurDRNMun7o}g%QfJ>d;m?yQh#stfiMaS6at`=9!0!$fHFdb=i-0Xdo zhvqkxa{-Ag=hm{A2AH>vt%7A2LxvZFo zo9@urLefPA&me!23+SAX)4%_(VH*9d6iEN=FAMMwbOLZDy$EPa4o?JS*fLgzJu_3& zKF^QGPg-`esBs~GSF9umMLp(edu@GV|7Uv(-UA~9>buw*(~J65uTYPWEH7S>2CSD8 zpHTO&ypreeaQ9elzjI~mtMVn^lghPvNC?r;8UFNWk;&ossldbHA3(U>jo0%xXb z0u*>>U$!1J2T^8pfw6je04Npsl4JAjKs3XG!D7{3%czTsj$D?-FZ_bl+aE z4?noO4)-~q8#?h+t1P!Vz%*utIQXhiEEn9ldFfjg) z9%Pi8Csl)E8G}JjP?#}rNx)b{pbB7MVEw`%HFTq6VuQgZhCgCz8(9IK^5Z`yxMxSR zN-Wc#m(#}fn9alX>v8FlNC;wmkiP%u{T=%t-X}%3Lv-~e$ieS}iwZy?`?GF*ffmM`J=A93`@f_N@8j#>q{lsq+_fxk5#`Qby> z)>|c{{y!^FcKgQ)Y*ae++SO?BnwRHmhImlPXe}OxqL>5T|U`7D7mwq-gw1WAK8D` z77!h=Nt0EP1a})0GZ%~Ww=Lt%Ob2f+x;s=&BBFGA0>__WiZXy zMC})*Hz~Q$3iTPS$`wwPOe|f>CXV+IG2q-(o10A?DHV=l5#B<}DLu|6=hIvEasWTY z^=5nnU?Vfz;2XW+O%Lez3@-i+_!(oTbt6aT35Q;z*PJ4UiR64>OD7OoWq(o&J{kRe z?5&DlGz^c2hZrMhn@|Yt&@B*h-5z)i>@nh`ATK94&0Y@6%onGJjr^a#84nvJ<@!%C zhX0*->Hm>cOmI63Do9rgT?@D|3`sShO_9%zWu9pR7nne6fYLb_k@6J|ZCJ+7SmheJ9;%lZ-W* z68hxt9hwb$?`(Q45}utpvKn3-C2jbYrBg2V=RAEn{%5b2HtmYg9e>oQtZ8GCEMSeT zB_pd{`+lC#|9rf^d$=o6XTb*He>H{0{*ze}ahAylG@GL>k;Bq*Pt{=8)kX^fz<`LZcybrpRAi6Jh+qd3>(dH&gg9A}rxXrYi-OfmGa@5 zaawD$Zd+o$_h)n6d=Q3pVY7?5GO|FT<+PA-{|GjgwgQ=0t@e@>@Wf!TOQ7_ANV0D; ziyeQ}-=N~I_nxa(oRp1V!Pg9}`7Sz9&1dM;s`jgE??UnlVzrMus0cNrVXDN=(n@Z< zf)b91MLM8e`G;y`qC%RVJv6Up3U?6t6L-ws zaRhOQ9e|}|t{N%+4F_@P9^rrNGw{x^1_^Lq3Oh?n{@mMSsA(!s(Eb!%+JTptDa}mg zQzh86tt_GnvBl`anIruKPA(in59Ap;z{OnAOzV4%$ zQUh`8{~p~@343@;Rlv2MW$0ay_>ReztVJ7mqdwt2tI{{&*zMvkXeo(bLS2qJ>;a=Hv027+05D{i@6JD^Y#z|SLL?UGS*_alLv&N zfR%>oADp^-#fn4$5r*N8gj>_FjV9SXYRD0cr#yU0gr0}Cl z@BJ3>=iqi-LR5dCc0CG#e65ic4jJgT{jVdBhIso`s;I%4TFiC*q4%Y2IqF!qcRbV5T$3FJERMVE+eu{>z%2 zaZ>(I4KY5D;1q#hGpVC=WMfDZ5NHa4ZOdN=3(1XQQzTE!lX&31fiv7J`eqk2w6s1Y z-oJJ4>R>c}xA#94)A|%9dS!c=E`8k(k^wJpBD+4EucSHVz5mTI{CN40`l6*`@h=bk3pUEQ{BTBA9TvK9AF;!&I{E7=P1q@FVQV$#WCAo-ehJhn1jYnthmZMA@DN=Un#XvK=oLt%W zncf}Wqxky%>_WMwRY_UAzcrZBAZT{06FaH`*q<4+Q*X!%R{Cz2vn{M96~g9B2}t9G zjGSU)g|2qF{aDGLaQy7KDYBDTKwo}i6W-nB<5{j&Q>TagVx5Ge!|CcfWnk*$II*v+ z`o<3jfrA|)Mf4K7ApsqK=p^SXFGo!1806Pcn|E&lnI=)H0u6fggxdq4HCV*fmg{VY zG4(~b$*(xM34>~>nrk<_uqBPaf1J!09Ir<1p zs~Qzi84Ng!m3n7blW4_Cp&gc&nncP*#5ZY8*Pdt}DsL#(3MQw&Eg% zwZ%PNeFCNIolzGe3JA1k6Vda;P_svvA+y>ga;E5f_6SpnEWLB4LGxw3I+Z=g5dyf( z@>KaZ_z=oe{3CEKp2CLu?7FPn?6`vzs|x^sn(z-KtBG~&&L8pZBr~6(S>!rgfa-NcRueDRhUUHkBnuk#P3~!eZ2jL5HpU4J&Gq;m~sZ707=Uhi_!O z=Y8;q9TF%~cEqfQ`KKV-Nv2W#is~y`sZ90sEc$Q4-frGE$8vn^oKa<*@skCyb(g8G zKKn4U;yCLYzv4vJYkKuA|Jo2aSLU!##3;l``s zOM?ndvqGLvUx|Rlm+aW?{J-2X9C%HWjfljU8XDT;<=n_0SmdQ{mXQ-?vutaX#|RYN zrBpxM?kEITs<00G%buzUtwO)L&+rfy+L9)$EV&g`2^H}*YC$V?NTh3MaUV>Dk9?x6 z2@wQde5>kF0&YV7ti-^chg$ldM+sDjK?(k+QmX$aQXPDJpmEuLVGIG&`FWkKcK5_k zD{DaEVj-z?Z)|8((DVU&n?jjl5-S)({7&o*0b5o1>f0Ojb@TS*#6jobddBm|^V3(S z5QV^{w6wJ$@KVaow~|E9(@=rB!_e=n>N?;ltO@$K0K!ysuaUJeB3rgI!xS%87&_(*??mOgkRotrNk#cqmck!Vc#znl>@K;2k z!o)|tAQb8?^H8`GS!=ZAQF;6UNy*G0<*IE-TsajsIkXH(h6`I{DlHEdx_aIOG90Un zA(0Ngd}dD;CT5|ec4E5vh0GU;S~n-_e{w{VmFK*zqgO)v8^y`v@q&)pv;lyP85j$? zVN4y@7AXlr!@^7 z06ZE-W3&oVR-2d+7p9S3M>uHNhK&mJH=}8EP)lFHsyS&T{OsEZF+hDu*9FzJCkCQ% z>7&Nak44hfQ2-(v>ZXUI{a;5HPx2m_78Jmc4xv;Ya~j&_{b+qG)vPkZp?j+INsm;I zfK`fB29vd@*GW{3;xHX!xF(jr;QgiKGCwhlc*<#t8LxY2uehMV6xuk3- zjK+Va=;0o}xl2_xuSP4q8%U|wMRa1HG0rS3E)RE|Zf46a;D9Y!2C zUvA{KYVXU*ZdJujWkiyVao1*I;Y_fU9b~(MUfPR0iUS&i8r#$Lf%X@IElZXxZg4dU zX2ks2`V~iGXd{^2+6spVE>_}VWWr8Ra{C{U?D~;>qR4D0muRTY3Qydk@k3As8F9#l z>faKKaW)e_3tSmPxY0!V6p|_|$KB+Xd6c828RnCW@`fF(U%&R-7#cnT*xcuxpUf7W zDq?(b`jq%+kBg*IL7`L#8O>*@N7y9jqC!Y+CPL7_)uN2=tl>e+;r;56!9Fq;MyLcr zdKQX`ZUzH#v+u`#^Hg{6v&po$F(l3l2s@CP9=qI%s?^bt0NcW7HmwuFoyUBwo;n0^*`S0=v1|*g_JEpLD7J-v{`;lu0MtN{FC)N z)f^Tp=&6))MGSY#KT1WB3%4J?)GbhRizziqSWX1a%*j#9#Ygdn1+|jTqjE^ms+oDGcuu93~NAn)Y~3vDOsE5@;!N^~k`rRF&{n-fpURc^>DP zPMxDDwFPVuE!UHsOmIqpIVzV-%`zfbrkzHNfqcDwf4kiMCVF>XEkKgZZhteZ z>(Jmn-r^S$f1oQ!vWOn0(MY9-nWySnX5BRRwP1027~1{|&F~N|(N~B9KAt zi3V%)6a?bW?rlC7IR8U*LD&_H*>It*^sOt{v!Sw#&mD%#bfc&{pNl9@vNBNM`5f?Y z0OL#aL-T<>j=zT`j9%Z+qBSFIj%jlQyW-*-*P;f~& z03L>X;xO;}3d-C5;{w#l5nAJ!^?Rs0x3}aC0D^zcjo#U17yl;tEv<}2a=q&L;j&== zSD-ed-Q#9BAL3;}UNX}$zQk}l2t^ImTw%;xSOnXD4vxKHj03X`!iP6Z-}=-XupfV&wn%)1{NC8&WaT3%NNc6+eWXV`k<0^f19Fq ztU^SUXxajJMRnMyG4HNi?zQTr)TOv`ly{VXAFfKUNccQgDm}}zyFG*!o}0e67VNLL zOD&gQkgk=t=O!kyPQr;(ZA3WX;=XYpJbX*B4CVYe+lKgypJYgmm7IWuCyi0vRTV+Y zl94-CX3t89dX^b1QH~d1ifI|$$}*apk<%FtY8BHWSADHgYFb#R5VrKZbcx`&g8^MJqX5lscuU#9 zd_MZNm4BLgCNIVp#gA0vMwX{XHz}e&g9X;nk1Hq%Owixm?TpCl?;T+Y)1oZK37a9? zEjwu;J_~oZxYGvLh9JrAyfP1~h1vU^{d!g+9D6+--=NM~YVzYr-uQf6q#R>FJw%{E z|G=r^?hf<%aZ;kSH{4a@!1$Cc{4YB!Lq=ux3(w#FtJ6y9_(2Z%Lfjg3LTUZOPnniT zBSv~oVK%~Vp;_J9o`uprq0uNxhche7ZEeC~*)ECz+Ta~;z_N_VzZ?lNVP>ad^6B!a zcu#w3qZng#J7LOqO5o^i@;S$K>f`#7={E#7O!Q9g`|DEJrDSwedta=o8+m1FQDnJ| zrfp{Ja;7zTl|>|YeV129>oglFE!js^fA>_jOQl9iYAnj&DAKAXshYN_n9?ts$v{~a zn=z@Dqtn#T;g}chR8IB=VBe-P1DIr(C{J)p(RJ@5eZHDrDcCWKtdqR-?ghSi|1z%d z(*ZL|VuKvCWow3NWTMkrjcqZKAi2bxzJJ$HZ8uR@ZQEtlvWMFM5Uv%Q;q~%7T z;+S(QtDk1_8Xjq`QfC1+Ofw5s_5j}+-cMgCf|qdg8hXzl?zVprp&>zUhfcvD2SGgP zRx$UBtm$<0{jExsF) z%ll?9{a-fwRD@of?1n?XWpZdp9HA*Px7HoFxH3umog~|B4e<%y?U9Sc+gnWVspFgy zgv~X)uM+eYc`5zKGdW)K<(-+nLu>gL5M|eyVBVLADQNi?Tq8OX03cRu!cZ_t1}5dG zKY}7xr7;xI#QG$ncEqc{=`zvfqDB$1dfESSA93PdWEpnlW^!X<#{bN#lm(W?mGs;< z>3Zrhq(`}s_Wg-!WSM}W?M7ezCx1LGl@><(5re$OjJeuTM2*(!wHq|Kso6qr{3?lL_ z#h`t1YEjl}>pamLiPXD+d$k-f&i<+rMV8DF$h_lj!QM;s9-Ogb6sVXbcviI2^MmLr z1&Zbs51MQgj!tZvjOiqDlyKNZ$&)wJ#g1r`-?#IH$vS|2o@*JB9A!xsPpg}?{xjd{ zrhV&UXi;ZqdjmTakda+jsR~WFlS_I9*UGWl4x~{EBdKO?OQSW};jJ;zf)hRj@*x7h zyk|D@Az^m~in$bA0mFCWQDpf=_d!$xDMjV|8GCY$TuS^0RJ8xGNJGZDVVI@dvQ$7UdWcw!04UEq^f6N8j94i+> zT%c4aN4}fWV}|FKdvjd)nfQdom=sKBJhdBtY!FUAoYxQbk5JC;R!Vp$1a;kriCbYi zdnEZ1I4p(P?m;CXUrZZvOK`;!TQIMMaVtE-MVPt-@|%wco;_o#7HlWoUU+@L)!K7s zhYY}4uhbK^j>11FVnLeqyCw_aIQC+9=YEIr9AMjFB5*Ede&y?o*|$vUO{DCmjrpv9 zFB6V#eaUL2Ab#Cw$yBz?0|jDBuDjf@q{g+giF+vr!25WhnVMY~XN0VqaG_&IZwu^Z zd1NVeNyH%}e4z3p*^!+)@d^_eW$n7lT{S)oG@?-KB=vY|1l0kVomX3aeP;Qba6Ti0 zi>PxBVC$q`u>NMu5$Zd=!~7>|vT%anwSQNkQ`rBD24Q@G1@p@qf>ibY$4kjV2Y(X7 z4_?;Ymsq7OlrJmq1q0F1VZ)+I84z@#DCbs_?8R7eVLB z$XRDQTKApGd4BmjXZa-_1=eqUYpeD*@+#{l*&N(rP%GYi5cgk8S-CP*^oKbl76%#d zpGah1R^&axLEmRkejbdieuZl#)OWN8bF50z;k}2-^J+ok+M2xMj&C(MBfhMDJtP_8 zIHXnbea8uQlTE<7I)1&1Z~|OtqEZsbu?aULQ=bZUxOufK@yHYcg_#~20-C)M+=?Pk zO$(eAY+6svCK!o5KFzwaFgCV9F&U!(EhO{e5}Cr92gX6rWPfsxDnDgT68w6d13rQ} zF6IIr-tPkit-B3vLa{Kt#$WH1B-@`jzSIcv0veKSmS0m&h3*{vpVApjpj-fogi#@1g!AxM=sUMxzsxF`rst&?C-(&+#_KVf_vHJ=Zu9@kS1(NvV^ z7omcEWu4}>hCh?bdec07OdXI!cSH{`GDEjdrr%@>c&aTFZxPh$MO$3FGx^5g6}R{* zZ9PtYRl*BO-zLQnK)VEP1oy*M!RxAJs_7(5%xM+ToS_)&8#_j3(&~HZ&|+^EMoueh z3vn!hLdxLjaxSv4GFw-~Ls9|Kwza{1?~^NAFW_H7d|}4US>OxZ(D$Ggo1MR8e%bF3g@S^wd9XX#F%}y{K3g<>j#`kTVG^^TRCwRP@G_GP<9iB_s zrPRveS^~Y@MQkIujiJN3>$qvHV#%(*4_fD_AOo~{w4`3l|B5oog_;o$c2;x-DLA4_ z0Ry0Ye_eZkxyi$XAsw1SRw?5Oe(ViRi;5-U11d}~%qq|bF5{N6sy#Q}of0ZtPGZHB z^o|Pz9%AN0B4nr4=&iulWx9$30X#LXBF!r!8M^p`^+gw?uIo;HaOH~&TTr-u0=e8?rOqd=P( z+M{g>##}1bxm)c((>=0P>@JYoLC^H;1;up9ELE!jLI+AI(QE>%7hqZriuX*M&i=L9Xii!AOfmpjt>YT0QM!FMr7+v~YPJ}i`L9`0$s>bH zsGp9MZu2`L#9?tn;h#>Bm?si|YLRC>Cw{7zh#jvT1~^PEplaxDSe&yNM|t`@OO!k` ze5sq2my{0=0q;<;XF7=`s4HSI$_pc$PT(}S9+=#BYU6CWuZlN1%=}TQu;e|j<{Tq> z|4blb&mM(H;N4lZ!+l78;l;b@D=2hbht)z#Qx^pWoF;TMXrHN~g-SL&8!GBcK}aB8 z77aM<$8uC@=U+$<6g4VgKjerFLNZ*N)AOs%Kf<(T*Lx3RVwjHR zmy~r5Q9(*+)hQ18#XlSJMXluFDBkI69;tK%38}<``Ib4+PnGgI=nY2l7^ZvF@&Xjk zBrCKt?Pz7$RL$YZ1e(elI$vz5So39mV9r}uU+ePF@cw~&ZQ(M8T%PO#|2)TIj$G#9 zOvz`c5g@`-cD}pL0RKcbRQn#I({TrTU-sPgip)%T0>h+__LvG-?0%qQEqPmK6bz7d zpWG#1Etge6>jZn%)Hy6KagW1Fo9yPZt8_X@1sSI{9H)|T zJFrQf=ioS7HUB@;uT?eOQtsbxC}>dsBNG~`3ZNP+_0BDtG(S_jXwb1d?Ikym8FmugA5`GKe6NFiDN@xjJW@k}?*!|coK+Z?v7^GhMa-``pz zti!m*$A7hH`6Omdh1#AJwe!@Kxy@Cn+lRw6AC=POQj9Q$lC?68d_N3WrAN4JGpu@g zIR^22`X$a*mAHj!&3UBnss8&-O{_m8rETKrIddF{74nzn6xLW>8IO712?V`jobu^_6rxfguvz(GnCXYTh0&44wLqZ%*gyqDM0OG;+vVUck}`k5H@-;a`n&>Di-(WBul*-ESRkGV zF@5eI{R(C$@D=RmG5f`hzB`te+V&IgG?0gXqhnD^ zCVjQh(zfM*5b@i6NCp?P<4hcEm-)}Q?s)DSq}x$Z0;<#EVWkLAunN$xJxHA3WRqUt zl=~B^jq|O?YG+d^hFn)fOGjAk_w))M=RM*Qg1QN*M62#4n6C9UAodwU0J*>(QwdeY zihYNuDk6|(UOytD`X2Kc0qMV;vyTuBg8nxaBL6oQgBnaAEjTZ{1=No`GFx*A89N?0 zZtSR0?&5G$3M~)*(Q6LHLI$VPt`R$OIHwyzvt38 zJ+1ohWpiWWUAL7r0%GguS_=Migj|IX$cOKC^G_Dn?Np~XvJmL8>&s#UR^VFQ?|`*- z+tb(ieL|3e(n8B3)$3W-8Ca4tZL-{Bb(-uuSxKU!4UR$+yCPDhCOJ!=qr7tKrzrjCsxyw#*)retb{_Qo0Rok;G$$4P#lxj9iSr&ycbj zJpb1PtxDeoE6D|z!n6nd3JQBD0|>_}sk$Z3)tT7KeZ`)q2>iRyOH z38XAvZL9d1)-6uQ{{weGh`&T{og^+*T0{KKa)yF-TC)V^bvZWX?Q|yEt>(CBuCCep z40BIUI;$CZe_KFw2%M5Mbb7^(Pf^g+P^RI;L|bDSdy8rfy2@*&Fck#plJnDg+P+X= zRzu_V0On(XAGKI0Fn>DT3QiU9X}WC=#WfmO(@?${S#1Fk?ZkP5h z48Vt~e=1aBLjVEHkzbbxwEZ7YSFlN7*-YlRDBI%4W^@GL$85Q4X8?0CPkwa^EFt3i z(*t=^qxStn>+|*?5tmLnRVaWey!I`J3Bh3WCBHdw{?{KRU!of<+Oqx zfhtBS&gzwAsJ6@a^;Muj?+TZ~ z{Yfn+-K-!Zu;_$>ZFxo@tCh{`OrlLHt8pr18=;(PT3U#De8>reXFgWXplR$=`!ZV5 ze<0Hj11xBB2W>mol9NI2wKUU*{Dd0fl&pP>!hkG2tENeuY13o~SI@?NT*Hbh^;_i| zTqn>n6WS*OP}ZMUur4)Bs@?86Ug^gTcoi$#xML@YzJ}MBrP;+CVg$-yJ7KA#@O5~- zAFst5SZ38!YGN7)G){tiIn~u}=sHi&e}&XEq4v9OVIhAD{cUPj<z@DOvY;`Ik^O)sjO<;EKq-fo!0jnd$eemn(a%e-I}fTt4W@U74{b9LiPkh z;F0njigJ_~G*VksoiVXibQ#8;d~RlZPY~=G%4sid(%o`q*~Y1}?P?|y=fy^_f4v*G z`tdH@HqVRO1u6-r3=i2d1utcEe_nSY72Q<)pqlsMeL*&6?oghY0e$>6A=|kFrn}bD)O@(|tI=Hlr*-9D~z3?_yoe zM0dDL+f6Mck;(Q?!6yhS-ldyae;AAE1$zI7Dt8i>OndEq5})$pPJCKm^$Xg;&C<_G znS-VBH~oGJ?jlf&u5e4mVaB4!*s59<`?Qn~1@>o?x7mNarmO zc|qA!l;`BsSpu8kaf2a-$zT{p` zrNsd}BGZ30t*GhE3ja?s>=@S5q!;$HayBpVaNJyv5wg0P_IQBLtA=! zwuXH8#w5`R5&4$1``g^mmY`#Koi5nl#rLWhxbG998#L9_%uo@cKNP4tX}h7|$JDz) z`oo8x2xLPO>uAVeZyi$ge^6Stv?N=OP;%Tk@?J|7Z-NkoLYti(Lgg9R658s#hNPG! zlPHuQKX$yuhoAAf;-e#gpUYD|hF>r`(gMRwU+oy+!!OxK6i?*ClL0*79`rZ#x??xF zzbo~S4qD08)~-?T2i_(O-9|mhhm|QoQeIZvRV#|Kbl{)xXFvXkf4>MUcfpW0qRByd zZ`<@TE1znn+FhD?{1n~R+p}pm+t)>1Q`Q&PQS0CFbQS)Ff4Gg$h9O(NOvc->X+#=# zvf2C>o{?~QR^Zf=S*+kVONr(XJ>w1d!iJq2rmY3fW6Y1|_+&!(gvRxKj1+Gg+2Y63 z*<42J$Y%4lY(3nLe_vEgsvRfqz$H?J$1i4yO8($X`9tRfd8Td54$T@bcmYu*i_9_M zFCEWOwBEAhBg)V>nkJh85nw^+D3;QYCV8!)UOr!P+>T9E@DPIm0`i4dc3hEMSQws@r#U1^0HR$6V&e`DFF zPw*kLTVNy3^7G;2V zcoemX&S9KVz|s+%F3{C9f<}Sca2`J*0{0`DNOX_jEP(>n#zt_SV6pXy?gN<9>`-KP zha=4eT(slB*n{DNR4YUie_P-gLl6}TY8Ad;@f^Ymf1(Q7#%PPj<&xq*m|9g#g88_( zXy6$%SQ@w@oY=K%80(vkpuPDBHjZL*qO)ljF9{z(*U}@16>!-h$iFIVL%b+`3n}TA zi$>9#kQxfOyi;@)u(P{>-4_4r9;3&QTbN;8o#a z*!MX~e`fQcoTV3QoH2+6&bSbD&bS!MoH2ycopB}3az@t$0f;e@^oT-UjeG?bO^h=F zf@4$oFg6DFj^Nq~`nATPu6L+os2Rl#3CS78tB>N1@|+cpS}!V=Jc~J^ncsd?U`IIfipbF_NgO+&zrD3%IwswSX@~_))+Y zV^UA6ClY*+d)!Z$bIqYTPwW6f)cKV}thiOHM?~aSV^4}!&w;VWBM-rIh$}7+esy;N ze_y{HYa_J2y;E+~75wHfzH=BqI0k?4M_dji_|sNTxT%h@yf^r`yK@0gM1sHSbe1ia zVv*g!U%PVdg02GyM-Jn+$8fQn4*s5#NAXw5x(oj-;NJxyiYuE(#Vmq9+%zn_1)=a9 z%?07(P!O{Zjfy#mS}|`}1n(P**vGioI4OUyAWm+RWf7^|Fh&i^r)HcK23T*w>`5(E)~;Cv!$C$;1W zfSU+`TPb}PtHYyAiYEw{r-%sb$BaDR(T973m7e=KnD z$a8l(ZTv{SqJq~@^I9*xoy9Y{wo9t@!&Z-s5?`5#bA2M9B) z4G&NY0012p002-+0|XQR2nYxOll^5+e^C%Umjb)}K(V5r_{FMF61E$oVuQp4rNBcC zq_rkKHMhId?b7|q-Q5~u6=lk%9nU9$l}NdktEA(T^;*d|CS~o8-F8B1FAAs;MT0EXFexy5D2LMW zW$0S_-9xfd4buV(+x4BTcH>27f48}{-Kclkt$MSwxBt8@P;UHYw9=8X#{&AM?R%k@ zJ`u=OR$mIt|DE(S^L&SthLXVa<~X;6b0`)tgYyFUjHOlktWC#-KUB4jl9U1s7X^wg zr3WhFdD0_+<;qzlt7oASF5z+kbC~DGqh*ASfcanCpPISE6$WC%9I=!N&=V54iIl7}IimP9XOKP)i30t*d8B*#Q6mvXhZ69g`1550l@d z2$NuFI)4x_s@=G-6G8$B&Ti_q+0wL1+Jc1GgYYOEcmN&>;eznN^8eYt?XT~TPXM@p zset$G_C9@;8R`wWTrQ<9(hUK(Ob(PRH)8ak}HiP@_)vaOb7CTZ!u5j=krwMG|0CJ2m#ZF zruUj|j3oi5jW3hZV{R#V_Sm-Mlhv<$`ct=P+|jij|Bhi-z~LGPOf0%Gxy#n1yBPKb z#PmYC?|5N!eDcU(4`LWYuw?=VV+9fC9f*DaP)i30LH+M{_y7O^ECB!jP)h>@6aWYa z2$NlY5tFECIDcAsd{ouF|NYJ^cXBg8NC+@2GD47SlL#te5HVp5BmoIahef=Zxk*N5 ziL(UaLe*-mt=nsDD{A|!wM}d7W^oct743rB+EriezP#>>-B+vTeb2dfl9^-z`rbc} zPr|+ToZs(ve%tvi=j2PTJ@y0A zNYqG267fJR5jHWNG^3`GGBMd}qynK{Gju4GiKP}dbsN!?S--fiClE9G0uf2$ysni- zc;)$kO|Ht}cW0te45WIEz;b+=@t#QBG?S5d4@UdVWD09xd{x6a4XXlSvw!h59%3fF zGm%M#%zurMsL527NcJ@LB#m&?Y&@Ja`ufad<0kdF$NFkFB5{qJOl6lF{YGQdi1##Z z>$=Fvox8brY2`h-Pe zadnMFBV~p%$w+#jaU#rWFL`O2PNg)R>5NmuYJXJ5Gz|-_gR(4%nHEf1Vtf|F%c(-A znKX-O?o?13&1NbE*|tPT854@h5sjPa#$7wwKxi)cbeco+n7sKj8ZBUQr4ze$v`#{6 z1=<<3NT-G5FGOqAXfaa>*6f6j#30739BRI{y;Ma@by`Aa!7AM_u7|1%tY*P!RLkTx zuYbtE$CxUs+a{WIbHr{#1mQ~Bh1jaGuCbi(q;F}(mpjsSZVT~JErQxmu;;$|9MnDYiT+>ub8w%+XC zn8?J#8w^1O7y}KizBkw}0$z_g9+@Jq`ZA`q+S+T@xGVH=-G{2HWA?SRrhtLdl4& zpYmdE@Lsx0@_8&5wbkm)$)quWh&=V!-e&R?QdRshMtvhUxL5JjDao_D<#w0Y!5G*Jwg0A`if3Z(N~#7AmE{| zGX+j7NOL#Xwd0XS-;^8R_3Hcuot~%vf{cN{zDw5}sPoW^_0efgdl{kH#t0mc2(RS20mV;q4%03xU(;z+rq0q(0@X+)p4w^- zc+q5`e14Dx)0~N-v}7XDFfuQrrQ(2x-8#EuY2%g^RewAT%%b8?L1wj=OIQa9E=BxE zC#*>?PeTcVL9|KJQ5_&G=G5!uGWsGk!!woEp~k)_iaak@DDyIUA9oa;WV%;HgH|uk z<~gtu&xMSMct^sn3%oo}YWOLhkKM26A&c5s@nd{e2`}Ykx!$G_K;s&nYh{4tH6E^?B9KW3=LV^l zMkey`a%ihBGqDP^Bju@U-CQ{3bNF28H0L3GS`y|LoP0jhlIp@%Vv53$W%BdG&-zi=7rJm29k_ zpyp`Q%l6R5u`04bR*?;=isa2Oa9~qLF0B=)v0p^Rj7G+8>(#X z;O&Us1#D`(!)oPH*dJq6@5B;EmK9#!$-7G6iMz4cavR>uZ<4$H0S?M2nA#BQlZ)-c zE`Q@%MoZ#MMXtpDx)j?80|zH%mpo|<34vB*QC@+7vZu$0s<1ZR>M-KOe2Y~-lD9vW ziKZji$bPH9YVdHk&ZZ12i)^TH!c6&POV?}kn|>ocV1WV>oy@W+JIh@#%x2i7Es;2s zfu;^27_Q&2v3Xb9&V!qFG_P;laBx@WhJPIgH*ag-;N=(!SdMbsIw8qveu6yTf8HS@elw%1SzJU4`|x0cIx9d*<99)18MK!b4L1{Y zXo>wEo$uuLVogg5rlQ9j_EPI?Nq-G1yz?=>y9DUyaOM|5T8~~dnlQo|zpuEb7Ne>$ znx5%#GkrLbJhU?sGZQj6Gt$`y`2G^UkI~l50k8d#Vsg-{tDZvEVr>t9h(E0J`x$M| zit1ugTW+$t2yUyTypKxs2g?YNX-?FLb%l+p!h@x%vzcxyN_&FwRu?;dI)4RAr%?Cm zV#XiK0=vEZasGr(F8<^UH=_+(Jicxu-k&&RHnu5A+Re1lZG^zvfW{9aFvP|On4ZfI z3^pDxdJ|zQGo`Amz*8jEO@%0r0seQB){>{jt(iQ#&WJ`kBeLk^l8pJzI7%8hqQot=&sdnIJ^6O4}78;-~>u`6Ts zebXl#;qx>6tPC&ciMi3k&%xoNMk?KEHAi0ls#P?84b#xoH&8L8jDK!(R}xA1j44ji z$4EcVFUUZFW_DUS(cHPNwKZ4mzo-tc`P;|=?d#9;@ON`3rDGQu?Pe-v^qA`-J*F&i zzi(w|Wt6zQ7+F4bhAvJ6{QQuAr1KB>$4stWJ2wVac^Dn42V`3Y(lUz9E=F@-iM7 z-A)hxdjh1DYG1V=UjyWokv@ejNR0`$#uS`zSYv4L=9x!A(SJ-T(ywmYnnNL|u-%A5 zizso{UDA=D+3K%cpA>_#ip zYsBMbG^Mn<&ic^AS-Ja`Ng!?DM-$adB6-*&YIU(xwtsE9RF(zCbY^wljao7KP+mYZ z09Bw9)zZlUNmNFYsqo}Hkd})Tx>zR8VOsrva6?VVc2%AJt&1j7<|XoAJvuPH`LVj1 z$X&yT^TjG%tP~d%^lUqOVYRR(RwELmqNdp=H}@6^zD8W6iwnitT(e$yv7?D*K!)I% zUa^jzm4Dv09$K(3*1cjQZP!JO*d&YNNS8;nqA)Gu!7YhI8k^ndlQ~cwl%eLr#@VWi zHW@WaqKE}jcKB~i;ZBMhF{zcbOceVj+*^tcu}wPY_S`X$eGROfz75$&>Tid5$G^0Cv1}(#+wiv$9na=8F^wpX@757Q{ZK<*r$u2*zYC7db?E0vaj&w zdJ1f7Ghe2QPGKPXARoxhWf^Va>99451w$e%Er-ojnUc5g@T?>00(R$BPraV#5xo*! zCPrAS!9FO68ku;g*Gx88rHizeM;wwC0;U~dmY$~D%*C9Th)X>rJmj(N1g$!c>EhE| zSbtgs@<}GmZh1RlSBjvW6e*obMY`bZun;6NM^1G+dY z(D}MTa<6&C)za@f#WhSD#v`NZG);9|Wp|f3ZThz~@5pO9^E01)p)1~u;A{6$^2*C2 zu9JUFQRG}V?_g5A1zA_zz|`o6Phg?2|9`L%Ndrhlu;J!C?GUMBD8ad*Pi;Qe!``(xI?F% z0XK+v~Eleuy^L zx5>%2M`;Jsr$=aK(D^uN!L5$E&hp*0!?bsZ_MO-&$7_e^vJ-?#g{D)G4$yq6qH0=8 zLfk3;WQm-k_!Jtg(P#;=Mr%g_Xn%b-6OED%Tsei;*+2lq0r74{O)?MH#e56ib@{gn zmS~y}Lh3}$hidC`JcsbxUEW)Md6wcsbVZiZ)=%3A^#}Lw?--&Z&PV8K*W*+d3_8k> zb~?+i?aa~*<#mtH+jFD0VDvUQx+gbs2S(m0M}p;d0!2bl(WwAAf9ej?e?a zz;XIWmOe2=pB|#)Ba{s`xdJ}t5Iy=RonUHm``nMx(@e+sS)WV3f0^k?kZ#hl^tEIB z5uaB64P}a%BlJ9QCF-{ZN1wy^x3l!UW8?#x1_S=cryb1FPqXyvCfDHTLzw@qns1Qv zWoxqZhm{hr5}<#!Kr3C&%YW3{kFxZ4iF6o9|5QkRiR2sy^=a;Lu^MfVBrUv;@m3bFX*ZQfs1gNrqt7+MuAr~vU8Q7r)Al9|7*v6u7668^D-%FrANuy z)4=Kn9G@(*z2Gqffw6R~N7=i4VSJOwE}Mu~wpFd4YUC$LEx6EgGQ*gB?Tc zFTW$pOOA7Omg`_Vmt||(B;RtDc2{s9%V!5yYWEU!gU=ONUb$y*^m%+#YCgB4Qj>zX zotH^7yAN8kk4Vq1tAF5CL%e#Jo10v6$zb51&o#vBv%IN-TeI9|t#FdO`1HAl`I0?8 zXR!Pz#=zH}uY!<1*(5X^zjWz8qN&fil9t zAekd<1}nH{hp0)Lb%fs^Y<~~b9_I(J)-ZqM;1GYT-si4+j7Nw*l@~1QJ1h9{T(m?qQ!$Zmrv;;Q zKWSDBR6qS1-LKJ88hxJV6)khH?Jw;&wCc&%l9HmV~fPS6>8b!b? znTiI>`SqkvHE;b$pgB_jAtYM>XP%1FQ7R?(*fd#_a({S!-mpdwstM41l^P{?|D=Ud zCEPhm+oe8qnKLFKa3|5304&AOt5jo6T+E{s%2zbsAX!y;=OUS3)VoSICuunn4T@a+ zzXVeaU^ zR+=SlrhiKDeVQ$PM{~r#X|7{7`5g0Uo?{Wschu7Y#|5;|v60SjTuO@^Ve&h!q%$2y zX|dxZEphybs+_ZEsdE9H<*cD)&Hz^A$}U}9Be<%Uk-L4?W%1%ER)r~BMZ+8|9E3tn1%5LAZwTUq{2lc$2eH_Sg#8?}NF zMt_;*-;VH02(r$V*lK^O^kB>UwX7=3f46tx5dQ=FPp$4fXzj!%O-3xwaef(u5KL5> z)PH@>rV`XDK8(B~N5maIS5ry7j0locy`*%UN5_cC$StXO=+qk3GFjEGW13gCGHwe>?{dRADqRB)?IBWXLmND--9k`S}T zurVEM&x$#B({d~9Osmg|d5ST=3?ve__J3f7Sdbs1WHjM+?id#SS>nuCg;;W-h%HhWDL{=Sz<=WU z5z!WG9}?~Oz9iUwlFI6zaNb9Hy<sdh|b{tt$^5>6?@tdH5UdEG>653 ztN^=R!=k%3D=x1P(X8mhY$;-D`I^oOaRr7mV-+dm>#99jadf;;ZFAHD?Akgz_Dy=fOWW|jY;wEX{l79kS*VfyL8pHDGu!)s7fcTDa&@q6LDF9T>Tp@0+ z9TM+6fdJn}{f>8tTWNr9QqNoI9{J=K`G?{HB#W2$uj=_Szbc=CMTvTr2(PHYbGn$R zp0mXw^;{xq)U!owav-paP2v&--zj#>r-L1(>N(9(rk>@FD)n6ESSz1)ihuek%^gMM z?a}yz44!-+D)d~qmHFaj(qExjEYnJH7!~kerMQQNRCbz<%rOO=0#PA(HKKPO5RHN0 z#lvnpiA*L%`A`z%X4yt4k_%+U0+lt0^`ca!4|`&k%!hJ96H7I*43nCuapq<(M%0%W z%kaAt#6-&|M#eB|au`d;Fn>JA7i7`0;bqG*f&TdNyJQPw@%4&g_FvQ~^Q(J|hy=F? z&6K^4J(?#$9XT;QHX&`H1SA_sDa$W$Cl1LjOWdl`UOz3Qc}RPUkoKy;@GEB2C497Ec3A?>vy?cIVkh3f9`zjzOxUSb}GZ$8AI=7;_VP)i30OlKHPf*1e* z?J|>r6C42|lhLFWe@Sk0bYX04Brz^yY+-YARa6B40RR910F74*d|PD||9?r_dz)sj zmTt=!qm&K0u4%_$Wds>-V550cZy#S6;?Fu(s zeDTIL@2>B)Vi(w{czvWk)>q$DA9Is~PQvmWHx*90ahvODJ7HTHo0|hxCL9~EV;5wy z$xMBu&q`$MruxDDaMBtKJHlgiZ>tq=J(jfTHO2FN*+ha1nE@+&6j3|X@1$%y?WFp- zy4_A^D2wZBf0~bOUK5Vn+w0$JLMa5g+-y2#Z*UT}!eTew-_oD9;t9KDN7@=3w9_r^ zsf=eO5=)OVP^K_1?z?G1SjQqYZcNB z6ZM`7E2=jW%eSoK@^gZihw4g{qc(^Ds^n`y5W)OcD2Q2@Enf!*F$Z(y>ktKhgPg0u zp#d1Ee^V%<>*>FP8kToVjv=iJmKtGTslu#&+dJEmK<1-0w|KB@dnv-T1k7d26=Ka3!_<>wb0YzgH&80-0()iH=ZqsB8#K2 zN~9f4;# z{S7l_(3@E?!{Ma`*d~RBzH7(Z0yrIKC>;3~4;eU<+U5yQcawC$S(1>QID0~w=(;H5 zf7wX`8|gVa&3j#YK<%@srAJ+DD@hGDVRI$Aa1QTypXDU7Y5Pq2!RlwqR8N&K??6LK10j7MVogDNo z>fi~+qUZ@tDQk4ZyYZd?-i7y)G{F@SPp8dmSiWU)&3GT)FY-RXOEPKCzz2(=f7Gnk zrPG#{Y2ZTvTqZ@tZ^h%2Vp*tQawV_8hlTD+CeTC$4SbZrbUd3eaG8PgCz#M)Sf_Fy z!^f*|6|Sb0Z`?Os%DQ?+YDYf6i9iq**nb6tPyPUxenG>c<=mTc(;2z}Uf8a37>UhA& zpoK%msXJr#VE)eCneRXOQaqZs<8H1sXY}PWaW9dy&4Rt1)uw*>wo|-JL3{`I3zzTG z8%3>7$@cZxX*<5rwsht82J7aVbeY7p#UDl4;0Eb zZ`u%EW8y~&jpKwRJf`hxe~$#PA3v6ocHmfErNaJC0@#b6^1_fyyn{nz5RZ$?_TmYO zjV0U+SAHgQ#a{fpcw@Dg5|96K!p5e7w7Vle3jT^tX>+rQcwNf%>iVQ|)$vXZ)UlE= z=YPXXGexEsQ_a9{8L5obXKzlkkS=MMRO2Q`=^6Y!fZyTSNwY+;e`w4&OFSnx?~e+q z*~Fje4mv60rXp1GFVgpHuh5=?_^Y_**Z3P%b2H5;PB|w2&apvKF6~l(k2Um&w=~R9 z@;~r$fPL_v#hRZlV{#+tzJDwDHg_H9h$VYG`5(MmiC6GniuT+NcL#e9Ulik_OR1+6 z{Xe`Oz=as2Av>H@f85=XF%{nkCdX^fa#Aem2bWsWHejW@>YJKY^qjr(|C_dX5-Q;7*vO`o?U^bCPz6Ehh!k$iWoy5;(rkuX8fgr;aa6Ctk;PqW79jf3=>0YU6X8N_2UA(VuAzZW2v7 z%t)c^%qDy7v|izZt(=n~ZASUrdGcrj2!jR42b+d`u4%~U9RMHcYj6;slDq%v#!)Pbb~FxQ zVGhejf3YIk*fWeKjjqh$nCe#k%i*|ToG^q%Ih?!;t5@XEwhPTXGoQaj(Hu66pd)(b z5Z)f`+=q(Y{y8h|KsT9e$-&AY-rX3DZY4D-7IqF{aiomLBIQF^5{*YwU%PIf~1ok-#u6 zzqhr@-x{n9)>eHUhlb4B;Hqe3mR7nd6bSL_Bi)w<)$XyULxG4HGVjDS3i*#uD(u41 z^0iB`Z7(A~>VLC1BoyeW{_HSrp_zGKW7E%=rA73;mL@Z!!JT+#Mq5aaad(Y7Vc|`7A-P*s-LDs zBltrOf2w}|fLXbwpM;d9baqS@OpPK1^8R6ncZHJ z2&zi9qmeQRaP>$O?d!qgt z73?ajQM0?sTPt#EUTsBB*RVP$rxr48a%#ygWW*7j;)aM3;!=I}!#(ubqalNie;8Fu zNjI#P(Vb6{U>_Pn6*cO}h*@?IjA*3NA2Pb=?#i56!C*esxf^r&TO^ED@?(B@M78D= zjen7t85S7chr>c;MK_iA)TrYpWkyruikw>8tuIiV;O(8^+eg*OQMnDnYTbSEosVse zYSU-`RHIHU1eg0*g=_d;cn9vnf6bh{1>VMSTHp{zRDs{cehnYO!y5jA1Cc-(VFdn> zLx#Xt*_H{}a0437VjmMIokn22I!?nA)kY1IYEV6mr__b&3JtGRS7~^)x>3WM)QE<6 zt4B3_R6VAi1=JJj=Nf-jJulFAmG650Y}KM+K!trb`97y{fr8)S`;x{5e+qu9Z;!?W z3O?c+)wn>x@AciUae;zA;M=Ehfr3Bi`<2E83jVb3IgJYx`~}}j8W$+|%f44ME>Q6Q z`YSXpkhs6vzd&#eiNmK(W7)kNb^pUT29_DaaM8!Sicc`!mw;8JCHTX#-&K#%VR)Go<*wT%b@r|<5e+_YYe&ZD!HpUKJ z#y(vjrkcE zBdGc@OC>Sew-$4Jn=sdR9_IOCsP^@v#&<5=K#u+X1C$Ums%`1RP~ z|36Sm2MA9re$T`V1ONcC7?bg3Gn2S{F@HVXc()3kx-R0WsCXlYf+8pgUZ%U#Z8Uoz z+13lu2k|Yu5Wx!{z=slNt0E!;nVCP|{0YhX$Lkw_4a^8UK0KT^?%bvfZYT-e9XDvX zbvH=kOlg^`H1XmzB-RaSl9qV0Ev*-{DY&tn*t$C{sV&vrEb?NRd8+W(Y;MVLYk!+r z)A*Thb+l%|wxzemEhUjkh>S`iR=Z>@pT&A(b$zwrh17NLhadzh7iq@?bf`25ETks# zBO^mi{;iQ&M#eu*Y%aB)|IP=+#meXx7{8WX>1&xp{#o;yg1n4D_WK$?N@MmLJLxeh z^$Y)97Fts2j-gYsRz^%rocy|6d%;Z0(xkvXHohDP)i30lnTR?YLiWVPJg9X3w&GEdH+uIxRR_qY{yAN0=cncVoR2t zgvJgEFUJYsSb1RQfk;ZYmagqfBwe9<700{=YuGy2*3q)HNmpQW%xq;{vw<9%LSXBF zveB-4cVl!L?H(;%JGO3v4ZQz%?v*V&GIU*j`RUy6obP<+JKy*J9>=e|_r>Rk=zl}v zPC=*dzI$-%9nHg9`k0>2G$)$VBh4MnX){+avYKs}`FPIE=$J3+SzWVqERJbbJUynT zk6ERh)tng7vXtwHSA}%V51oKatLsEaSM;t2dq2Eo--y*W@WzR&O@)wqDF@*{%^Vc7J8f^f6qx zYv+R7A>4n3kvHtC1bw*eee``_4Qnm#)9kTc%hGehS!{1VD9F>+elSc+XjzC9su#5F z|Dm@+jUif2^3Q-+@T?BV(a@YEe8#f9Xt$9J$q1%$unTFZL zhq;t=?U2o=+1CC(o7cNzAAiG?eLJe#eOb-21U0s`SILr-+ro4Stz|2yg2L6uD%1>z z=qC)zwxq#s3e$RO4N(hSItOl!P71XNYLc@h+sJnHnb|B*2xMCdMFj=*T*015LYkn4 ziXM`a=b%Oh#X}UMPOxS%!z$q1`nLANbFC4kjkJli*eq!2yfp=ZO@EEEqI-))O`fSx zcZhn}({+Zm!ze;Cvp5l^%bg1)a6v5t^f$F7=f}}DzW5b%CGQ6^m&{dMp=$&whP9J# z7pCphT1UOqC+L>zq<7Q|n2N@5i7laSXtg$|8B@2^ylJaxGjD4~Ue)pwU~_abbgNU{ zd7=P9Pkju`ojs(+u*(sp)2-892D(HWqf@Xv@@%xN&`*)Fr zwNt;K4L>5R6dDlJ()NKcl`*zEL`m8s$ZHw5>k>)*VcJJGu%QMK>I)jmwT}fem}>6F zwbFhZi4b7l_P1YXkuV*kL#)b;;L94r0lJA10e#zR7-PF>+J8_}E9{11L$+2#s#w2C zp$~`XW=2>0T$|*z9Onz0vrY{d-@+$pf_8l{R`__W$XA^~jap+D?wc000yV`LnW*H% zKDS^A+EN20AM8W`eCYb#_~tF$0UAXqkt~*;E)@-XqH8yD8q(knV^rsGFc4xew?s=m z4S#Q{ai;5s+J7=&nq!m=(X9lHS5|A+pD&bbh|sm1LMA7Nxyn0uyDdZoLNQu&c)LP& zB_Dui&i3N~B)$;yzP7{L8ImVxB1GeKJEE#o$Y?fnSFqII&tmVSyI7;UE8^sB_Ky|K zac!7$PC^#j9;W-~r+-+;Pgky0Ws>bBBb(t`@-rd2 zpOI8Q%h8X5B&j7+reh*!dM1xn z8ry`-J+1lPv<-(;O{?z0LBld^b0(UR1VV@=u8N`;aTL4QvPTk1c~vY5{T@OMubtgyQQw)>bC8P2{C#e3zDzG759Rd} zw!1Jtwr48q%k&jye+3ok0(*_n=UQ>8l*cuhQ3$aTe^yIp+5lHGh6J zX-+f3nepprUM+1zW(1Zc=+Yl4XF;<9xnt-aaM!js6bZr7WE@tAe`PlC@1& zxy;z9#ZeT{j+P3)GS&;Vx3rzoQfA$ZwXZa+1aT_v;A|$C=1C!)QC&P1~wO-oejWh zx|BuBcEHk$y`zvA7EvGs%P}B?XXA1@AmWu|bb(MsbU~D*+k;~@NbDDfu)(mndoC7B1#~!JkwQ|( z%1u7vf6It)68eTw1c=4Yc|Cu@pRwjg_4*z9h*rwl6?)&i?SDA`W^t6=e9PRwEB#*u zDPkDqxzhaMv1ymAzA;=>myecRyBI7Pp@&3Tj3Bqpw0Gm0r5dxh?hJ@As6&W(3W#G! zt3~-R-EW3PjysSRfyk?`PHnQY3Kd4&t7B!lEH&^F`6s7;5Pv;KJ*ngrZGG-4Pq(+pd+}p* zakR<1IhF90Y1=6Z#Ul8)`p`+Qn4EqiHV}P=b_hB}s`pt^QUjijp@wUtXKB~KIZCFI zB05ETC+U;m0<^u4RI?qpfUOYqJVU8P^gOj-z9p4PMjH-K(Ge(nirQlG{B^N&bTcb> z6!dT^`F|oUjXmdml!7tO=1KC3m#UA*TyVrrPI{Qbc;h@gRi$~?KFI| z2s24|WxDT^q5Oy5i`WVDMjM+)>y?+5sRFqBM#uubRx|i-= zx}}??JER0bO1fE)6eL$Vqy&`i5)_v15)f%bx};XhZ{>Tx=Xv>d&wcjn%x|ulxoh{H zGxNW&Q#2W?jQn#8PQNCk4+NH2?{jTl<`l_sti^+q4L-l=BvyelJoWiT{lWDQYz99O zE(yNlzwKdK1iy3m#TyWDdlw+N&OJTIA546G)PKhw@MZeI=~wT&z&GL>;LhP)$E(Bo zGb@g;QM|5IZ-S$`c)P0^`k4M1NGV?K84`izk(F3t@x|MnT0L#{G>+*FneRlZksT@G zDaQeY^2_r{)wTn)v@hWCF>~&dP*X22Xi}*aVpkJ8+X_U9BucCD-gz`o|{g zKg_rqpSAMe^7L=31B+NsASdX^Yv(Us;L)PJ?HN8(e!eqqmvr09ZaQ@Fr(7O7ZJAvR zqdxIGqx9^|v%v>XiZFJvUtROx%6FR`<)T+=O;2GpbV`Wb=K2lwPG`fV#e&CWh*>-Q zJBu_{Bw*58$)j>DLq3iTn;zz>AA#8)3=&*sxci59IK&Q%Ej%=)AWy{}PZ5aG6cm9( zlcQ=@-QQ@4rEMdL{W|i&%+ea14AV|?uZfU99iFNjuhZi7^!QRQK>ll#i}Q>_nJ*)Y zLQd5Jq`HF2mv`v&!|qq0y&6n~1)4Wu{cXS^iUlP>dLe&0kH_nTaG zWzOU|?6SwcB=1WQzJXj5-{P-@1DxPmH(o6(ZX4+Ch9#Hgvv8fWnGsG&0rf3+awNi# zACJ)`2KeSU@^>SR;5i!|c&f@te(j7|DJH&jhNQAve$T?{Fl4QYFeGf4b!nu3WpR_hqU->4IhaK zy6tZo?Eva6Rv9{}2dE_#;geNkl;JhDC2badMG08N{NpF zf=KKHFR~*(Lga$vm-T+4Sx?kCmL(W!u-Rnlq4kl}CKOR(<|_(28n0>7ma0`~ZIlOe zEddBrTbTru;>-cdvnhF9A8v;*G=>2Q%e-_7|u>H z_$ppV#I`S~IvfT|I!JshrJw6~yddTL=5&tEkuiNKaBG0UaGdw~2gFpVyj34*Tos52 zozW7;sk92sTRvV9o&CqZZg~F=o+L1PRpJr=0AqCb5u(Pkg&;^na_nzCh`89QVqL6F zv@39hSfU~#il5rxDs_UJVLsMw`>3{WZtz1QDJx&oB39rsoQI#_aLYBM=I+~HGkH;)B;_zj}Y2H%Qlqc?J#tOx|qG+W3mP6IO$YhsrJN zS4M$ry&qjm^bxYxzWBH|Wj8wu7Cf3lzAU`~%b zETk$$EUVJ0!pps4!sF=eUe-wsuvIba5C!#=AY3ddctPF*tKMeY)yRj}3=^Drj_H|Dv~?)cO(^A>P5sau_v@TB6A%^J0Ol2p7O9NB#{jp$YU$@<`qy$5s zt!+MkV=ryJFZBc3CCakEhkcOYwZ_<&kbDz5Y#9eOPYuHv<{qXcr?;n>TNp9T9&E@c zAobi(T%&$1RXU?pTrl16j*VSCI@=|h;mQH9!5wYA1Cp3iIOI({Qpoi`%k%ruZj|g| zv-8K+rk5===iiJ&;EAUe&#LE-Qq8Pm@ zObP~T*_A-^Xxmub>3`BKcc-p)Kk{R%Rr0bHn%M}x{g`!k6YvKRYCBJGT=#SZU5j6# zF`p}i=!3lnn?WAwg4Ku95%trU3^V?S1USF!)`y6hZf-qRRsq3;sJfUAVr(rVh=gW0 zpVEfj*utt?NRwbxnEHgoGj&8rJ%;l7jGfqujphvWq9UDD#fFq|7kp%Kyx&tCZL?7* z`&+^nwsFbyeN>>PcXr=egvjE~eAv&`~@EFT@W$pG_-%lwbd(W-t^TNmIb*~@bg z?J(T3;QMvcjIkd^84;6bUO;t1sG$=1IuN-E7srUF&dFH9GR(#r9jk*sm?$zv-gt)9 z%~V}<(M~?uwza$_UZ^v?Ud=wbLxY6#_60|&Blo;FapL#9*!-S;dT@Ka!fT1t65}1k zibum`9}+{-(!?@ietPh3mcI?Y=TLs?{)$$~6Fy;dcU zq8*f`O41v!Uy4s2o>d>DOw{Zp59;AA&Eb*wYI-H}L8sC_aT|A0GPaeDqTN z90gu^H~FsvdR>lKfr=vDN2d4}t|-qz`GvI4DXy{wa)ew~hW!&(4N%<%9ikyvIOZ#c zd@-Il)KR^0IL|4Sz;|H>5;21yd7OShn1>?D(cqVGa+ZCiDuKmHZFa164y9+hxlT3$ zte;?;DKSITin^~#$lD&55f^_jXk!H)nmmT>JnF1(_dpg+#Dl>BWaI$}yCmi|+A)=< z>z!m>c3zQu2{;B$DWRsH5Mx{l1l>7biW}PHDEvshL&*c?eU#Oj=3ZJvzDlI%K73Nz zC)eU18Z7Y>>j}MhJB_cTugN7x4-~GWF<5K{*Y6dyCtrSf`>H)#&N8UU?(w^|riL-y zYTPUiOpTF@cqLmRONyk{7wxZv) zxvok|jTE7_)^6rm0shl-@r8@jf|&Bt3ASRB@v)#H4`CJR#>*{`X(2%yrQD9?At<9V z77HoYRq>D=3ex*C`R5VDMEk@E#H3(wM*t(_X0S6O{!F!OSg;nza7}z*Nm-Ml%$e8L z#^kasj+h|7b^AhAG%Vs`lh3B^hTs6dFuLnKj9gsx(M?v_S`QK1_~fNC)$Q*fA8a>Q zTadI!)(C48e&yN{3O%H0L&fZskU5B~_W{InHm$Z%WrQjjy2Vmb>S% zo$WB8kxf?d7x0_(E85p#2|6huvayuEhPC!SGv{q&KmS&W!Hju(F5GY;z>?tj2YC{GGHgIf@&&h zYpQCR9E(`Dz_I%^t58>cvQgiFmoG;oW2kHpWDF^=|7dL8D^UMb=zS``0a%#v>ks|Z zSzWC0TK$0uU3-c~rP8VKUerq8=GT&0tbe*g^hx$9J218q=t6Ucm@5+h+@1n-%(r}CjEywT@gO7td z9o_5@PScQWX1ce;)BJDca`!MIe9SoFO?GY<$2fEkPH-hbVFQPsHT>g_TJ$cXOi7So z2YSD;axI5`>=_{6U8;?a^+=gfb(4&HZ|qm<+662z$oOEq5iI-owyd{lf$)HeLn#sC ztcpF$Mv8udS__B)LV?L1!@!F}af?^8hZlp8kPr#qUmizaeE>?R7~Sztw!`?4Z(TpY z??wQNq%t+(zNi@AmZgx;oV5t)a2PHRvGK!X52ffpR{TzTx;s7a&4m*%YJTD#6a{T_ zIG`OMe-dHDhYsdFd3p0u*!`tYqs8PH@M7N~`ohf&WxIL2J(S^;lHjTIkHp0b)X@t_ z77h0Sw4Yd+Oa~6L5 zqGPw{B}*~EiL2b(S|wg8ib~+X|6C#wyhcxzD>p| ziS5WMxx0=hb>dF;?zFGpB50Y&((8oTEoib=AP*i9#~Zjo#FKa4!)kGpEb?S$owH^) zOe@%@+vymNMbmrO0w?m@4eK|*p{NL4)3iN#y55Z4_P-Vr&5B5RM+l2bWNkF4b(ucI zm&kzl?kUtqE=ESKoU4#8w!v|#W)`bO2DP%`Jt3(caSjXb&cvWbPG$oaG6zpt%TZYi z_F+D#l5Slr4~BQAe8;dX0u@xv4iIH!bvq2aY#;VrX+OHXJ?fPPRP?>WVNC>noAqYn zXDU^0Nqb!pUtFJT%v8CB9m`=BTh$9W4Tzfl)MdbvokJRJCy+<;bBCZlLxj<(zV5{@ zatxY*|0^wO4@1e}Gc9pqpj*WUngZG%8#tGGQ$xdR58;jZvz|jN`7?Y*o%GcVD zMVxtSMai%yAT)?BFQsFriH?}Of{4fK9Qx<_dE^2=@u3Q zXi|wjR%{ZQMPHmWFc-YmAi>EM4H;i1p@$)yjuU(gCC)_HosUIAOb@Op6+_ziwk4GZXf@0Ipq?AzZQr)?td`+XF*^CQ`VH`(A0g8aZ5Y-OO@0Vn-8}mw% zTKq3duS)DI>@v6=JSe1PBpWpG-23vKGA$DWQBE7qe`Zfx@HfoxaTB)CQYo-el`?_o z%wSI>K~hMFqV^(T=%tWA&$&SJazx;p7v+Q2{+n52&-jkyd10^EOIVE_ZTlX$*|l7^ zu~FoNL6uQhzYnB}6_p>jmPu?E1NE^~U+^qeF7xa%6R+j#zKl!ru%#?^tbcLENA|~$ zWSQCRh-rCK!RJIC>gOxIvHn3pcIt3zHpBI=<*PZb=@`KQCLJW&8Zj>7XBODg6YwTx z#32!Vbce1$;r-WqZ2d560+VI-ay6wU_**@~Q2H^5fJPV3ZG^(TO4$Ef z;v?jcq$audDA^aK{#^&UTFIG1-A#q|IvECg%H%dn0Xm}*LQ7b2kBNC2J6^t5j;@c& z!{ar3!LxU~wvz>!Ju)=wuAiB&YfDbAyvnxsJ(}4oyps)hJbvwt!wXXQ1KD$-6+Ywh zkGYEd{w49+otT$zQGdxZph0eufh+x#@ac!MBoB3ug6b=G~QFt{S6^p@eR)OAB<~64D z^$FvcZlv-aIsU*Q-#IlEto3e4jSFx#UD}Oa5a0&!tin0W43#$ZR+Keh-PMaleX(lSWU* zSB{B>_Cs>r@sx6OdS#zWMr@4132)<)WhLL4O}vcnLBotElrqeSfc>#TswHPXRgCKB z;jURF)GWSQu$^@OL{ooK6%XBVko1o{vxi;;O}WRTbyX#A6O6pW7nUwz50FU3IaDH| zbl88B*WW$CPW8@Gk&aTl_fyZfNirul*YXq_p(f-!K&~`p*@6GePQp$qp}HEsuFHJ` z$teu~R#5hdBER62UcnDG^VmgYR8MCK0xSih_``&P@{-~u*#(9QZ7=ujvoy>g+9ggI zBGF42lcrzR!9L5JUhU%xqwWQ}{Ug2F_y`w|n#8v?s3}yApOhyiHJyuR1F8!h3of1a zIVeSKpQq<2FlMW%)4HHUr_Spenyz9#Wek5>THLQt_$SGDEC5q+2xv&T`upCj-~?pT zT7U)sC_t;K-=nTxX(%v2jcaUCtt%oA5};pdNRYGep#*h6=xGfza8{jO%?$Bd*MyjR zBmlttyV&ACuSg;U#0WL2sF!Ugj+5VfTvYI`WOPJb^%&2TS-su<BS9`;y3a_gM}yMW z^8(L}pZ_XEJk|yyR74-tu*doz5Cr_kl^)UNhn>1%|3^)ngXC|Uf%pFB2*ojkBL4%$ z7_NKxGZ*DO_>XfnqVduXz+9etaGHnp9{k7F72y)X@&JtDLx2nj$7{U%-Sw}t;{ON7 zprMU&zs%nE|TU%t7_n2x9@E){jto@&HnT#x|P*?>!k1`80@p z-Us=q8qk7P5-3TF5X#@!@=(ndQsh|8`?RO67|`$*Y2d%XwE+OZ2Zh19|A5ym{J{T? z1W5k?>@@ff$O`-?a2%p3+z%joYXqbM{O_o04?A3BivXygbZvZ8|1MJk05~3~Jc8!8 z0uc;0bi(oea035#65roBd;kE$1NLX|-)3R{v%Cq)S5FJPpM8edS6hhfVFMq<-S?s; zi1Gf&{5#SL0MI?qoqTf-Dz~!$??=cGT{T6VowN@ip}c!2ubmnA&!7;Z%7&-{BR zH4k`S<^3}tLdhO+G4ni7voE{{b@T5pRN(*pSJp<{a2|Hzwgg)6Nd@@N-3S)|V0)mX e{Sg5G5zENPNVU~b5#<2@M#Os+0czL&{q{eZe&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -65,7 +65,7 @@ echo. 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo location of your Java installation. 1>&2 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line @@ -73,21 +73,10 @@ goto fail @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% From 6f0fb37de6d767134f6c4e6db9974208dfb5ae98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 08:54:39 +0200 Subject: [PATCH 077/259] chore(deps): bump com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp (#2809) Bumps [com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp](https://github.com/FasterXML/jackson-datatypes-misc) from 2.21.2 to 2.21.3. - [Commits](https://github.com/FasterXML/jackson-datatypes-misc/compare/jackson-datatypes-misc-parent-2.21.2...jackson-datatypes-misc-parent-2.21.3) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp dependency-version: 2.21.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c1584d45b1..607a679479 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" flyway = "12.4.0" -jackson = "2.21.2" +jackson = "2.21.3" jakarta-json = "2.1.3" junit = "6.0.3" nimbus = "10.9" From eac99f892d760559a560bff0a3747b7a6e5d6f4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 08:55:00 +0200 Subject: [PATCH 078/259] chore(deps): bump io.swagger.core.v3.swagger-gradle-plugin (#2808) Bumps io.swagger.core.v3.swagger-gradle-plugin from 2.2.48 to 2.2.49. --- updated-dependencies: - dependency-name: io.swagger.core.v3.swagger-gradle-plugin dependency-version: 2.2.49 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 607a679479..1222f63093 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -250,5 +250,5 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } shadow = { id = "com.gradleup.shadow", version = "9.4.1" } -swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.48" } +swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.49" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From 3725c89bce29569f99d4490fb27d116afd158c49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 08:55:17 +0200 Subject: [PATCH 079/259] chore(deps): bump aws from 2.42.40 to 2.43.2 (#2807) Bumps `aws` from 2.42.40 to 2.43.2. Updates `software.amazon.awssdk:s3` from 2.42.40 to 2.43.2 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.42.40 to 2.43.2 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.43.2 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.43.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1222f63093..80b45a1ed8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.42.40" +aws = "2.43.2" azure-storage-blob = "12.33.3" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" From 2d9a454186fc4e787bb8cd6b30fc4c2cab9e0d3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 08:55:39 +0200 Subject: [PATCH 080/259] chore(deps): bump step-security/harden-runner from 2.19.0 to 2.19.1 (#2806) Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.19.0 to 2.19.1. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/8d3c67de8e2fe68ef647c8db1e6a09f647780f40...a5ad31d6a139d249332a2605b85202e8c0b78450) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.19.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 2 +- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/deployment-test.yaml | 6 ++--- .github/workflows/draft-release.yaml | 2 +- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 2 +- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 6 ++--- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/stale-bot.yml | 2 +- .github/workflows/triage-issue.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/trivy.yml | 6 ++--- .github/workflows/upgradeability-test.yaml | 4 ++-- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 4 ++-- 19 files changed, 41 insertions(+), 41 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 59218dc185..5157c7915d 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -55,7 +55,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index 87d549bae5..bd994e93a5 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Copy labels from linked issue to PR diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index efa1559876..736b9a0fab 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: test-prepare steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -84,7 +84,7 @@ jobs: "v1.33.7" ] steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index e5fff6e5ad..dd2bef0b49 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -44,7 +44,7 @@ jobs: is_official_release: ${{ steps.validation.outputs.is_official_release }} steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index 8213edb385..69cbc28514 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 5826f2917e..01a69d4d7c 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit ############## diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index f0cd532b4c..85391ebc90 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index 99e34c76f0..dd6e23bc89 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -38,7 +38,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index e286156623..47d37c7cfe 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -72,7 +72,7 @@ jobs: HAS_SWAGGER: ${{ steps.secret-presence.outputs.HAS_SWAGGER }} steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Check whether secrets exist @@ -95,7 +95,7 @@ jobs: DATED: ${{ steps.get-version.outputs.DATED }} steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -165,7 +165,7 @@ jobs: if: ${{ needs.determine-version.outputs.DATED == 'true' }} steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 68709314f3..c0029a0130 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,7 +56,7 @@ jobs: update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -148,7 +148,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -188,7 +188,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -251,7 +251,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit @@ -294,7 +294,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Checkout main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 4b6793e772..1cace0aba2 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -42,7 +42,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Checkout Repository diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 330c243729..21f1e4e108 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -39,7 +39,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 diff --git a/.github/workflows/triage-issue.yml b/.github/workflows/triage-issue.yml index a090002360..a470f7cfc5 100644 --- a/.github/workflows/triage-issue.yml +++ b/.github/workflows/triage-issue.yml @@ -36,7 +36,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - run: gh issue edit "$NUMBER" --add-label "$LABELS" diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index 0cfad95d07..5bbe913ecd 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -71,7 +71,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 28b4025e35..0d8d934f5d 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 785c46fb02..f6458215bf 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -38,7 +38,7 @@ jobs: value: ${{ steps.git-sha7.outputs.SHA7 }} steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Resolve git 7-chars sha @@ -54,7 +54,7 @@ jobs: security-events: write steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -92,7 +92,7 @@ jobs: - edc-dataplane-hashicorp-vault steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 8c558c21bf..8a14a7505f 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: [ test-prepare ] steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 2dc879db13..dfea67d52b 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -36,7 +36,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -152,7 +152,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -172,7 +172,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -192,7 +192,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -214,7 +214,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -248,7 +248,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -265,7 +265,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -287,7 +287,7 @@ jobs: contents: write steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 00cfdfeed7..515d113e2e 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -46,7 +46,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit @@ -71,7 +71,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 # v2.19.0 + uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit From 3a9dc0c0377e3e35fb65acfb054122ab263607ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 08:56:01 +0200 Subject: [PATCH 081/259] chore(deps): bump eclipse-temurin in /resources (#2804) Bumps eclipse-temurin from `5fcc275` to `c707c0d`. --- updated-dependencies: - dependency-name: eclipse-temurin dependency-version: 25-jre-alpine dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- resources/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/Dockerfile b/resources/Dockerfile index 229885ada1..9da1b2052f 100644 --- a/resources/Dockerfile +++ b/resources/Dockerfile @@ -19,7 +19,7 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -FROM eclipse-temurin:25-jre-alpine@sha256:5fcc27581b238efbfda93da3a103f59e0b5691fe522a7ac03fe8057b0819c888 +FROM eclipse-temurin:25-jre-alpine@sha256:c707c0d18cb9e8556380719f80d96a7529d0746fbb42143893949b98ed2f8943 RUN apk update && apk upgrade --no-cache ARG JAR From f72950a8f09777193cc93f50cc677a504a575512 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 08:56:23 +0200 Subject: [PATCH 082/259] chore(deps): bump github/codeql-action from 4.35.2 to 4.35.3 (#2805) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.35.3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...e46ed2cbd01164d986452f91f178727624ae40d7) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 4 ++-- .github/workflows/kics.yml | 2 +- .github/workflows/trivy.yml | 4 ++-- .github/workflows/workflow-security-lint.yaml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 5157c7915d..a61afd6dbf 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 + uses: github/codeql-action/init@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 + uses: github/codeql-action/analyze@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 85391ebc90..ecc451411a 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 + uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index f6458215bf..302b78790a 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -71,7 +71,7 @@ jobs: output: "trivy-results-config.sarif" severity: "CRITICAL,HIGH" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 + uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 if: always() with: sarif_file: "trivy-results-config.sarif" @@ -122,6 +122,6 @@ jobs: timeout: "10m0s" - name: Upload Trivy scan results to GitHub Security tab if: success() && steps.imageCheck.outcome != 'failure' - uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 + uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 with: sarif_file: "trivy-results-${{ matrix.image }}.sarif" diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 515d113e2e..03734b0532 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -88,7 +88,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2 + uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 if: always() with: sarif_file: results-fixed.sarif From 0c213529e75dee6e7128497c753e105d6580c128 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 09:05:20 +0200 Subject: [PATCH 083/259] chore(deps): bump org.postgresql:postgresql from 42.7.10 to 42.7.11 (#2803) Bumps [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc) from 42.7.10 to 42.7.11. - [Release notes](https://github.com/pgjdbc/pgjdbc/releases) - [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md) - [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.7.10...REL42.7.11) --- updated-dependencies: - dependency-name: org.postgresql:postgresql dependency-version: 42.7.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 80b45a1ed8..c95541e023 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,7 @@ okhttp = "5.3.2" opentelemetry = "2.27.0" opentelemetry-instrumentation = "2.27.0" opentelemetry-log4j-appender = "2.27.0-alpha" -postgres = "42.7.10" +postgres = "42.7.11" restAssured = "6.0.0" rsApi = "4.0.0" testcontainers = "2.0.5" From 2a70b8108bec4722dc15a73b129c77abd1b3f319 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 09:10:38 +0200 Subject: [PATCH 084/259] chore(deps): bump flyway from 12.4.0 to 12.5.0 (#2802) Bumps `flyway` from 12.4.0 to 12.5.0. Updates `org.flywaydb:flyway-core` from 12.4.0 to 12.5.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.4.0 to 12.5.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.5.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.5.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c95541e023..46c1dbff54 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ azure-storage-blob = "12.33.3" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" -flyway = "12.4.0" +flyway = "12.5.0" jackson = "2.21.3" jakarta-json = "2.1.3" junit = "6.0.3" From ceeda7139aae321b035fc6de35c8c63d6db33caf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 08:38:00 +0200 Subject: [PATCH 085/259] chore(deps): bump com.azure:azure-storage-blob from 12.33.3 to 12.33.4 (#2819) Bumps [com.azure:azure-storage-blob](https://github.com/Azure/azure-sdk-for-java) from 12.33.3 to 12.33.4. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/com.azure+azure-storage-blob_12.33.3...com.azure+azure-storage-blob_12.33.4) --- updated-dependencies: - dependency-name: com.azure:azure-storage-blob dependency-version: 12.33.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 46c1dbff54..3274ea9189 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" aws = "2.43.2" -azure-storage-blob = "12.33.3" +azure-storage-blob = "12.33.4" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" From a763221ae60ec94829b6644dd08f7785bea44fbd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 08:38:55 +0200 Subject: [PATCH 086/259] chore(deps): bump github/codeql-action from 4.35.3 to 4.35.4 (#2817) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.3 to 4.35.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e46ed2cbd01164d986452f91f178727624ae40d7...68bde559dea0fdcac2102bfdf6230c5f70eb485e) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 4 ++-- .github/workflows/kics.yml | 2 +- .github/workflows/trivy.yml | 4 ++-- .github/workflows/workflow-security-lint.yaml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index a61afd6dbf..df8c78267c 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 + uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 + uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index ecc451411a..85c107fd46 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 302b78790a..aa9827af18 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -71,7 +71,7 @@ jobs: output: "trivy-results-config.sarif" severity: "CRITICAL,HIGH" - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 if: always() with: sarif_file: "trivy-results-config.sarif" @@ -122,6 +122,6 @@ jobs: timeout: "10m0s" - name: Upload Trivy scan results to GitHub Security tab if: success() && steps.imageCheck.outcome != 'failure' - uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: sarif_file: "trivy-results-${{ matrix.image }}.sarif" diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 03734b0532..35e5acebd2 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -88,7 +88,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 if: always() with: sarif_file: results-fixed.sarif From 7fe13f774885e3b8f5fc3727055b05c651526443 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 08:39:31 +0200 Subject: [PATCH 087/259] chore(deps): bump log4j2 from 2.25.4 to 2.26.0 (#2816) Bumps `log4j2` from 2.25.4 to 2.26.0. Updates `org.apache.logging.log4j:log4j-api` from 2.25.4 to 2.26.0 Updates `org.apache.logging.log4j:log4j-core` from 2.25.4 to 2.26.0 Updates `org.apache.logging.log4j:log4j-core-test` from 2.25.4 to 2.26.0 Updates `org.apache.logging.log4j:log4j-layout-template-json` from 2.25.4 to 2.26.0 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-version: 2.26.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-core dependency-version: 2.26.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-core-test dependency-version: 2.26.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.apache.logging.log4j:log4j-layout-template-json dependency-version: 2.26.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3274ea9189..f1d03df10a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,7 +27,7 @@ rsApi = "4.0.0" testcontainers = "2.0.5" testcontainers-keycloak = "4.2.1" titanium = "1.7.0" -log4j2 = "2.25.4" +log4j2 = "2.26.0" wiremock = "3.13.2" From 4a6d840dc4672fa8668a98a7b9285fe3958e57f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arno=20Wei=C3=9F?= <86715435+arnoweiss@users.noreply.github.com> Date: Fri, 15 May 2026 11:19:52 +0200 Subject: [PATCH 088/259] fix(helm): add otel configmap to tractusx-connector-memory chart (#2815) * fix: add otel config to in mem chart * docs(helm): regenerate tractusx-connector-memory chart docs --- charts/tractusx-connector-memory/README.md | 1 + .../templates/configmap-otel.yaml | 34 +++++++++++++++++++ .../templates/deployment-runtime.yaml | 9 +++++ charts/tractusx-connector-memory/values.yaml | 5 +++ 4 files changed, 49 insertions(+) create mode 100644 charts/tractusx-connector-memory/templates/configmap-otel.yaml diff --git a/charts/tractusx-connector-memory/README.md b/charts/tractusx-connector-memory/README.md index 9450a8b681..33c40a36d4 100644 --- a/charts/tractusx-connector-memory/README.md +++ b/charts/tractusx-connector-memory/README.md @@ -141,6 +141,7 @@ helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0- | runtime.livenessProbe.timeoutSeconds | int | `5` | number of seconds after which the probe times out | | runtime.logs.level | string | `"DEBUG"` | Defines the log granularity of the default Console Monitor. | | runtime.nodeSelector | object | `{}` | [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) to constrain pods to nodes | +| runtime.opentelemetry | string | `"otel.javaagent.enabled=false\notel.javaagent.debug=false"` | configuration of the [Open Telemetry Agent](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/) to collect and expose metrics | | runtime.podAnnotations | object | `{}` | additional annotations for the pod | | runtime.podLabels | object | `{}` | additional labels for the pod | | runtime.podSecurityContext | object | `{"fsGroup":10001,"runAsGroup":10001,"runAsUser":10001,"seccompProfile":{"type":"RuntimeDefault"}}` | The [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) defines privilege and access control settings for a Pod within the deployment | diff --git a/charts/tractusx-connector-memory/templates/configmap-otel.yaml b/charts/tractusx-connector-memory/templates/configmap-otel.yaml new file mode 100644 index 0000000000..04d95e2d8b --- /dev/null +++ b/charts/tractusx-connector-memory/templates/configmap-otel.yaml @@ -0,0 +1,34 @@ +################################################################################# + # Copyright (c) 2023 ZF Friedrichshafen AG + # Copyright (c) 2023 Mercedes-Benz Tech Innovation GmbH + # Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + # Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # 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. + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + # License for the specific language governing permissions and limitations + # under the License. + # + # SPDX-License-Identifier: Apache-2.0 + ################################################################################# + + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "txdc.fullname" . }}-runtime + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "txdc.runtime.labels" . | nindent 4 }} +data: + opentelemetry.properties: |- + {{- .Values.runtime.opentelemetry | nindent 4 }} diff --git a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml index c1ae50676c..2e8896ddf4 100644 --- a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml +++ b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml @@ -348,6 +348,9 @@ spec: mountPath: /opt/java/openjdk/lib/security/cacerts subPath: cacerts {{- end }} + - name: "configuration" + mountPath: "/app/opentelemetry.properties" + subPath: "opentelemetry.properties" - name: log4j2-config mountPath: /app/log4j2.yaml subPath: log4j2.yaml @@ -363,6 +366,12 @@ spec: emptyDir: sizeLimit: 1Mi {{- end }} + - name: "configuration" + configMap: + name: {{ include "txdc.fullname" . }}-runtime + items: + - key: "opentelemetry.properties" + path: "opentelemetry.properties" - name: "log4j2-config" configMap: name: {{ include "txdc.fullname" . }}-log4j2 diff --git a/charts/tractusx-connector-memory/values.yaml b/charts/tractusx-connector-memory/values.yaml index af90752eaf..ea4b5a5fb5 100644 --- a/charts/tractusx-connector-memory/values.yaml +++ b/charts/tractusx-connector-memory/values.yaml @@ -380,6 +380,11 @@ runtime: # -- targetAverageUtilization of memory provided to a pod targetMemoryUtilizationPercentage: 80 + # -- configuration of the [Open Telemetry Agent](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/) to collect and expose metrics + opentelemetry: |- + otel.javaagent.enabled=false + otel.javaagent.debug=false + # -- [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) to constrain pods to nodes nodeSelector: {} # -- [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to configure preferred nodes From 731842809108c7237a3310a0cb14aef27ab13280 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 May 2026 12:49:23 +0200 Subject: [PATCH 089/259] chore(deps): bump aws from 2.43.2 to 2.44.4 (#2818) Bumps `aws` from 2.43.2 to 2.44.4. Updates `software.amazon.awssdk:s3` from 2.43.2 to 2.44.4 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.43.2 to 2.44.4 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.44.4 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.44.4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f1d03df10a..2306fd9577 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.43.2" +aws = "2.44.4" azure-storage-blob = "12.33.4" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" From f2c5c008fae9d0de7deafa6876774e47d66d5ef0 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Fri, 15 May 2026 14:48:11 +0200 Subject: [PATCH 090/259] feat: use trivy central (#2812) * feat: use trivy from central * fix: remove concurrency for publish-new-snapshot * fix: remove concurrency for publish-new-snapshot * feat: add poutine ignore --------- Co-authored-by: Lars Geyer-Blaumeiser --- .../action.yml | 2 - .github/poutine.yml | 29 +++++++++++ .github/scripts/fix-poutine-sarif.py | 7 ++- .github/workflows/trivy.yml | 52 +++---------------- .github/workflows/workflow-security-lint.yaml | 2 + 5 files changed, 43 insertions(+), 49 deletions(-) create mode 100644 .github/poutine.yml diff --git a/.github/actions/generate-and-check-dependencies/action.yml b/.github/actions/generate-and-check-dependencies/action.yml index fa193bf798..1ed0ef1bb7 100644 --- a/.github/actions/generate-and-check-dependencies/action.yml +++ b/.github/actions/generate-and-check-dependencies/action.yml @@ -40,8 +40,6 @@ runs: - name: Run dash id: run-dash - # poutine: ignore[unpinnable_action] - # poutine: ignore[github_action_from_unverified_creator_used] uses: eclipse-tractusx/sig-infra/.github/actions/run-dash@main with: dash_input: dependency-list diff --git a/.github/poutine.yml b/.github/poutine.yml new file mode 100644 index 0000000000..550919627e --- /dev/null +++ b/.github/poutine.yml @@ -0,0 +1,29 @@ +################################################################################# +# Copyright (c) 2026 Cofinity-X GmbH +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +skip: + - rule: github_action_from_unverified_creator_used + path: .github/workflows/trivy.yml + - rule: unpinnable_action + path: .github/workflows/trivy.yml + - rule: github_action_from_unverified_creator_used + path: .github/actions/generate-and-check-dependencies/action.yml + - rule: unpinnable_action + path: .github/actions/generate-and-check-dependencies/action.yml + diff --git a/.github/scripts/fix-poutine-sarif.py b/.github/scripts/fix-poutine-sarif.py index ca8cf30928..41f0ac1661 100644 --- a/.github/scripts/fix-poutine-sarif.py +++ b/.github/scripts/fix-poutine-sarif.py @@ -83,6 +83,12 @@ print(f"Fixed location -> {filepath}:{lineno} ({ref})") fixed_idx += 1 +# Drop stale fingerprints after location/region rewrites so GitHub recalculates them. +for run in sarif.get("runs", []): + for result in run.get("results", []): + result.pop("fingerprints", None) + result.pop("partialFingerprints", None) + # ── Fix 2: Patch artifact lengths (-1 → real size) ─────────────────────────── # poutine emits length=-1 which causes GitHub Advanced Security to ignore # startLine and show every finding at line 1 in the Security tab. @@ -96,4 +102,3 @@ json.dump(sarif, f) print(f"Done. Fixed {fixed_idx} location(s). Written to results-fixed.sarif.") - diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index aa9827af18..2a80fd7179 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -37,44 +37,20 @@ jobs: outputs: value: ${{ steps.git-sha7.outputs.SHA7 }} steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - name: Resolve git 7-chars sha id: git-sha7 run: | echo "SHA7=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT trivy-analyze-config: - runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 - with: - scan-type: "config" - # ignore-unfixed: true - exit-code: "0" - hide-progress: false - format: "sarif" - output: "trivy-results-config.sarif" - severity: "CRITICAL,HIGH" - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 - if: always() - with: - sarif_file: "trivy-results-config.sarif" + uses: eclipse-tractusx/sig-infra/.github/workflows/reusable-trivy.yaml@main + with: + scan-type: "config" + output: "trivy-results-config.sarif" trivy: needs: [ git-sha7 ] @@ -91,14 +67,6 @@ jobs: - edc-controlplane-postgresql-hashicorp-vault - edc-dataplane-hashicorp-vault steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - ## This step will fail if the docker images is not found - name: "Check if image exists" id: imageCheck @@ -112,16 +80,8 @@ jobs: ## the next two steps will only execute if the image exists check was successful - name: Run Trivy vulnerability scanner if: success() && steps.imageCheck.outcome != 'failure' - uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # 0.36.0 + uses: eclipse-tractusx/sig-infra/.github/workflows/reusable-trivy.yaml@main with: + scan-type: "image" image-ref: "tractusx/${{ matrix.image }}:sha-${{ needs.git-sha7.outputs.value }}" - format: "sarif" output: "trivy-results-${{ matrix.image }}.sarif" - exit-code: "0" - severity: "CRITICAL,HIGH" - timeout: "10m0s" - - name: Upload Trivy scan results to GitHub Security tab - if: success() && steps.imageCheck.outcome != 'failure' - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 - with: - sarif_file: "trivy-results-${{ matrix.image }}.sarif" diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 35e5acebd2..ec835fd3f9 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -82,6 +82,8 @@ jobs: - name: Run poutine uses: boostsecurityio/poutine-action@e240ebd3eff8b2db5a8e5f6b28f58739d7db2247 # v1.1.4 + with: + config: .github/poutine.yml - name: Fix and patch poutine SARIF if: always() From 05e1eeced2b518d20287e5dea5f41ef8011b90ed Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Wed, 20 May 2026 11:01:30 +0200 Subject: [PATCH 091/259] fix: fix using of trivy-central (#2820) --- .github/workflows/trivy.yml | 58 +++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 2a80fd7179..e35bb7d7ed 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -50,38 +50,40 @@ jobs: uses: eclipse-tractusx/sig-infra/.github/workflows/reusable-trivy.yaml@main with: scan-type: "config" - output: "trivy-results-config.sarif" + output-file: "trivy-results-config.sarif" - trivy: + trivy-edc-runtime-memory: needs: [ git-sha7 ] permissions: actions: read contents: read security-events: write - runs-on: ubuntu-latest - strategy: - fail-fast: false # continue scanning other images although if the other has been vulnerable - matrix: - image: - - edc-runtime-memory - - edc-controlplane-postgresql-hashicorp-vault - - edc-dataplane-hashicorp-vault - steps: - ## This step will fail if the docker images is not found - - name: "Check if image exists" - id: imageCheck - env: - IMAGE: ${{ matrix.image }} - SHA7: ${{ needs.git-sha7.outputs.value }} - run: | - docker buildx imagetools inspect --format '{{ json . }}' "tractusx/$IMAGE:sha-$SHA7" - continue-on-error: true + uses: eclipse-tractusx/sig-infra/.github/workflows/reusable-trivy.yaml@main + with: + scan-type: "image" + image-ref: "tractusx/edc-runtime-memory:sha-${{ needs.git-sha7.outputs.value }}" + output-file: "trivy-results-edc-runtime-memory.sarif" + + trivy-edc-controlplane: + needs: [ git-sha7 ] + permissions: + actions: read + contents: read + security-events: write + uses: eclipse-tractusx/sig-infra/.github/workflows/reusable-trivy.yaml@main + with: + scan-type: "image" + image-ref: "tractusx/edc-controlplane-postgresql-hashicorp-vault:sha-${{ needs.git-sha7.outputs.value }}" + output-file: "trivy-results-edc-controlplane-postgresql-hashicorp-vault.sarif" - ## the next two steps will only execute if the image exists check was successful - - name: Run Trivy vulnerability scanner - if: success() && steps.imageCheck.outcome != 'failure' - uses: eclipse-tractusx/sig-infra/.github/workflows/reusable-trivy.yaml@main - with: - scan-type: "image" - image-ref: "tractusx/${{ matrix.image }}:sha-${{ needs.git-sha7.outputs.value }}" - output: "trivy-results-${{ matrix.image }}.sarif" + trivy-edc-dataplane: + needs: [ git-sha7 ] + permissions: + actions: read + contents: read + security-events: write + uses: eclipse-tractusx/sig-infra/.github/workflows/reusable-trivy.yaml@main + with: + scan-type: "image" + image-ref: "tractusx/edc-dataplane-hashicorp-vault:sha-${{ needs.git-sha7.outputs.value }}" + output-file: "trivy-results-edc-dataplane-hashicorp-vault.sarif" From 1231504eed0c2f089fcd49142e2804581af8cc5c Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Thu, 21 May 2026 16:07:02 +0200 Subject: [PATCH 092/259] fix: Add migration script for EDC 8-11 (#2823) * fix: change migration strategy * fix: change migration strategy --- .../connector/V1_6_0__EDC_8_migration.sql | 62 +++++++++++++++++++ .../connector/V1_6_1__EDC_9_migration.sql | 4 ++ .../connector/V1_6_2__EDC_11_migration.sql | 32 ++++++++++ 3 files changed, 98 insertions(+) create mode 100644 edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_0__EDC_8_migration.sql create mode 100644 edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_1__EDC_9_migration.sql create mode 100644 edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_2__EDC_11_migration.sql diff --git a/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_0__EDC_8_migration.sql b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_0__EDC_8_migration.sql new file mode 100644 index 0000000000..9fa2705a7e --- /dev/null +++ b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_0__EDC_8_migration.sql @@ -0,0 +1,62 @@ +CREATE INDEX IF NOT EXISTS data_plane_state ON edc_data_plane (state,state_time_stamp); + +ALTER TABLE edc_data_plane ADD COLUMN IF NOT EXISTS transfer_type_destination VARCHAR DEFAULT 'HttpData'; + +CREATE INDEX IF NOT EXISTS transfer_process_state ON edc_transfer_process (state,state_time_stamp); + +CREATE INDEX IF NOT EXISTS policy_monitor_state ON edc_policy_monitor (state,state_time_stamp); + +CREATE INDEX IF NOT EXISTS contract_negotiation_state ON edc_contract_negotiation (state,state_timestamp); + +CREATE TABLE IF NOT EXISTS edc_federated_catalog +( + id VARCHAR PRIMARY KEY NOT NULL, + catalog JSON, + marked BOOLEAN DEFAULT FALSE +); + +ALTER TABLE edc_policydefinitions ADD COLUMN IF NOT EXISTS profiles JSON; + +CREATE TABLE IF NOT EXISTS edc_data_plane_instance +( + id VARCHAR NOT NULL PRIMARY KEY, + data JSON, + lease_id VARCHAR + CONSTRAINT data_plane_instance_lease_id_fk + REFERENCES edc_lease + ON DELETE SET NULL +); + + +CREATE TABLE IF NOT EXISTS edc_lease +( + leased_by VARCHAR NOT NULL, + leased_at BIGINT, + lease_duration INTEGER NOT NULL, + lease_id VARCHAR NOT NULL + CONSTRAINT lease_pk + PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS edc_agreement_retirement +( + contract_agreement_id VARCHAR PRIMARY KEY, + reason TEXT NOT NULL, + agreement_retirement_date BIGINT NOT NULL +); + + + + + + + + + + + + + + + + diff --git a/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_1__EDC_9_migration.sql b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_1__EDC_9_migration.sql new file mode 100644 index 0000000000..a443c4a9f2 --- /dev/null +++ b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_1__EDC_9_migration.sql @@ -0,0 +1,4 @@ +UPDATE edc_policydefinitions SET profiles='[]'::json where profiles is NULL; + +ALTER TABLE edc_data_plane + ADD COLUMN IF NOT EXISTS runtime_id VARCHAR; diff --git a/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_2__EDC_11_migration.sql b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_2__EDC_11_migration.sql new file mode 100644 index 0000000000..d22eaa7818 --- /dev/null +++ b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_6_2__EDC_11_migration.sql @@ -0,0 +1,32 @@ +CREATE TABLE IF NOT EXISTS edc_contract_agreement_bpns +( + agreement_id VARCHAR + CONSTRAINT contract_agreement_bpns_contract_agreement_id_fk PRIMARY KEY + REFERENCES edc_contract_agreement, + provider_bpn VARCHAR(255) NOT NULL, + consumer_bpn VARCHAR(255) NOT NULL + ); + +CREATE TABLE IF NOT EXISTS edc_jti_validation +( + token_id VARCHAR NOT NULL PRIMARY KEY, + expires_at BIGINT +); + +CREATE INDEX IF NOT EXISTS contract_negotiation_lease_id_index + ON edc_contract_negotiation (lease_id); + +CREATE INDEX IF NOT EXISTS contract_negotiation_agreement_id_index + ON edc_contract_negotiation (agreement_id); + +CREATE INDEX IF NOT EXISTS policy_monitor_lease_id_index + ON edc_policy_monitor (lease_id); + +CREATE INDEX IF NOT EXISTS transfer_process_lease_id_index + ON edc_transfer_process (lease_id); + + +ALTER TABLE edc_data_plane + ADD COLUMN IF NOT EXISTS resource_definitions json DEFAULT '[]'::json; + +CREATE INDEX IF NOT EXISTS data_plane_lease_id ON edc_data_plane (lease_id); From 9bf3681d26ce61fb8472a02ea82987c4d7057edc Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Thu, 21 May 2026 16:07:43 +0200 Subject: [PATCH 093/259] fix: move federate catalog migration to baseline (#2824) --- .../V1_7_0__Remove_FederatedCatalogCache_Database_Schema.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename edc-extensions/migrations/{control-plane-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/federatedcatalog/V0_0_2__Remove_FederatedCatalogCache_Database_Schema.sql => connector-migration/src/main/resources/migrations/connector/V1_7_0__Remove_FederatedCatalogCache_Database_Schema.sql} (100%) diff --git a/edc-extensions/migrations/control-plane-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/federatedcatalog/V0_0_2__Remove_FederatedCatalogCache_Database_Schema.sql b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_7_0__Remove_FederatedCatalogCache_Database_Schema.sql similarity index 100% rename from edc-extensions/migrations/control-plane-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/federatedcatalog/V0_0_2__Remove_FederatedCatalogCache_Database_Schema.sql rename to edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_7_0__Remove_FederatedCatalogCache_Database_Schema.sql From e82ff1b50cc62526a625bc8c336b37803a52fd97 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Thu, 21 May 2026 16:46:00 +0200 Subject: [PATCH 094/259] Update tractusx config file for new openapi specs Signed-off-by: Lars Geyer-Blaumeiser --- .tractusx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.tractusx b/.tractusx index 88c3d0c480..d00b3446b7 100644 --- a/.tractusx +++ b/.tractusx @@ -2,8 +2,8 @@ product: "Tractus-X EDC" leadingRepository: "https://github.com/eclipse-tractusx/tractusx-edc" repositories: [] openApiSpecs: -- "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.12.0/control-plane.yaml" -- "https://eclipse-tractusx.github.io/tractusx-edc/openapi/data-plane-api/0.12.0/data-plane.yaml" +- "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.12.1/control-plane.yaml" +- "https://eclipse-tractusx.github.io/tractusx-edc/openapi/data-plane-api/0.12.1/data-plane.yaml" - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.11.2/control-plane.yaml" - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/data-plane-api/0.11.2/data-plane.yaml" - "https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/0.10.3/control-plane.yaml" From 4b1521beba7495828d5e738c73e9310bd4a68f9b Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Thu, 21 May 2026 17:49:54 +0200 Subject: [PATCH 095/259] chore: Adaptations due to 0.16.0 upstream changes (#2811) * Adaptations due to 0.16.0 upstream changes Signed-off-by: Lars Geyer-Blaumeiser * Adapt e2e tests towards 0.16.0 upstream Signed-off-by: Lars Geyer-Blaumeiser * fix: add headers on the source address before storage (#2821) * fix: remaining e2e tests * PR remarks * Reversion migration due to conflicting prs Signed-off-by: Lars Geyer-Blaumeiser --------- Signed-off-by: Lars Geyer-Blaumeiser Co-authored-by: andrea bertagnolli --- .../tractusx/edc/jsonld/JsonLdExtension.java | 30 ++------ .../edc/jsonld/TxCachedDocumentRegistry.java | 64 +++++++++++++++++ .../edc/jsonld/JsonLdExtensionTest.java | 6 +- .../edc/cx/CxCachedDocumentRegistry.java | 57 +++++++++++++++ .../tractusx/edc/cx/CxJsonLdExtension.java | 20 ++---- .../edc-controlplane-base/build.gradle.kts | 9 ++- .../edc-dataplane-base/build.gradle.kts | 1 - .../DataPlaneTokenRefreshServiceImpl.java | 65 ++++++++++------- .../DataPlaneTokenRefreshServiceImplTest.java | 22 ++++-- .../dcp/tx-dcp-sts-div/build.gradle.kts | 1 - .../build.gradle.kts | 5 +- .../DspApiConfigurationV08Extension.java | 2 +- .../V1_8_0__Add_DataAddressAlias.sql | 1 + .../provision-additional-headers/README.md | 11 --- .../build.gradle.kts | 33 --------- .../AdditionalHeadersDeprovisioner.java | 48 ------------- .../AdditionalHeadersProvisioner.java | 60 ---------------- ...nalHeadersResourceDefinitionGenerator.java | 55 -------------- .../ProvisionAdditionalHeadersExtension.java | 50 ------------- ...rg.eclipse.edc.spi.system.ServiceExtension | 21 ------ .../AdditionalHeadersProvisionerTest.java | 72 ------------------- ...eadersResourceDefinitionGeneratorTest.java | 66 ----------------- ...ovisionAdditionalHeadersExtensionTest.java | 57 --------------- .../tests/fixtures/DcpHelperFunctions.java | 10 +-- .../fixtures/IdentityHubParticipant.java | 1 + .../tests/transfer/TransferEndToEndTest.java | 43 ++++++++++- edc-tests/e2e-fixtures/build.gradle.kts | 2 - .../tractusx/edc/tests/ParticipantEdrApi.java | 12 ++-- .../edc/tests/TestRuntimeConfiguration.java | 1 + .../edc/tests/participant/DcpParticipant.java | 4 +- .../TractusxDcpParticipantBase.java | 28 ++++---- .../participant/TractusxParticipantBase.java | 62 ++++++++++++---- .../edc/tests/runtimes/PostgresExtension.java | 6 +- .../tests/transfer/ProviderPushBaseTest.java | 3 +- .../edc/tests/catalog/CatalogTest.java | 6 +- .../edc/tests/catalog/CatalogTestDspV08.java | 5 +- .../transfer/test/AzureToAzureTest.java | 2 +- .../transfer/test/MultiCloudTest.java | 10 +-- .../dataplane/transfer/test/S3ToS3Test.java | 2 +- .../tests/transfer/DivConsumerPullTest.java | 12 ++-- .../tests/transfer/StsConsumerPullTest.java | 6 +- .../discovery/e2e/ConnectorDiscoveryTest.java | 15 ++-- .../e2e/ConnectorParameterDiscoveryTest.java | 27 ++++--- .../edc/tests/edrv2/NegotiateEdrTest.java | 6 +- .../transfer/AzureToAzureEndToEndTest.java | 6 +- .../tests/transfer/S3ToS3EndToEndTest.java | 6 +- .../tests/auth/DelegatedAuthEndToEndTest.java | 2 +- .../EmptyAssetSelectorValidatorTest.java | 2 +- .../policy/PolicyDefinitionEndToEndTest.java | 2 +- .../policy/PolicyMonitorEndToEndTest.java | 6 +- .../tests/transfer/RetireAgreementTest.java | 6 +- .../transfer/TransferPullEndToEndTest.java | 5 +- .../transfer/TransferPushEndToEndTest.java | 5 +- .../TransferWithTokenRefreshTest.java | 6 +- .../services/TransferProcessServiceStub.java | 17 +---- .../build.gradle.kts | 7 +- .../build.gradle.kts | 1 - gradle/libs.versions.toml | 6 +- settings.gradle.kts | 1 - 59 files changed, 395 insertions(+), 702 deletions(-) create mode 100644 core/json-ld-core/src/main/java/org/eclipse/tractusx/edc/jsonld/TxCachedDocumentRegistry.java create mode 100644 core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxCachedDocumentRegistry.java create mode 100644 edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_8_0__Add_DataAddressAlias.sql delete mode 100644 edc-extensions/provision-additional-headers/README.md delete mode 100644 edc-extensions/provision-additional-headers/build.gradle.kts delete mode 100644 edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersDeprovisioner.java delete mode 100644 edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java delete mode 100644 edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java delete mode 100644 edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java delete mode 100644 edc-extensions/provision-additional-headers/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension delete mode 100644 edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java delete mode 100644 edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java delete mode 100644 edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java diff --git a/core/json-ld-core/src/main/java/org/eclipse/tractusx/edc/jsonld/JsonLdExtension.java b/core/json-ld-core/src/main/java/org/eclipse/tractusx/edc/jsonld/JsonLdExtension.java index 0287e98845..b54ed1cf01 100644 --- a/core/json-ld-core/src/main/java/org/eclipse/tractusx/edc/jsonld/JsonLdExtension.java +++ b/core/json-ld-core/src/main/java/org/eclipse/tractusx/edc/jsonld/JsonLdExtension.java @@ -23,18 +23,12 @@ import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import java.io.File; -import java.util.Map; - import static org.eclipse.edc.api.management.ManagementApi.MANAGEMENT_SCOPE; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.DSP_SCOPE_V_2025_1; -import static org.eclipse.tractusx.edc.core.utils.FileUtils.getResourceFile; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.EDC_CONTEXT; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_AUTH_NS; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_AUTH_PREFIX; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_NAMESPACE; @@ -42,20 +36,8 @@ public class JsonLdExtension implements ServiceExtension { - public static final String CREDENTIALS_V_1 = "https://www.w3.org/2018/credentials/v1"; - - public static final String SECURITY_JWS_V1 = "https://w3id.org/security/suites/jws-2020/v1"; - public static final String SECURITY_ED25519_V1 = "https://w3id.org/security/suites/ed25519-2020/v1"; - public static final String TX_AUTH_CONTEXT = "https://w3id.org/tractusx/auth/v1.0.0"; - private static final String PREFIX = "document" + File.separator; - private static final Map FILES = Map.of( - CREDENTIALS_V_1, PREFIX + "credential-v1.jsonld", - SECURITY_JWS_V1, PREFIX + "security-jws-2020.jsonld", - SECURITY_ED25519_V1, PREFIX + "security-ed25519-2020.jsonld", - TX_AUTH_CONTEXT, PREFIX + "tx-auth-v1.jsonld", - EDC_CONTEXT, PREFIX + "edc-v1.jsonld"); @Inject private JsonLd jsonLdService; @@ -71,13 +53,9 @@ public void initialize(ServiceExtensionContext context) { jsonLdService.registerNamespace(TX_AUTH_PREFIX, TX_AUTH_NS, MANAGEMENT_SCOPE); - FILES.entrySet().stream().map(this::mapToFile) - .forEach(result -> result.onSuccess(entry -> jsonLdService.registerCachedDocument(entry.getKey(), entry.getValue().toURI())) - .onFailure(failure -> monitor.warning("Failed to register cached json-ld document: " + failure.getFailureDetail()))); - } - - private Result> mapToFile(Map.Entry fileEntry) { - return getResourceFile(fileEntry.getValue()) - .map(file1 -> Map.entry(fileEntry.getKey(), file1)); + TxCachedDocumentRegistry.getDocuments().forEach(result -> result + .onSuccess(c -> jsonLdService.registerCachedDocument(c.url(), c.resource())) + .onFailure(failure -> monitor.warning("Failed to register cached json-ld document: " + failure.getFailureDetail())) + ); } } diff --git a/core/json-ld-core/src/main/java/org/eclipse/tractusx/edc/jsonld/TxCachedDocumentRegistry.java b/core/json-ld-core/src/main/java/org/eclipse/tractusx/edc/jsonld/TxCachedDocumentRegistry.java new file mode 100644 index 0000000000..09cf0450b8 --- /dev/null +++ b/core/json-ld-core/src/main/java/org/eclipse/tractusx/edc/jsonld/TxCachedDocumentRegistry.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2026 Think-it GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.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.tractusx.edc.edr.spi.CoreConstants.EDC_CONTEXT; +import static org.eclipse.tractusx.edc.jsonld.JsonLdExtension.TX_AUTH_CONTEXT; + +public class TxCachedDocumentRegistry { + + public static final String CREDENTIALS_V_1 = "https://www.w3.org/2018/credentials/v1"; + public static final String SECURITY_JWS_V1 = "https://w3id.org/security/suites/jws-2020/v1"; + public static final String SECURITY_ED25519_V1 = "https://w3id.org/security/suites/ed25519-2020/v1"; + + public static Stream> getDocuments() { + return Map.of( + "credential-v1.jsonld", CREDENTIALS_V_1, + "security-jws-2020.jsonld", SECURITY_JWS_V1, + "security-ed25519-2020.jsonld", SECURITY_ED25519_V1, + "tx-auth-v1.jsonld", TX_AUTH_CONTEXT, + "edc-v1.jsonld", EDC_CONTEXT + ).entrySet().stream() + .map(entry -> getResourceUri("document/" + entry.getKey()) + .map(uri -> new JsonLdContext(uri, entry.getValue()))); + } + + static Result getResourceUri(String name) { + var uri = TxCachedDocumentRegistry.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())); + } + } +} diff --git a/core/json-ld-core/src/test/java/org/eclipse/tractusx/edc/jsonld/JsonLdExtensionTest.java b/core/json-ld-core/src/test/java/org/eclipse/tractusx/edc/jsonld/JsonLdExtensionTest.java index 0bb5d4115c..35a143111c 100644 --- a/core/json-ld-core/src/test/java/org/eclipse/tractusx/edc/jsonld/JsonLdExtensionTest.java +++ b/core/json-ld-core/src/test/java/org/eclipse/tractusx/edc/jsonld/JsonLdExtensionTest.java @@ -29,9 +29,9 @@ import java.net.URI; -import static org.eclipse.tractusx.edc.jsonld.JsonLdExtension.CREDENTIALS_V_1; -import static org.eclipse.tractusx.edc.jsonld.JsonLdExtension.SECURITY_ED25519_V1; -import static org.eclipse.tractusx.edc.jsonld.JsonLdExtension.SECURITY_JWS_V1; +import static org.eclipse.tractusx.edc.jsonld.TxCachedDocumentRegistry.CREDENTIALS_V_1; +import static org.eclipse.tractusx.edc.jsonld.TxCachedDocumentRegistry.SECURITY_ED25519_V1; +import static org.eclipse.tractusx.edc.jsonld.TxCachedDocumentRegistry.SECURITY_JWS_V1; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; diff --git a/core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxCachedDocumentRegistry.java b/core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxCachedDocumentRegistry.java new file mode 100644 index 0000000000..d06b675188 --- /dev/null +++ b/core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxCachedDocumentRegistry.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2026 Think-it GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.cx; + +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.tractusx.edc.cx.CxJsonLdExtension.CX_ODRL_CONTEXT; +import static org.eclipse.tractusx.edc.cx.CxJsonLdExtension.CX_POLICY_2025_09_CONTEXT; + +public class CxCachedDocumentRegistry { + + public static Stream> getDocuments() { + return Map.of( + "cx-policy-v1.jsonld", CX_POLICY_2025_09_CONTEXT, + "cx-odrl.jsonld", CX_ODRL_CONTEXT + ).entrySet().stream() + .map(entry -> getResourceUri("document/" + entry.getKey()) + .map(uri -> new JsonLdContext(uri, entry.getValue()))); + } + + static Result getResourceUri(String name) { + var uri = CxCachedDocumentRegistry.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())); + } + } +} diff --git a/core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxJsonLdExtension.java b/core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxJsonLdExtension.java index 4515fb0cc4..2437c646d4 100644 --- a/core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxJsonLdExtension.java +++ b/core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxJsonLdExtension.java @@ -23,17 +23,12 @@ import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import java.io.File; -import java.util.Map; - import static org.eclipse.edc.api.management.ManagementApi.MANAGEMENT_SCOPE; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.DSP_SCOPE_V_2025_1; -import static org.eclipse.tractusx.edc.core.utils.FileUtils.getResourceFile; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_NS; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_PREFIX; @@ -45,10 +40,6 @@ public class CxJsonLdExtension implements ServiceExtension { public static final String CX_ODRL_CONTEXT = "https://w3id.org/catenax/2025/9/policy/odrl.jsonld"; public static final String CX_POLICY_2025_09_CONTEXT = "https://w3id.org/catenax/2025/9/policy/context.jsonld"; - private static final String PREFIX = "document" + File.separator; - private static final Map FILES = Map.of( - CX_POLICY_2025_09_CONTEXT, PREFIX + "cx-policy-v1.jsonld", - CX_ODRL_CONTEXT, PREFIX + "cx-odrl.jsonld"); @Inject private JsonLd jsonLdService; @@ -63,13 +54,10 @@ public void initialize(ServiceExtensionContext context) { jsonLdService.registerContext(CX_POLICY_2025_09_CONTEXT, MANAGEMENT_SCOPE); - FILES.entrySet().stream().map(this::mapToFile) - .forEach(result -> result.onSuccess(entry -> jsonLdService.registerCachedDocument(entry.getKey(), entry.getValue().toURI())) - .onFailure(failure -> monitor.warning("Failed to register cached json-ld document: " + failure.getFailureDetail()))); + CxCachedDocumentRegistry.getDocuments().forEach(result -> result + .onSuccess(c -> jsonLdService.registerCachedDocument(c.url(), c.resource())) + .onFailure(failure -> monitor.warning("Failed to register cached json-ld document: " + failure.getFailureDetail())) + ); } - private Result> mapToFile(Map.Entry fileEntry) { - return getResourceFile(fileEntry.getValue()) - .map(file1 -> Map.entry(fileEntry.getKey(), file1)); - } } diff --git a/edc-controlplane/edc-controlplane-base/build.gradle.kts b/edc-controlplane/edc-controlplane-base/build.gradle.kts index 3748567758..86a1b7a6d2 100644 --- a/edc-controlplane/edc-controlplane-base/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-base/build.gradle.kts @@ -32,9 +32,7 @@ configurations.all { } dependencies { - runtimeOnly(libs.edc.bom.controlplane.base) { - exclude(module = "dsp-2024") - } + runtimeOnly(libs.edc.bom.controlplane.base) runtimeOnly(libs.edc.bom.controlplane.dcp) implementation(project(":core:edr-core")) @@ -52,6 +50,11 @@ dependencies { implementation(project(":edc-extensions:dcp:tx-dcp")) implementation(project(":edc-extensions:dcp:tx-dcp-sts-div")) implementation(project(":edc-extensions:dcp:verifiable-presentation-cache")) + implementation(project(":edc-extensions:dsp:dsp-catalog-08")) + implementation(project(":edc-extensions:dsp:dsp-http-api-configuration-08")) + implementation(project(":edc-extensions:dsp:dsp-http-dispatcher-08")) + implementation(project(":edc-extensions:dsp:dsp-negotiation-08")) + implementation(project(":edc-extensions:dsp:dsp-transfer-process-08")) implementation(project(":edc-extensions:edr:edr-api-v2")) implementation(project(":edc-extensions:edr:edr-callback")) implementation(project(":edc-extensions:tokenrefresh-handler")) diff --git a/edc-dataplane/edc-dataplane-base/build.gradle.kts b/edc-dataplane/edc-dataplane-base/build.gradle.kts index fa69a9e5a1..8c105884cc 100644 --- a/edc-dataplane/edc-dataplane-base/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-base/build.gradle.kts @@ -41,7 +41,6 @@ dependencies { implementation(project(":edc-extensions:tokenrefresh-handler")) implementation(project(":edc-extensions:event-subscriber")) implementation(project(":edc-extensions:non-finite-provider-push:non-finite-provider-push-core")) - implementation(project(":edc-extensions:provision-additional-headers")) implementation(project(":edc-extensions:dataplane:dataflow:dataflow-api")) implementation(project(":edc-extensions:dataplane:dataflow:dataflow-service")) diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java index 602fd3737c..cc817ca68e 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java @@ -38,6 +38,7 @@ import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.spi.result.ServiceResult; +import org.eclipse.edc.spi.result.StoreResult; import org.eclipse.edc.spi.security.Vault; import org.eclipse.edc.spi.types.domain.DataAddress; import org.eclipse.edc.token.rules.ExpirationIssuedAtValidationRule; @@ -59,6 +60,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; @@ -66,7 +68,9 @@ import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.AUDIENCE; import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.EXPIRATION_TIME; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AUDIENCE_PROPERTY; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.EDR_PROPERTY_EXPIRES_IN; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.EDR_PROPERTY_REFRESH_AUDIENCE; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.EDR_PROPERTY_REFRESH_ENDPOINT; @@ -220,15 +224,6 @@ public Result obtainToken(TokenParameters tokenParameters, Objects.requireNonNull(tokenParameters, "TokenParameters must be non-null."); Objects.requireNonNull(backendDataAddress, "DataAddress must be non-null."); - - //create a refresh token - var refreshTokenResult = createToken(TokenParameters.Builder.newInstance().build()); - if (refreshTokenResult.failed()) { - var msg = "Could not generate refresh token: %s".formatted(refreshTokenResult.getFailureDetail()); - monitor.debug(msg); - return Result.failure(msg); - } - var accessTokenResult = createToken(tokenParameters); if (accessTokenResult.failed()) { var msg = "Could not generate access token: %s".formatted(accessTokenResult.getFailureDetail()); @@ -236,15 +231,13 @@ public Result obtainToken(TokenParameters tokenParameters, return Result.failure(msg); } - // the edrAdditionalData contains the refresh token, which is NOT supposed to be put in the DB - // note: can't use DBI (double-bracket initialization) here, because SonarCloud will complain about it - var additionalDataForStorage = new HashMap<>(additionalTokenData); - additionalDataForStorage.put("authType", "bearer"); + var accessToken = accessTokenResult.getContent(); + var storeResult = storeAccessTokenData(tokenParameters, backendDataAddress, additionalTokenData, accessToken); - // the ClaimToken is created based solely on the TokenParameters. The additional information (refresh token...) is persisted separately - var claimToken = ClaimToken.Builder.newInstance().claims(tokenParameters.getClaims()).build(); - var accessTokenData = new AccessTokenData(accessTokenResult.getContent().id(), claimToken, backendDataAddress, additionalDataForStorage); - var storeResult = accessTokenDataStore.store(accessTokenData); + if (storeResult.failed()) { + monitor.severe("Could not store AccessTokenData: %s".formatted(storeResult.getFailureDetail())); + return Result.failure(storeResult.getFailureMessages()); + } var participantContextServiceResult = participantContextSupplier.get(); if (participantContextServiceResult.failed()) { @@ -254,11 +247,18 @@ public Result obtainToken(TokenParameters tokenParameters, } var participantContext = participantContextServiceResult.getContent(); - storeRefreshToken(accessTokenResult.getContent().id(), new RefreshToken(refreshTokenResult.getContent().tokenRepresentation().getToken(), + var refreshTokenResult = createToken(TokenParameters.Builder.newInstance().build()); + if (refreshTokenResult.failed()) { + var msg = "Could not generate refresh token: %s".formatted(refreshTokenResult.getFailureDetail()); + monitor.debug(msg); + return Result.failure(msg); + } + + storeRefreshToken(accessToken.id(), new RefreshToken(refreshTokenResult.getContent().tokenRepresentation().getToken(), tokenExpirySeconds, refreshEndpoint), participantContext); // the refresh token information must be returned in the EDR - var audience = additionalDataForStorage.get(AUDIENCE_PROPERTY); + var audience = additionalTokenData.get(AUDIENCE_PROPERTY); if (audience == null) { var msg = "Missing audience in the additional properties"; @@ -273,16 +273,11 @@ public Result obtainToken(TokenParameters tokenParameters, edrAdditionalData.put(EDR_PROPERTY_REFRESH_AUDIENCE, audience); var edrTokenRepresentation = TokenRepresentation.Builder.newInstance() - .token(accessTokenResult.getContent().tokenRepresentation().getToken()) // the access token + .token(accessToken.tokenRepresentation().getToken()) // the access token .additional(edrAdditionalData) //contains additional properties and the refresh token .expiresIn(tokenExpirySeconds) //todo: needed? .build(); - if (storeResult.failed()) { - monitor.severe("Could not store AccessTokenData: %s".formatted(storeResult.getFailureDetail())); - return Result.failure(storeResult.getFailureMessages()); - } - return Result.success(edrTokenRepresentation); } @@ -319,6 +314,26 @@ public ServiceResult revoke(String transferProcessId, String reason) { }); } + private StoreResult storeAccessTokenData(TokenParameters tokenParameters, DataAddress backendDataAddress, + Map additionalTokenData, TokenRepresentationWithId token) { + var additionalDataForStorage = new HashMap<>(additionalTokenData); + additionalDataForStorage.put("authType", "bearer"); + + var claimToken = ClaimToken.Builder.newInstance().claims(tokenParameters.getClaims()).build(); + + var sourceAddressBuilder = backendDataAddress.toBuilder(); + + Optional.ofNullable(additionalTokenData.get(AGREEMENT_ID_PROPERTY)) + .ifPresent(agreementId -> sourceAddressBuilder.property("header:Edc-Contract-Agreement-Id", agreementId)); + + Optional.ofNullable(additionalTokenData.get(BPN_PROPERTY)) + .ifPresent(bpn -> sourceAddressBuilder.property("header:Edc-Bpn", bpn)); + + var accessTokenData = new AccessTokenData(token.id(), claimToken, sourceAddressBuilder.build(), additionalDataForStorage); + + return accessTokenDataStore.store(accessTokenData); + } + private Result deleteTokenData(AccessTokenData tokenData) { var deletionResult = vault.deleteSecret(tokenData.id()); if (deletionResult.failed()) { diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplTest.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplTest.java index ce22a6468e..ad9d182330 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplTest.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplTest.java @@ -40,6 +40,7 @@ import org.eclipse.edc.token.spi.TokenValidationService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import java.time.Clock; import java.util.Map; @@ -49,7 +50,9 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.eclipse.tractusx.edc.dataplane.tokenrefresh.core.TestFunctions.createJwt; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AUDIENCE_PROPERTY; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.EDR_PROPERTY_EXPIRES_IN; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.EDR_PROPERTY_REFRESH_ENDPOINT; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.EDR_PROPERTY_REFRESH_TOKEN; @@ -95,15 +98,27 @@ void obtainToken() { when(tokenGenService.generate(any(), any(), any(TokenDecorator[].class))).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("foo-token").build())); when(accessTokenDataStore.store(any(AccessTokenData.class))).thenReturn(StoreResult.success()); + Map additionalTokenData = Map.of( + "fizz", "buzz", + "refreshToken", "getsOverwritten", + AUDIENCE_PROPERTY, "audience", + AGREEMENT_ID_PROPERTY, "contract-agreement-id", + BPN_PROPERTY, "BPN" + ); + + var result = accessTokenService.obtainToken(params, address, additionalTokenData); - var result = accessTokenService.obtainToken(params, address, Map.of("fizz", "buzz", "refreshToken", "getsOverwritten", AUDIENCE_PROPERTY, "audience")); assertThat(result).isSucceeded().extracting(TokenRepresentation::getToken).isEqualTo("foo-token"); assertThat(result.getContent().getAdditional()) .containsKeys("fizz", EDR_PROPERTY_REFRESH_TOKEN, EDR_PROPERTY_EXPIRES_IN, EDR_PROPERTY_REFRESH_ENDPOINT) .containsEntry(EDR_PROPERTY_REFRESH_TOKEN, "foo-token"); verify(tokenGenService, times(2)).generate(any(), any(), any(TokenDecorator[].class)); - verify(accessTokenDataStore).store(any(AccessTokenData.class)); + var captor = ArgumentCaptor.forClass(AccessTokenData.class); + verify(accessTokenDataStore).store(captor.capture()); + var storedAccessTokenData = captor.getValue(); + assertThat(storedAccessTokenData.dataAddress().getProperty("header:Edc-Contract-Agreement-Id")).isEqualTo("contract-agreement-id"); + assertThat(storedAccessTokenData.dataAddress().getProperty("header:Edc-Bpn")).isEqualTo("BPN"); } @Test @@ -127,7 +142,6 @@ void obtainToken_invalidParams() { .isInstanceOf(NullPointerException.class); assertThatThrownBy(() -> accessTokenService.obtainToken(TokenParameters.Builder.newInstance().build(), null, Map.of())) .isInstanceOf(NullPointerException.class); - } @Test @@ -170,7 +184,7 @@ void obtainToken_storingFails() { var result = accessTokenService.obtainToken(params, address, Map.of(AUDIENCE_PROPERTY, "audience")); assertThat(result).isFailed().detail().isEqualTo("test failure"); - verify(tokenGenService, times(2)).generate(any(), any(), any(TokenDecorator[].class)); + verify(tokenGenService, times(1)).generate(any(), any(), any(TokenDecorator[].class)); verify(accessTokenDataStore).store(any(AccessTokenData.class)); } diff --git a/edc-extensions/dcp/tx-dcp-sts-div/build.gradle.kts b/edc-extensions/dcp/tx-dcp-sts-div/build.gradle.kts index 45cbeedf6d..809c7c2cef 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/build.gradle.kts +++ b/edc-extensions/dcp/tx-dcp-sts-div/build.gradle.kts @@ -30,7 +30,6 @@ dependencies { implementation(libs.edc.spi.participant.context.single) implementation(libs.edc.auth.oauth2.client) - testImplementation(libs.edc.junit) testImplementation(testFixtures(libs.edc.lib.http)) } diff --git a/edc-extensions/dcp/verifiable-presentation-cache/build.gradle.kts b/edc-extensions/dcp/verifiable-presentation-cache/build.gradle.kts index 859b277f66..504b654ebd 100644 --- a/edc-extensions/dcp/verifiable-presentation-cache/build.gradle.kts +++ b/edc-extensions/dcp/verifiable-presentation-cache/build.gradle.kts @@ -27,10 +27,11 @@ dependencies { implementation(libs.edc.spi.decentralized.claims) implementation(libs.edc.spi.participant.context.single) implementation(libs.edc.lib.dcp) - implementation(libs.edc.verifiable.credentials) + implementation(libs.edc.lib.verifiable.credentials) implementation(libs.edc.identity.vc.ldp) implementation(libs.edc.identity.vc.jwt) - implementation(libs.edc.decentralized.claims.service) + implementation(libs.edc.iam.decentralized.claims.core) + implementation(libs.edc.iam.decentralized.claims.service) implementation(project(":spi:dcp-spi")) diff --git a/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java b/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java index 30cd1a965d..b144ceb4c5 100644 --- a/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java +++ b/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java @@ -129,6 +129,6 @@ private void registerTransformers() { dspApiTransformerRegistry.register(new JsonObjectToDataAddressDspaceTransformer(DSP_NAMESPACE_V_08)); dspApiTransformerRegistry.register(new JsonObjectFromPolicyTransformer(jsonBuilderFactory, participantIdMapper)); - dspApiTransformerRegistry.register(new JsonObjectFromDataAddressDspaceTransformer(jsonBuilderFactory, typeManager, JSON_LD)); + dspApiTransformerRegistry.register(new JsonObjectFromDataAddressDspaceTransformer(jsonBuilderFactory, typeManager, JSON_LD, DSP_NAMESPACE_V_08)); } } diff --git a/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_8_0__Add_DataAddressAlias.sql b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_8_0__Add_DataAddressAlias.sql new file mode 100644 index 0000000000..f81f496d16 --- /dev/null +++ b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_8_0__Add_DataAddressAlias.sql @@ -0,0 +1 @@ +ALTER TABLE edc_transfer_process ADD COLUMN data_address_alias text; diff --git a/edc-extensions/provision-additional-headers/README.md b/edc-extensions/provision-additional-headers/README.md deleted file mode 100644 index 61fe14873e..0000000000 --- a/edc-extensions/provision-additional-headers/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Provision: additional headers - -The goal of this extension is to provide additional headers to the request to the backend service done by the provider -in order to retrieve the data that will be given to the consumer. - -This gives for example the provider backend service the possibility to audit the data requests. - -The following headers are added to the `HttpDataAddress`: - -- `Edc-Contract-Agreement-Id`: the id of the contract agreement -- `Edc-Bpn`: the BPN of the consumer diff --git a/edc-extensions/provision-additional-headers/build.gradle.kts b/edc-extensions/provision-additional-headers/build.gradle.kts deleted file mode 100644 index f45163663d..0000000000 --- a/edc-extensions/provision-additional-headers/build.gradle.kts +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -plugins { - `maven-publish` - `java-library` -} - -dependencies { - implementation(project(":spi:core-spi")) - - implementation(libs.edc.spi.core) - implementation(libs.edc.spi.dataplane.dataplane) - implementation(libs.edc.spi.dataplane.http) - - testImplementation(libs.edc.junit) -} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersDeprovisioner.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersDeprovisioner.java deleted file mode 100644 index aac4b2c769..0000000000 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersDeprovisioner.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -// Some portions generated by claude-sonnet-4.6 - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.connector.dataplane.spi.provision.DeprovisionedResource; -import org.eclipse.edc.connector.dataplane.spi.provision.Deprovisioner; -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; -import org.eclipse.edc.spi.response.StatusResult; - -import java.util.concurrent.CompletableFuture; - -class AdditionalHeadersDeprovisioner implements Deprovisioner { - - private final String type; - - AdditionalHeadersDeprovisioner(String type) { - this.type = type; - } - - @Override - public String supportedType() { - return type; - } - - @Override - public CompletableFuture> deprovision(ProvisionResource resource) { - return CompletableFuture.completedFuture(StatusResult.success(DeprovisionedResource.Builder.from(resource).build())); - } -} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java deleted file mode 100644 index 3b1303a0bd..0000000000 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -// Some portions generated by claude-sonnet-4.6 - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.connector.dataplane.http.spi.HttpDataAddress; -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionedResource; -import org.eclipse.edc.connector.dataplane.spi.provision.Provisioner; -import org.eclipse.edc.spi.response.StatusResult; - -import java.util.concurrent.CompletableFuture; - -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; - -public class AdditionalHeadersProvisioner implements Provisioner { - - private final String type; - - public AdditionalHeadersProvisioner(String type) { - this.type = type; - } - - @Override - public String supportedType() { - return type; - } - - @Override - public CompletableFuture> provision(ProvisionResource resource) { - var addressBuilder = resource.getDataAddress().toBuilder(); - addressBuilder.property(HttpDataAddress.ADDITIONAL_HEADER + "Edc-Contract-Agreement-Id", (String) resource.getProperty(AGREEMENT_ID_PROPERTY)); - addressBuilder.property(HttpDataAddress.ADDITIONAL_HEADER + "Edc-Bpn", (String) resource.getProperty(BPN_PROPERTY)); - - var provisioned = ProvisionedResource.Builder.from(resource) - .dataAddress(addressBuilder.build()) - .build(); - - return CompletableFuture.completedFuture(StatusResult.success(provisioned)); - } -} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java deleted file mode 100644 index c3dff33df3..0000000000 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -// Some portions generated by claude-sonnet-4.6 - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.connector.dataplane.spi.DataFlow; -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; -import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGenerator; -import org.jetbrains.annotations.Nullable; - -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; - -class AdditionalHeadersResourceDefinitionGenerator implements ResourceDefinitionGenerator { - - private final String type; - - AdditionalHeadersResourceDefinitionGenerator(String type) { - this.type = type; - } - - @Override - public String supportedType() { - return type; - } - - @Override - public @Nullable ProvisionResource generate(DataFlow dataFlow) { - return ProvisionResource.Builder.newInstance() - .flowId(dataFlow.getId()) - .type(type) - .dataAddress(dataFlow.getSource()) - .property(AGREEMENT_ID_PROPERTY, dataFlow.getAgreementId()) - .property(BPN_PROPERTY, dataFlow.getProperties().get(BPN_PROPERTY)) - .build(); - } -} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java deleted file mode 100644 index f54baf3a36..0000000000 --- a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -// Some portions generated by claude-sonnet-4.6 - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionerManager; -import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGeneratorManager; -import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; - -import static org.eclipse.edc.dataaddress.httpdata.spi.HttpDataAddressSchema.HTTP_DATA_TYPE; -import static org.eclipse.tractusx.edc.proxy.ProxyHttpDataAddressSchema.PROXY_HTTP_DATA_TYPE; - -public class ProvisionAdditionalHeadersExtension implements ServiceExtension { - - @Inject - private ResourceDefinitionGeneratorManager resourceDefinitionGeneratorManager; - - @Inject - private ProvisionerManager provisionerManager; - - @Override - public void initialize(ServiceExtensionContext context) { - resourceDefinitionGeneratorManager.registerProviderGenerator(new AdditionalHeadersResourceDefinitionGenerator(HTTP_DATA_TYPE)); - resourceDefinitionGeneratorManager.registerProviderGenerator(new AdditionalHeadersResourceDefinitionGenerator(PROXY_HTTP_DATA_TYPE)); - provisionerManager.register(new AdditionalHeadersProvisioner(HTTP_DATA_TYPE)); - provisionerManager.register(new AdditionalHeadersProvisioner(PROXY_HTTP_DATA_TYPE)); - provisionerManager.register(new AdditionalHeadersDeprovisioner(HTTP_DATA_TYPE)); - provisionerManager.register(new AdditionalHeadersDeprovisioner(PROXY_HTTP_DATA_TYPE)); - } -} diff --git a/edc-extensions/provision-additional-headers/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/provision-additional-headers/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension deleted file mode 100644 index 4f1e44009a..0000000000 --- a/edc-extensions/provision-additional-headers/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ /dev/null @@ -1,21 +0,0 @@ -################################################################################# -# Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# Copyright (c) 2021,2023 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# 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. -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# SPDX-License-Identifier: Apache-2.0 -################################################################################# - -org.eclipse.tractusx.edc.provision.additionalheaders.ProvisionAdditionalHeadersExtension diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java deleted file mode 100644 index c4a319d790..0000000000 --- a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -// Some portions generated by claude-sonnet-4.6 - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.connector.dataplane.http.spi.HttpDataAddress; -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionedResource; -import org.eclipse.edc.spi.response.StatusResult; -import org.junit.jupiter.api.Test; - -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.assertj.core.api.InstanceOfAssertFactories.map; -import static org.assertj.core.api.InstanceOfAssertFactories.type; -import static org.eclipse.edc.dataaddress.httpdata.spi.HttpDataAddressSchema.HTTP_DATA_TYPE; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; - -class AdditionalHeadersProvisionerTest { - - private final AdditionalHeadersProvisioner provisioner = new AdditionalHeadersProvisioner(HTTP_DATA_TYPE); - - @Test - void supportedType_shouldReturnHttpData() { - assertThat(provisioner.supportedType()).isEqualTo(HTTP_DATA_TYPE); - } - - @Test - void shouldAddAdditionalHeaders() { - var address = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); - var resource = ProvisionResource.Builder.newInstance() - .flowId("flowId") - .type("HttpData") - .dataAddress(address) - .property(AGREEMENT_ID_PROPERTY, "contractId") - .property(BPN_PROPERTY, "bpn") - .build(); - - var result = provisioner.provision(resource); - - assertThat(result) - .succeedsWithin(5, SECONDS) - .matches(StatusResult::succeeded) - .extracting(StatusResult::getContent) - .asInstanceOf(type(ProvisionedResource.class)) - .extracting(ProvisionedResource::getDataAddress) - .extracting(a -> HttpDataAddress.Builder.newInstance().copyFrom(a).build()) - .extracting(HttpDataAddress::getAdditionalHeaders) - .asInstanceOf(map(String.class, String.class)) - .containsEntry("Edc-Contract-Agreement-Id", "contractId") - .containsEntry("Edc-Bpn", "bpn"); - } -} diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java deleted file mode 100644 index 39fef95580..0000000000 --- a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -// Some portions generated by claude-sonnet-4.6 - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.connector.dataplane.http.spi.HttpDataAddress; -import org.eclipse.edc.connector.dataplane.spi.DataFlow; -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; -import org.junit.jupiter.api.Test; - -import java.util.Map; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.assertj.core.api.InstanceOfAssertFactories.type; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.AGREEMENT_ID_PROPERTY; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.BPN_PROPERTY; - -class AdditionalHeadersResourceDefinitionGeneratorTest { - - private final AdditionalHeadersResourceDefinitionGenerator generator = new AdditionalHeadersResourceDefinitionGenerator("HttpData"); - - @Test - void supportedType_shouldReturnHttpData() { - assertThat(generator.supportedType()).isEqualTo("HttpData"); - } - - @Test - void shouldCreateResourceDefinitionWithDataAddressAndProperties() { - var source = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); - var dataFlow = DataFlow.Builder.newInstance() - .id("flowId") - .source(source) - .properties(Map.of(BPN_PROPERTY, "bpn", AGREEMENT_ID_PROPERTY, "contractId")) - .build(); - - var result = generator.generate(dataFlow); - - assertThat(result) - .asInstanceOf(type(ProvisionResource.class)) - .satisfies(resource -> { - assertThat(resource.getFlowId()).isEqualTo("flowId"); - assertThat(resource.getType()).isEqualTo("HttpData"); - assertThat(resource.getDataAddress()).isNotNull(); - assertThat(resource.getProperty(AGREEMENT_ID_PROPERTY)).isEqualTo("contractId"); - assertThat(resource.getProperty(BPN_PROPERTY)).isEqualTo("bpn"); - }); - } -} diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java deleted file mode 100644 index 964180c132..0000000000 --- a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ -// Some portions generated by claude-sonnet-4.6 - -package org.eclipse.tractusx.edc.provision.additionalheaders; - -import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionerManager; -import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGeneratorManager; -import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(DependencyInjectionExtension.class) -class ProvisionAdditionalHeadersExtensionTest { - - private final ResourceDefinitionGeneratorManager resourceDefinitionGeneratorManager = mock(); - private final ProvisionerManager provisionerManager = mock(); - - @BeforeEach - void setUp(ServiceExtensionContext context) { - context.registerService(ResourceDefinitionGeneratorManager.class, resourceDefinitionGeneratorManager); - context.registerService(ProvisionerManager.class, provisionerManager); - } - - @Test - void initializeShouldRegisterGeneratorAndProvisioners(ProvisionAdditionalHeadersExtension extension, ServiceExtensionContext context) { - extension.initialize(context); - - verify(resourceDefinitionGeneratorManager, times(2)).registerProviderGenerator(isA(AdditionalHeadersResourceDefinitionGenerator.class)); - verify(provisionerManager, times(2)).register(isA(AdditionalHeadersProvisioner.class)); - verify(provisionerManager, times(2)).register(isA(AdditionalHeadersDeprovisioner.class)); - } -} diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java index 2d4d332130..69361058a8 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java @@ -22,11 +22,12 @@ import org.eclipse.edc.iam.decentralizedclaims.sts.spi.service.StsAccountService; import org.eclipse.edc.iam.did.spi.document.Service; -import org.eclipse.edc.identityhub.spi.participantcontext.ParticipantContextService; +import org.eclipse.edc.identityhub.spi.participantcontext.IdentityHubParticipantContextService; import org.eclipse.edc.identityhub.spi.participantcontext.model.KeyDescriptor; import org.eclipse.edc.identityhub.spi.participantcontext.model.ParticipantManifest; import org.eclipse.edc.identityhub.spi.verifiablecredentials.store.CredentialStore; import org.eclipse.edc.junit.extensions.RuntimeExtension; +import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.security.Vault; import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer; import org.eclipse.tractusx.edc.tests.participant.TractusxDcpParticipantBase; @@ -35,7 +36,7 @@ public class DcpHelperFunctions { public static void configureParticipantContext(DataspaceIssuer issuer, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) { - var participantContextService = identityHubRuntime.getService(ParticipantContextService.class); + var participantContextService = identityHubRuntime.getService(IdentityHubParticipantContextService.class); var participantKey = issuer.getKeyPairAsJwk(); var key = KeyDescriptor.Builder.newInstance() @@ -57,7 +58,8 @@ public static void configureParticipantContext(DataspaceIssuer issuer, IdentityH .active(true) .build(); - participantContextService.createParticipantContext(participantManifest); + participantContextService.createParticipantContext(participantManifest) + .orElseThrow(f -> new EdcException("Cannot create participant context: " + f.getFailureDetail())); var vault = identityHubRuntime.getService(Vault.class); vault.storeSecret(issuer.getPrivateKeyAlias(), issuer.getPrivateKeyAsString()); @@ -80,7 +82,7 @@ public static void configureParticipant(TractusxDcpParticipantBase participant, } public static void configureParticipantContext(TractusxDcpParticipantBase participant, IdentityHubParticipant identityHubParticipant, RuntimeExtension identityHubRuntime) { - var participantContextService = identityHubRuntime.getService(ParticipantContextService.class); + var participantContextService = identityHubRuntime.getService(IdentityHubParticipantContextService.class); var participantKey = participant.getKeyPairAsJwk(); var key = KeyDescriptor.Builder.newInstance() diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java index 0b719a5237..accba6d38c 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java @@ -60,6 +60,7 @@ public Config getConfig() { settings.put("web.http.did.path", didApi.get().getPath()); settings.put("edc.iam.did.web.use.https", "false"); settings.put("edc.api.accounts.key", "password"); + settings.put("edc.encryption.strict", "false"); return ConfigFactory.fromMap(settings); } diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java index 62a4954678..ae8027f5b9 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.edc.compatibility.tests.transfer; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; +import jakarta.json.Json; import jakarta.json.JsonObject; import org.eclipse.edc.connector.controlplane.test.system.utils.PolicyFixtures; import org.eclipse.edc.junit.extensions.RuntimeExtension; @@ -59,15 +60,23 @@ import static com.github.tomakehurst.wiremock.client.WireMock.ok; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static io.restassured.http.ContentType.JSON; +import static jakarta.json.Json.createArrayBuilder; +import static jakarta.json.Json.createObjectBuilder; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.awaitility.Awaitility.await; import static org.eclipse.edc.connector.controlplane.test.system.utils.PolicyFixtures.noConstraintPolicy; import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates.STARTED; import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates.SUSPENDED; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.eclipse.tractusx.edc.compatibility.tests.fixtures.DcpHelperFunctions.configureParticipant; import static org.eclipse.tractusx.edc.compatibility.tests.fixtures.DcpHelperFunctions.configureParticipantContext; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.inForceDatePolicyLegacy; @CompatibilityTest @@ -238,7 +247,35 @@ protected void createResourcesOnProvider(TractusxDcpParticipantBase provider, St var contractPolicyId = provider.createPolicyDefinition(contractPolicy); var noConstraintPolicyId = provider.createPolicyDefinition(noConstraintPolicy()); - provider.createContractDefinition(assetId, UUID.randomUUID().toString(), noConstraintPolicyId, contractPolicyId); + createContractDefinitionLegacyManagementContext(provider, assetId, UUID.randomUUID().toString(), noConstraintPolicyId, contractPolicyId); + } + + public String createContractDefinitionLegacyManagementContext(TractusxDcpParticipantBase participant, String assetId, String definitionId, String accessPolicyId, String contractPolicyId) { + var requestBody = createObjectBuilder() + .add(CONTEXT, createArrayBuilder().add(EDC_CONNECTOR_MANAGEMENT_CONTEXT)) + .add(ID, definitionId) + .add(TYPE, "ContractDefinition") + .add(EDC_NAMESPACE + "accessPolicyId", accessPolicyId) + .add(EDC_NAMESPACE + "contractPolicyId", contractPolicyId) + .add(EDC_NAMESPACE + "assetsSelector", Json.createArrayBuilder() + .add(createObjectBuilder() + .add(TYPE, "Criterion") + .add(EDC_NAMESPACE + "operandLeft", EDC_NAMESPACE + "id") + .add(EDC_NAMESPACE + "operator", "=") + .add(EDC_NAMESPACE + "operandRight", assetId) + .build()) + .build()) + .build(); + + return participant.baseManagementRequest() + .contentType(JSON) + .body(requestBody) + .when() + .post("/contractdefinitions") + .then() + .log().ifValidationFails() + .statusCode(200) + .extract().jsonPath().getString(ID); } private @NotNull Map httpSourceDataAddress() { @@ -254,8 +291,8 @@ private static class ParticipantsArgProvider implements ArgumentsProvider { @Override public Stream provideArguments(ExtensionContext context) { return Stream.of( - Arguments.of(REMOTE_PARTICIPANT, LOCAL_PARTICIPANT, "dataspace-protocol-http"), - Arguments.of(LOCAL_PARTICIPANT, REMOTE_PARTICIPANT, "dataspace-protocol-http") + Arguments.of(REMOTE_PARTICIPANT, LOCAL_PARTICIPANT, DSP_08), + Arguments.of(LOCAL_PARTICIPANT, REMOTE_PARTICIPANT, DSP_08) ); } } diff --git a/edc-tests/e2e-fixtures/build.gradle.kts b/edc-tests/e2e-fixtures/build.gradle.kts index 7ba38a3c0c..7c3b110d21 100644 --- a/edc-tests/e2e-fixtures/build.gradle.kts +++ b/edc-tests/e2e-fixtures/build.gradle.kts @@ -34,7 +34,6 @@ dependencies { testFixturesApi(project(":core:json-ld-cx")) testFixturesApi(libs.edc.ext.jsonld) - testFixturesApi(libs.edc.core.token) testFixturesApi(libs.edc.junit) testFixturesApi(libs.edc.lib.cryptocommon) testFixturesApi(libs.edc.lib.jws2020) @@ -55,7 +54,6 @@ dependencies { testFixturesApi(testFixtures(libs.edc.api.management.test.fixtures)) - testFixturesApi(libs.edc.iam.decentralized.claims.core) testFixturesApi(libs.edc.verifiablecredentials.jwt) testFixturesApi(libs.awaitility) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/ParticipantEdrApi.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/ParticipantEdrApi.java index bb21ab5a02..97b9661008 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/ParticipantEdrApi.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/ParticipantEdrApi.java @@ -88,7 +88,7 @@ public ValidatableResponse getEdrRequest(String transferProcessId) { public ValidatableResponse getEdrWithRefresh(String transferProcessId, boolean autoRefresh) { return baseEdrRequest() .when() - .get("/v3/edrs/{id}/dataaddress?auto_refresh={auto_refresh}", transferProcessId, autoRefresh) + .get("/edrs/{id}/dataaddress?auto_refresh={auto_refresh}", transferProcessId, autoRefresh) .then() .log().ifError(); @@ -100,7 +100,7 @@ public ValidatableResponse getEdrWithRefresh(String transferProcessId, boolean a public ValidatableResponse refreshEdr(String transferProcessId) { return baseEdrRequest() .when() - .post("/v3/edrs/{id}/refresh", transferProcessId) + .post("/edrs/{id}/refresh", transferProcessId) .then() .log().ifError(); } @@ -130,7 +130,7 @@ public String negotiateEdr(TransferParticipant other, String assetId, JsonArray var response = baseEdrRequest() .when() .body(requestBody) - .post("/v3/edrs") + .post("/edrs") .then(); var body = response.extract().body().asString(); @@ -150,7 +150,7 @@ public JsonArray getEdrEntriesByContractNegotiationId(String contractNegotiation return baseEdrRequest() .when() .body(query) - .post("/v3/edrs/request") + .post("/edrs/request") .then() .statusCode(200) .extract() @@ -169,7 +169,7 @@ public JsonArray getEdrEntriesByAgreementId(String agreementId) { return baseEdrRequest() .when() .body(query) - .post("/v3/edrs/request") + .post("/edrs/request") .then() .statusCode(200) .extract() @@ -188,7 +188,7 @@ public JsonArray getEdrEntriesByAssetId(String assetId) { return baseEdrRequest() .when() .body(query) - .post("/v3/edrs/request") + .post("/edrs/request") .then() .statusCode(200) .extract() diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/TestRuntimeConfiguration.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/TestRuntimeConfiguration.java index f791872f03..b39d9118f4 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/TestRuntimeConfiguration.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/TestRuntimeConfiguration.java @@ -31,6 +31,7 @@ public class TestRuntimeConfiguration { public static final String PROVIDER_BPN = "BPNL0000PROVIDER"; public static final String PROVIDER_DID = DID_PREFIX + PROVIDER_NAME; public static final String DSP_08 = "dataspace-protocol-http"; + public static final String DSP_08_PATH = ""; public static final String DSP_2025 = "dataspace-protocol-http:2025-1"; public static final String DSP_2025_PATH = "/2025-1"; diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java index 9277015401..fc3344f230 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java @@ -26,7 +26,7 @@ import org.eclipse.edc.iam.did.spi.document.Service; import org.eclipse.edc.iam.did.spi.document.VerificationMethod; import org.eclipse.edc.identityhub.spi.keypair.KeyPairService; -import org.eclipse.edc.identityhub.spi.participantcontext.ParticipantContextService; +import org.eclipse.edc.identityhub.spi.participantcontext.IdentityHubParticipantContextService; import org.eclipse.edc.identityhub.spi.participantcontext.model.KeyDescriptor; import org.eclipse.edc.identityhub.spi.participantcontext.model.ParticipantManifest; import org.eclipse.edc.identityhub.spi.verifiablecredentials.model.VerifiableCredentialResource; @@ -90,7 +90,7 @@ public void configureParticipant(DataspaceIssuer issuer, RuntimeExtension runtim .participantContextId(getDid()) .did(getDid()) .build(); - var participantContextService = stsRuntimeExtension.getService(ParticipantContextService.class); + var participantContextService = stsRuntimeExtension.getService(IdentityHubParticipantContextService.class); var createParticipantContextResponse = participantContextService.createParticipantContext(participantManifest) .orElseThrow(f -> new EdcException("cannot create participant context: " + f.getFailureDetail())); diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxDcpParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxDcpParticipantBase.java index b39a1d26be..efac746704 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxDcpParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxDcpParticipantBase.java @@ -24,7 +24,7 @@ import org.eclipse.edc.spi.system.configuration.ConfigFactory; import java.net.URI; -import java.util.Map; +import java.util.HashMap; import java.util.Objects; import static org.eclipse.edc.util.io.Ports.getFreePort; @@ -42,18 +42,20 @@ public abstract class TractusxDcpParticipantBase extends TractusxParticipantBase protected String trustedIssuer; public Config dcpConfig() { - var additionalSettings = Map.of( - "edc.iam.sts.oauth.token.url", stsUri.get() + "/token", - "edc.iam.sts.oauth.client.id", getDid(), - "edc.iam.sts.oauth.client.secret.alias", "client_secret_alias", - "edc.ih.iam.id", getDid(), - "edc.ih.iam.publickey.alias", getFullKeyId(), - "edc.agent.identity.key", "client_id", - "edc.iam.trusted-issuer.issuer.id", trustedIssuer, - "edc.transfer.proxy.token.signer.privatekey.alias", getPrivateKeyAlias(), - "edc.transfer.proxy.token.verifier.publickey.alias", getFullKeyId(), - "edc.iam.did.web.use.https", "false" - ); + var additionalSettings = new HashMap() { + { + put("edc.iam.sts.oauth.token.url", stsUri.get() + "/token"); + put("edc.iam.sts.oauth.client.id", getDid()); + put("edc.iam.sts.oauth.client.secret.alias", "client_secret_alias"); + put("edc.ih.iam.id", getDid()); + put("edc.ih.iam.publickey.alias", getFullKeyId()); + put("edc.agent.identity.key", "client_id"); + put("edc.iam.trusted-issuer.issuer.id", trustedIssuer); + put("edc.transfer.proxy.token.signer.privatekey.alias", getPrivateKeyAlias()); + put("edc.transfer.proxy.token.verifier.publickey.alias", getFullKeyId()); + put("edc.iam.did.web.use.https", "false"); + } + }; return getConfig().merge(ConfigFactory.fromMap(additionalSettings)); } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java index 0c9519109e..9ddb9e0d18 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java @@ -25,9 +25,12 @@ import jakarta.json.JsonObject; import org.eclipse.edc.connector.controlplane.test.system.utils.Participant; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates; +import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.junit.utils.LazySupplier; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.system.configuration.ConfigFactory; +import org.eclipse.tractusx.edc.cx.CxCachedDocumentRegistry; +import org.eclipse.tractusx.edc.jsonld.TxCachedDocumentRegistry; import org.eclipse.tractusx.edc.tests.ParticipantConsumerDataPlaneApi; import org.eclipse.tractusx.edc.tests.ParticipantDataApi; import org.eclipse.tractusx.edc.tests.ParticipantEdrApi; @@ -56,6 +59,10 @@ import static org.eclipse.tractusx.edc.agreements.retirement.spi.types.AgreementsRetirementEntry.AR_ENTRY_TYPE; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_NAMESPACE; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.BPN_SUFFIX; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08_PATH; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025_PATH; /** @@ -131,10 +138,10 @@ public Config getConfig() { put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); put("edc.dataplane.api.public.baseurl", "%s/v2/data".formatted(dataPlanePublic.get())); put("edc.policy.validation.enabled", "true"); - put("edc.iam.did.web.use.https", "false"); put("edc.participant.context.id", "general-test-id"); put("tractusx.edc.participant.bpn", getBpn()); put("edc.iam.did.web.use.https", "false"); + put("edc.encryption.strict", "false"); } }; @@ -175,7 +182,7 @@ public void storeBusinessPartner(String bpn, String... groups) { .contentType(JSON) .body(body) .when() - .post("/v3/business-partner-groups") + .post("/business-partner-groups") .then() .statusCode(204); } @@ -192,7 +199,7 @@ public void updateBusinessPartner(String bpn, String... groups) { .contentType(JSON) .body(body) .when() - .put("/v3/business-partner-groups") + .put("/business-partner-groups") .then() .statusCode(204); } @@ -203,7 +210,7 @@ public void updateBusinessPartner(String bpn, String... groups) { public void deleteBusinessPartner(String bpn) { baseManagementRequest() .when() - .delete("/v3/business-partner-groups/{bpn}", bpn) + .delete("/business-partner-groups/{bpn}", bpn) .then() .statusCode(204); } @@ -218,7 +225,7 @@ public ValidatableResponse retireProviderAgreement(String agreementId) { .contentType(JSON) .body(body) .when() - .post("/v3/contractagreements/retirements") + .post("/contractagreements/retirements") .then(); } @@ -249,14 +256,14 @@ public ValidatableResponse getCatalog(TractusxParticipantBase provider) { .add(TYPE, "CatalogRequest") .add("counterPartyId", provider.id) .add("counterPartyAddress", provider.getProtocolUrl()) - .add("protocol", protocol); + .add("protocol", protocol.name()); return baseManagementRequest() .header("x-api-key", MANAGEMENT_API_KEY) .contentType(JSON) .when() .body(requestBodyBuilder.build()) - .post("/v3/catalog/request") + .post("/catalog/request") .then(); } @@ -265,7 +272,7 @@ public String getTransferProcessField(String transferProcessId, String fieldName return baseManagementRequest() .contentType(JSON) .when() - .get("/v3/transferprocesses/{id}", transferProcessId) + .get("/transferprocesses/{id}", transferProcessId) .then() .statusCode(200) .extract().body().jsonPath() @@ -274,9 +281,10 @@ public String getTransferProcessField(String transferProcessId, String fieldName public void triggerDataTransfer(String dataFlowId) { baseManagementRequest() + .basePath("v4alpha") .contentType(JSON) .when() - .post("/v4alpha/dataflows/{id}/trigger", dataFlowId) + .post("/dataflows/{id}/trigger", dataFlowId) .then() .log().ifError() .statusCode(204); @@ -284,22 +292,43 @@ public void triggerDataTransfer(String dataFlowId) { public ValidatableResponse discoverDspParameters(JsonObject requestBody) { return baseManagementRequest() + .basePath("v4alpha") .contentType(JSON) .body(requestBody) .when() - .post("/v4alpha/connectordiscovery/dspversionparams") + .post("/connectordiscovery/dspversionparams") .then(); } public ValidatableResponse discoverConnectorServices(JsonObject requestBody) { return baseManagementRequest() + .basePath("v4alpha") .contentType(JSON) .body(requestBody) .when() - .post("/v4alpha/connectordiscovery/connectors") + .post("/connectordiscovery/connectors") .then(); } + // The following functions have been implemented, because these helper methods were removed upstream + // They are needed for support of DSP version v0.8 + public void setProtocol(String protocol) { + if (DSP_2025.equals(protocol)) { + this.protocol = new Protocol(DSP_2025, DSP_2025_PATH); + } else { + this.protocol = new Protocol(DSP_08, DSP_08_PATH); + } + } + + public void setJsonLd(JsonLd jsonLd) { + this.jsonLd = jsonLd; + } + + public String getBaseUrl() { + return controlPlaneProtocol.get().toString(); + } + // End of section with helper functions removed from upstream + public static class Builder

> extends Participant.Builder { protected Builder(P participant) { super(participant); @@ -316,7 +345,7 @@ public B did(String did) { } public B protocolVersionPath(String path) { - this.participant.protocolVersionPath = path; + this.participant.protocol = new Protocol(this.participant.protocol.name(), path); return self(); } @@ -337,6 +366,15 @@ public P build() { this.participant.edrs = new ParticipantEdrApi(participant); this.participant.data = new ParticipantDataApi(); this.participant.dataPlane = new ParticipantConsumerDataPlaneApi(this.participant.dataPlaneProxy, Map.of("x-api-key", CONSUMER_PROXY_API_KEY)); + + TxCachedDocumentRegistry.getDocuments().forEach(result -> result + .onSuccess(c -> this.participant.jsonLd.registerCachedDocument(c.url(), c.resource())) + ); + + CxCachedDocumentRegistry.getDocuments().forEach(result -> result + .onSuccess(c -> this.participant.jsonLd.registerCachedDocument(c.url(), c.resource())) + ); + return participant; } } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/runtimes/PostgresExtension.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/runtimes/PostgresExtension.java index 56cbf820cc..af3b62b589 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/runtimes/PostgresExtension.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/runtimes/PostgresExtension.java @@ -24,8 +24,8 @@ import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExtensionContext; -import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.postgresql.PostgreSQLContainer; import java.sql.DriverManager; import java.sql.SQLException; @@ -44,12 +44,12 @@ public class PostgresExtension implements BeforeAllCallback, AfterAllCallback { private static final String USER = "postgres"; private static final String PASSWORD = "password"; private static final String DB_SCHEMA_NAME = "testschema"; - private final PostgreSQLContainer postgreSqlContainer; + private final PostgreSQLContainer postgreSqlContainer; private final String[] databases; public PostgresExtension(String... databases) { this.databases = databases; - this.postgreSqlContainer = new PostgreSQLContainer<>(getPostgresTestContainerName()) + this.postgreSqlContainer = new PostgreSQLContainer(getPostgresTestContainerName()) .withUsername(USER) .withPassword(PASSWORD); } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java index a2afc171e7..4c56e4003c 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java @@ -170,8 +170,7 @@ void httpPushNonFiniteDataTransfer() { consumer().terminateTransfer(consumerTransferProcessId); consumer().awaitTransferToBeInState(consumerTransferProcessId, TransferProcessStates.TERMINATED); - await().atMost(ASYNC_TIMEOUT) - .untilAsserted(() -> dataFlowIsInState(providerTransferProcessId, DataFlowStates.DEPROVISIONED)); + await().untilAsserted(() -> dataFlowIsInState(providerTransferProcessId, DataFlowStates.TERMINATED)); } private void waitAndAssert(Duration duration, Runnable... assertions) { diff --git a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java index f04c0b5a8c..f6d329ed82 100644 --- a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java +++ b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java @@ -71,8 +71,7 @@ public class CatalogTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @@ -80,8 +79,7 @@ public class CatalogTest { .name(PROVIDER_NAME) .id(PROVIDER_DID) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @RegisterExtension diff --git a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java index 2f20d0f379..f807dbfd76 100644 --- a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java +++ b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java @@ -49,6 +49,7 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08_PATH; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; @@ -66,7 +67,7 @@ public class CatalogTestDspV08 { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_08) + .protocol(DSP_08, DSP_08_PATH) .build(); @@ -74,7 +75,7 @@ public class CatalogTestDspV08 { .name(PROVIDER_NAME) .id(PROVIDER_DID) .bpn(PROVIDER_BPN) - .protocol(DSP_08) + .protocol(DSP_08, DSP_08_PATH) .build(); @RegisterExtension diff --git a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/AzureToAzureTest.java b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/AzureToAzureTest.java index caa3c7de9e..988bf49255 100644 --- a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/AzureToAzureTest.java +++ b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/AzureToAzureTest.java @@ -312,7 +312,7 @@ void transferFile_targetContainerNotExist_shouldFail(Vault vault) { private JsonObjectBuilder createFlowRequestBuilder(JsonObjectBuilder sourceDataAddress, JsonObjectBuilder destinationDataAddress) { return Json.createObjectBuilder() - .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/v0.8/")) + .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/2025/1/")) .add("@type", EDC_DATA_FLOW_START_MESSAGE_TYPE) .add("@id", UUID.randomUUID().toString()) .add("processId", UUID.randomUUID().toString()) diff --git a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/MultiCloudTest.java b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/MultiCloudTest.java index 5aa89193f3..67f237c980 100644 --- a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/MultiCloudTest.java +++ b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/MultiCloudTest.java @@ -101,7 +101,7 @@ void transferFile_azureToS3MultipleFiles(Vault vault) { var bucketName = MINIO_CONTAINER.createBucket(); var request = Json.createObjectBuilder() - .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/v0.8/")) + .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/2025/1/")) .add("@type", EDC_DATA_FLOW_START_MESSAGE_TYPE) .add("@id", UUID.randomUUID().toString()) .add("processId", UUID.randomUUID().toString()) @@ -155,7 +155,7 @@ void transferFile_azureToS3(Vault vault) { var bucketName = MINIO_CONTAINER.createBucket(); var request = Json.createObjectBuilder() - .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/v0.8/")) + .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/2025/1/")) .add("@type", EDC_DATA_FLOW_START_MESSAGE_TYPE) .add("@id", UUID.randomUUID().toString()) .add("processId", UUID.randomUUID().toString()) @@ -214,7 +214,7 @@ void transferFile_s3ToAzureMultipleFiles(Vault vault) { """.formatted(blobStoreClient.generateAccountSas(containerName))); var request = Json.createObjectBuilder() - .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/v0.8/")) + .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/2025/1/")) .add("@type", EDC_DATA_FLOW_START_MESSAGE_TYPE) .add("@id", UUID.randomUUID().toString()) .add("processId", UUID.randomUUID().toString()) @@ -276,7 +276,7 @@ void transferFile_s3ToAzureMultipleFiles_whenConsumerDefinesBloblName_success(Va """.formatted(blobStoreClient.generateAccountSas(containerName))); var request = Json.createObjectBuilder() - .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/v0.8/")) + .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/2025/1/")) .add("@type", EDC_DATA_FLOW_START_MESSAGE_TYPE) .add("@id", UUID.randomUUID().toString()) .add("processId", UUID.randomUUID().toString()) @@ -332,7 +332,7 @@ void transferFile_s3ToAzure(Vault vault) { """.formatted(blobStoreClient.generateAccountSas(containerName))); var request = Json.createObjectBuilder() - .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/v0.8/")) + .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/2025/1/")) .add("@type", EDC_DATA_FLOW_START_MESSAGE_TYPE) .add("@id", UUID.randomUUID().toString()) .add("processId", UUID.randomUUID().toString()) diff --git a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/S3ToS3Test.java b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/S3ToS3Test.java index 0c1050ee22..fafd1b79f8 100644 --- a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/S3ToS3Test.java +++ b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/S3ToS3Test.java @@ -212,7 +212,7 @@ private CompletableFuture uploadLargeFile(File file, String buc private JsonObject createDataFlowStartMessage(String sourceBucketName, String destinationBucketName, List additionalSourceAddressProperties, String processId) { return Json.createObjectBuilder() - .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/v0.8/")) + .add("@context", Json.createObjectBuilder().add("@vocab", EDC_NAMESPACE).add("dspace", "https://w3id.org/dspace/2025/1/")) .add("@type", EDC_DATA_FLOW_START_MESSAGE_TYPE) .add("@id", UUID.randomUUID().toString()) .add("processId", processId) diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java index b160b20a55..7beabf3920 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java @@ -25,14 +25,14 @@ import org.eclipse.edc.iam.decentralizedclaims.sts.spi.model.StsAccount; import org.eclipse.edc.iam.decentralizedclaims.sts.spi.service.StsAccountService; import org.eclipse.edc.identityhub.spi.keypair.KeyPairService; -import org.eclipse.edc.identityhub.spi.participantcontext.model.ParticipantContext; -import org.eclipse.edc.identityhub.spi.participantcontext.store.ParticipantContextStore; +import org.eclipse.edc.identityhub.spi.participantcontext.model.IdentityHubParticipantContext; import org.eclipse.edc.json.JacksonTypeManager; import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.junit.utils.LazySupplier; import org.eclipse.edc.keys.spi.PrivateKeyResolver; +import org.eclipse.edc.participantcontext.spi.store.ParticipantContextStore; import org.eclipse.edc.security.token.jwt.DefaultJwsSignerProvider; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.token.JwtGenerationService; @@ -90,8 +90,7 @@ public class DivConsumerPullTest extends AbstractDcpConsumerPullTest { .trustedIssuer(DATASPACE_ISSUER_PARTICIPANT.didUrl()) .divUri(DIV_URI) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); private static final DcpParticipant PROVIDER = DcpParticipant.Builder.newInstance() .name(PROVIDER_NAME) @@ -101,8 +100,7 @@ public class DivConsumerPullTest extends AbstractDcpConsumerPullTest { .trustedIssuer(DATASPACE_ISSUER_PARTICIPANT.didUrl()) .divUri(DIV_URI) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @RegisterExtension @@ -174,7 +172,7 @@ private static EmbeddedSecureTokenService tokenServiceFor(TokenGenerationService }); var participantContextStore = runtime.getService(ParticipantContextStore.class); - participantContextStore.create(ParticipantContext.Builder.newInstance() + participantContextStore.create(IdentityHubParticipantContext.Builder.newInstance() .participantContextId(participant.getDid()) .did(participant.getDid()) .apiTokenAlias(participant.getDid()).build()); diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java index b0f4391518..4bf90cb8b1 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/StsConsumerPullTest.java @@ -61,8 +61,7 @@ public class StsConsumerPullTest extends AbstractDcpConsumerPullTest { .credentialServiceUri(STS.credentialServiceUri()) .trustedIssuer(DATASPACE_ISSUER_PARTICIPANT.didUrl()) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); private static final DcpParticipant PROVIDER = DcpParticipant.Builder.newInstance() .name(PROVIDER_NAME) @@ -72,8 +71,7 @@ public class StsConsumerPullTest extends AbstractDcpConsumerPullTest { .credentialServiceUri(STS.credentialServiceUri()) .trustedIssuer(DATASPACE_ISSUER_PARTICIPANT.didUrl()) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @RegisterExtension diff --git a/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorDiscoveryTest.java b/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorDiscoveryTest.java index ea323c601c..2a06d121e2 100644 --- a/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorDiscoveryTest.java +++ b/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorDiscoveryTest.java @@ -69,8 +69,7 @@ public class ConnectorDiscoveryTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @@ -89,8 +88,8 @@ public class ConnectorDiscoveryTest { private static final DidDocument DIDDOCUMENT = DidDocument.Builder.newInstance() .id(LOCAL_PROVIDER_DID) .service(List.of( - new Service(LOCAL_PROVIDER_DID + "#connector", "DataService", PROVIDER_FULL_DSP.getProtocolUrl()), - new Service(LOCAL_PROVIDER_DID + "#connector2", "DataService", PROVIDER_DSP_V08.getProtocolUrl()), + new Service(LOCAL_PROVIDER_DID + "#connector", "DataService", PROVIDER_FULL_DSP.getBaseUrl()), + new Service(LOCAL_PROVIDER_DID + "#connector2", "DataService", PROVIDER_DSP_V08.getBaseUrl()), new Service(LOCAL_PROVIDER_DID + "#cs", "CredentialService", "http://dontcare"))) .build(); @@ -138,10 +137,10 @@ public void setup() throws Exception { @Test void discoveryShouldReturnDspParams_DidAsIdentifier() { var expectedProtocolString = "\"protocol\":\"dataspace-protocol-http:2025-1\""; - var expectedAddressString = "\"counterPartyAddress\":\"%s/2025-1\"".formatted(PROVIDER_FULL_DSP.getProtocolUrl()); + var expectedAddressString = "\"counterPartyAddress\":\"%s/2025-1\"".formatted(PROVIDER_FULL_DSP.getBaseUrl()); var expectedIdString = "\"counterPartyId\":\"%s\"".formatted(LOCAL_PROVIDER_DID); var expectedProtocolString2 = "\"protocol\":\"dataspace-protocol-http\""; - var expectedAddressString2 = "\"counterPartyAddress\":\"%s\"".formatted(PROVIDER_DSP_V08.getProtocolUrl()); + var expectedAddressString2 = "\"counterPartyAddress\":\"%s\"".formatted(PROVIDER_DSP_V08.getBaseUrl()); var expectedIdString2 = "\"counterPartyId\":\"%s\"".formatted(PROVIDER_DSP_V08.getBpn()); @@ -165,10 +164,10 @@ void discoveryShouldReturnDspParams_DidAsIdentifier() { @Test void discoveryShouldReturnDspParams_BpnAsIdentifier() { var expectedProtocolString = "\"protocol\":\"dataspace-protocol-http:2025-1\""; - var expectedAddressString = "\"counterPartyAddress\":\"%s/2025-1\"".formatted(PROVIDER_FULL_DSP.getProtocolUrl()); + var expectedAddressString = "\"counterPartyAddress\":\"%s/2025-1\"".formatted(PROVIDER_FULL_DSP.getBaseUrl()); var expectedIdString = "\"counterPartyId\":\"%s\"".formatted(LOCAL_PROVIDER_DID); var expectedProtocolString2 = "\"protocol\":\"dataspace-protocol-http\""; - var expectedAddressString2 = "\"counterPartyAddress\":\"%s\"".formatted(PROVIDER_DSP_V08.getProtocolUrl()); + var expectedAddressString2 = "\"counterPartyAddress\":\"%s\"".formatted(PROVIDER_DSP_V08.getBaseUrl()); var expectedIdString2 = "\"counterPartyId\":\"%s\"".formatted(PROVIDER_DSP_V08.getBpn()); var requestBody = createRequestBody(PROVIDER_FULL_DSP.getBpn(), emptyList()); diff --git a/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorParameterDiscoveryTest.java b/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorParameterDiscoveryTest.java index 6b5f50804a..fe07cb0685 100644 --- a/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorParameterDiscoveryTest.java +++ b/edc-tests/e2e/discovery-tests/src/test/java/org/eclipse/tractusx/edc/discovery/e2e/ConnectorParameterDiscoveryTest.java @@ -54,8 +54,7 @@ public class ConnectorParameterDiscoveryTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @@ -107,7 +106,7 @@ private static String resolveProviderBpn(String did) { @Test void discoveryShouldReturn2025DspParams_BpnAsIdentifier() { - var requestBody = createRequestBody(PROVIDER_FULL_DSP.getBpn(), PROVIDER_FULL_DSP.getProtocolUrl()); + var requestBody = createRequestBody(PROVIDER_FULL_DSP.getBpn(), PROVIDER_FULL_DSP.getBaseUrl()); var response = CONSUMER.discoverDspParameters(requestBody); @@ -116,7 +115,7 @@ void discoveryShouldReturn2025DspParams_BpnAsIdentifier() { assertThat(body) .isNotNull() - .contains("\"counterPartyAddress\":\"" + PROVIDER_FULL_DSP.getProtocolUrl() + "/2025-1\"") + .contains("\"counterPartyAddress\":\"" + PROVIDER_FULL_DSP.getBaseUrl() + "/2025-1\"") .contains("\"counterPartyId\":\"" + PROVIDER_FULL_DSP.getDid() + "\"") .contains("\"protocol\":\"" + "dataspace-protocol-http:2025-1" + "\""); } @@ -124,7 +123,7 @@ void discoveryShouldReturn2025DspParams_BpnAsIdentifier() { @Test void discoveryShouldReturn2025DspParams_DidAsIdentifier() { - var requestBody = createRequestBody(PROVIDER_FULL_DSP.getDid(), PROVIDER_FULL_DSP.getProtocolUrl()); + var requestBody = createRequestBody(PROVIDER_FULL_DSP.getDid(), PROVIDER_FULL_DSP.getBaseUrl()); var response = CONSUMER.discoverDspParameters(requestBody); @@ -133,7 +132,7 @@ void discoveryShouldReturn2025DspParams_DidAsIdentifier() { assertThat(body) .isNotNull() - .contains("\"counterPartyAddress\":\"" + PROVIDER_FULL_DSP.getProtocolUrl() + "/2025-1\"") + .contains("\"counterPartyAddress\":\"" + PROVIDER_FULL_DSP.getBaseUrl() + "/2025-1\"") .contains("\"counterPartyId\":\"" + PROVIDER_FULL_DSP.getDid() + "\"") .contains("\"protocol\":\"" + "dataspace-protocol-http:2025-1" + "\""); } @@ -141,7 +140,7 @@ void discoveryShouldReturn2025DspParams_DidAsIdentifier() { @Test void discoveryShouldReturn08DspParams_whenDsp2025NotAvailable_BpnAsIdentifier() { - var requestBody = createRequestBody(PROVIDER_DSP_V08.getBpn(), PROVIDER_DSP_V08.getProtocolUrl()); + var requestBody = createRequestBody(PROVIDER_DSP_V08.getBpn(), PROVIDER_DSP_V08.getBaseUrl()); var response = CONSUMER.discoverDspParameters(requestBody); @@ -150,7 +149,7 @@ void discoveryShouldReturn08DspParams_whenDsp2025NotAvailable_BpnAsIdentifier() assertThat(body) .isNotNull() - .contains("\"counterPartyAddress\":\"" + PROVIDER_DSP_V08.getProtocolUrl()) + .contains("\"counterPartyAddress\":\"" + PROVIDER_DSP_V08.getBaseUrl()) .contains("\"counterPartyId\":\"" + PROVIDER_DSP_V08.getBpn() + "\"") .contains("\"protocol\":\"" + "dataspace-protocol-http" + "\""); } @@ -158,7 +157,7 @@ void discoveryShouldReturn08DspParams_whenDsp2025NotAvailable_BpnAsIdentifier() @Test void discoveryShouldReturn08DspParams_whenDsp2025NotAvailable_DidAsIdentifier() { - var requestBody = createRequestBody(PROVIDER_DSP_V08.getDid(), PROVIDER_DSP_V08.getProtocolUrl()); + var requestBody = createRequestBody(PROVIDER_DSP_V08.getDid(), PROVIDER_DSP_V08.getBaseUrl()); var response = CONSUMER.discoverDspParameters(requestBody); @@ -167,7 +166,7 @@ void discoveryShouldReturn08DspParams_whenDsp2025NotAvailable_DidAsIdentifier() assertThat(body) .isNotNull() - .contains("\"counterPartyAddress\":\"" + PROVIDER_DSP_V08.getProtocolUrl()) + .contains("\"counterPartyAddress\":\"" + PROVIDER_DSP_V08.getBaseUrl()) .contains("\"counterPartyId\":\"" + PROVIDER_DSP_V08.getBpn() + "\"") .contains("\"protocol\":\"" + "dataspace-protocol-http" + "\""); } @@ -175,7 +174,7 @@ void discoveryShouldReturn08DspParams_whenDsp2025NotAvailable_DidAsIdentifier() @Test void discoveryShouldReturn400_whenDidNotResolvable() { - var requestBody = createRequestBody(UNKNOWN_BPNL, PROVIDER_FULL_DSP.getProtocolUrl()); + var requestBody = createRequestBody(UNKNOWN_BPNL, PROVIDER_FULL_DSP.getBaseUrl()); var response = CONSUMER.discoverDspParameters(requestBody); @@ -193,7 +192,7 @@ void discoveryShouldReturn400_ifRequestHasMissingProps() { var requestBody = createObjectBuilder() .add(CONTEXT, createObjectBuilder().add("edc", EDC_NAMESPACE).add("tx", TX_NAMESPACE)) .add(TYPE, "tx:ConnectorDiscoveryRequest") - .add("edc:counterPartyAddress", PROVIDER_FULL_DSP.getProtocolUrl()) + .add("edc:counterPartyAddress", PROVIDER_FULL_DSP.getBaseUrl()) .build(); var response = CONSUMER.discoverDspParameters(requestBody); @@ -209,7 +208,7 @@ void discoveryShouldReturn400_ifRequestHasMissingProps() { @Test void discoveryShouldReturn502_ifMetadaEndpointNotReachable() { - var requestBody = createRequestBody(PROVIDER_FULL_DSP.getBpn(), PROVIDER_FULL_DSP.getProtocolUrl() + "/not-existing"); + var requestBody = createRequestBody(PROVIDER_FULL_DSP.getBpn(), PROVIDER_FULL_DSP.getBaseUrl() + "/not-existing"); var response = CONSUMER.discoverDspParameters(requestBody); @@ -235,7 +234,7 @@ void discoveryShouldReturn502_whenProviderEndpointNotReachable() { @Test void discoveryShouldReturn400_whenNoProtocolsAvailable() { - var requestBody = createRequestBody(PROVIDER_NO_PROTOCOLS.getBpn(), PROVIDER_NO_PROTOCOLS.getProtocolUrl()); + var requestBody = createRequestBody(PROVIDER_NO_PROTOCOLS.getBpn(), PROVIDER_NO_PROTOCOLS.getBaseUrl()); var response = CONSUMER.discoverDspParameters(requestBody); diff --git a/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/NegotiateEdrTest.java b/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/NegotiateEdrTest.java index effefbb47c..a5d2fe6acc 100644 --- a/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/NegotiateEdrTest.java +++ b/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/NegotiateEdrTest.java @@ -80,16 +80,14 @@ public class NegotiateEdrTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); private static final TransferParticipant PROVIDER = TransferParticipant.Builder.newInstance() .name(PROVIDER_NAME) .id(PROVIDER_DID) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @RegisterExtension diff --git a/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AzureToAzureEndToEndTest.java b/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AzureToAzureEndToEndTest.java index 1a04021698..5bcd5d2bb7 100644 --- a/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AzureToAzureEndToEndTest.java +++ b/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AzureToAzureEndToEndTest.java @@ -72,15 +72,13 @@ public class AzureToAzureEndToEndTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); private static final TransferParticipant PROVIDER = TransferParticipant.Builder.newInstance() .name(PROVIDER_NAME) .id(PROVIDER_DID) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); private static final int AZURITE_HOST_PORT = getFreePort(); diff --git a/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/S3ToS3EndToEndTest.java b/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/S3ToS3EndToEndTest.java index aebddde99c..ef868dfede 100644 --- a/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/S3ToS3EndToEndTest.java +++ b/edc-tests/e2e/end2end-transfer-cloud/src/test/java/org/eclipse/tractusx/edc/tests/transfer/S3ToS3EndToEndTest.java @@ -64,15 +64,13 @@ public class S3ToS3EndToEndTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); private static final TransferParticipant PROVIDER = TransferParticipant.Builder.newInstance() .name(PROVIDER_NAME) .id(PROVIDER_DID) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @RegisterExtension diff --git a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/auth/DelegatedAuthEndToEndTest.java b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/auth/DelegatedAuthEndToEndTest.java index 21ea90b25e..6ec5828abb 100644 --- a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/auth/DelegatedAuthEndToEndTest.java +++ b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/auth/DelegatedAuthEndToEndTest.java @@ -66,7 +66,7 @@ void shouldDelegateAuth() { CONNECTOR.baseManagementRequest() .header("Authorization", "Bearer " + token) .contentType(ContentType.JSON) - .post("/v3/assets/request") + .post("/assets/request") .then() .log().ifValidationFails() .statusCode(200); diff --git a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java index f05f275241..e8a3679e0b 100644 --- a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java +++ b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java @@ -125,7 +125,7 @@ private ValidatableResponse createContractDefinitionRequest(String definitionId, .contentType(JSON) .body(requestBody.build()) .when() - .post("/v3/contractdefinitions") + .post("/contractdefinitions") .then(); } diff --git a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java index da68180053..470acdde80 100644 --- a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java +++ b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java @@ -248,7 +248,7 @@ public Stream provideArguments(ExtensionContext extensionCo private Response createPolicyDefinition(JsonObject policy) { JsonObject requestBody = Json.createObjectBuilder().add("@context", Json.createObjectBuilder().add("@vocab", "https://w3id.org/edc/v0.0.1/ns/")).add("@type", "PolicyDefinition").add("policy", policy).build(); - return (Response) PROVIDER.baseManagementRequest().contentType(ContentType.JSON).body(requestBody).when().post("/v3/policydefinitions", new Object[0]).then().extract(); + return (Response) PROVIDER.baseManagementRequest().contentType(ContentType.JSON).body(requestBody).when().post("/policydefinitions", new Object[0]).then().extract(); } private static JsonObject policyFromRules(String ruleType, String policyDefinition, JsonObject... rules) { diff --git a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyMonitorEndToEndTest.java b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyMonitorEndToEndTest.java index 0dc7836061..f8ec9534f0 100644 --- a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyMonitorEndToEndTest.java +++ b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyMonitorEndToEndTest.java @@ -63,8 +63,7 @@ public class PolicyMonitorEndToEndTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @@ -72,8 +71,7 @@ public class PolicyMonitorEndToEndTest { .name(PROVIDER_NAME) .id(PROVIDER_DID) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @RegisterExtension diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java index 761a005493..cb300c566f 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java @@ -62,16 +62,14 @@ public class RetireAgreementTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); private static final TransferParticipant PROVIDER = TransferParticipant.Builder.newInstance() .name(PROVIDER_NAME) .id(PROVIDER_DID) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .enableEventSubscription() .build(); diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java index 5083d2b746..787855cfe5 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java @@ -52,7 +52,6 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025; -import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025_PATH; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; @@ -449,8 +448,8 @@ class Dsp2025to2025 extends Tests { @BeforeAll static void beforeAll() { CONSUMER.setJsonLd(CONSUMER_RUNTIME.getService(JsonLd.class)); - CONSUMER.setProtocol(DSP_2025, DSP_2025_PATH); - PROVIDER.setProtocol(DSP_2025, DSP_2025_PATH); + CONSUMER.setProtocol(DSP_2025); + PROVIDER.setProtocol(DSP_2025); } } } \ No newline at end of file diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPushEndToEndTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPushEndToEndTest.java index 0e124a856c..c08cc4948d 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPushEndToEndTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPushEndToEndTest.java @@ -36,7 +36,6 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025; -import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025_PATH; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; @@ -133,8 +132,8 @@ public RuntimeExtension consumerRuntime() { @BeforeAll static void beforeAll() { CONSUMER.setJsonLd(CONSUMER_RUNTIME.getService(JsonLd.class)); - CONSUMER.setProtocol(DSP_2025, DSP_2025_PATH); - PROVIDER.setProtocol(DSP_2025, DSP_2025_PATH); + CONSUMER.setProtocol(DSP_2025); + PROVIDER.setProtocol(DSP_2025); } } } diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java index 53c7af70b0..6f3c7f9015 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java @@ -79,15 +79,13 @@ public class TransferWithTokenRefreshTest { .name(CONSUMER_NAME) .id(CONSUMER_DID) .bpn(CONSUMER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); private static final TransferParticipant PROVIDER = TransferParticipant.Builder.newInstance() .name(PROVIDER_NAME) .id(PROVIDER_DID) .bpn(PROVIDER_BPN) - .protocol(DSP_2025) - .protocolVersionPath(DSP_2025_PATH) + .protocol(DSP_2025, DSP_2025_PATH) .build(); @RegisterExtension diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/TransferProcessServiceStub.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/TransferProcessServiceStub.java index 2bf880c54e..1ecf47bcee 100644 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/TransferProcessServiceStub.java +++ b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/TransferProcessServiceStub.java @@ -20,11 +20,10 @@ package org.eclipse.tractusx.edc.mock.services; import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessService; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.DeprovisionedResource; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.ProvisionResponse; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest; import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.NotifyPreparedCommand; +import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.NotifyStartedCommand; import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.ResumeTransferCommand; import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.SuspendTransferCommand; import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.TerminateTransferCommand; @@ -86,11 +85,6 @@ public ServiceResult> search(QuerySpec query) { return responseQueue.getNext(Void.class, "Error resuming TransferProcess: %s"); } - @Override - public @NotNull ServiceResult deprovision(String transferProcessId) { - return responseQueue.getNext(Void.class, "Error deprovisioning TransferProcess: %s"); - } - @Override public @NotNull ServiceResult initiateTransfer(ParticipantContext participantContext, TransferRequest request) { return responseQueue.getNext(TransferProcess.class, "Error initiating TransferProcess: %s"); @@ -102,12 +96,7 @@ public ServiceResult notifyPrepared(NotifyPreparedCommand command) { } @Override - public ServiceResult completeDeprovision(String transferProcessId, DeprovisionedResource resource) { - return responseQueue.getNext(Void.class, "Error completing/deprovisioning TransferProcess: %s"); - } - - @Override - public ServiceResult addProvisionedResource(String transferProcessId, ProvisionResponse response) { - return responseQueue.getNext(Void.class, "Error adding Provisioned resource to TransferProcess: %s"); + public ServiceResult notifyStarted(NotifyStartedCommand command) { + return responseQueue.getNext(Void.class, "Error notifying started on TransferProcess: %s"); } } diff --git a/edc-tests/runtime/runtime-discovery/runtime-discovery-no-protocols/build.gradle.kts b/edc-tests/runtime/runtime-discovery/runtime-discovery-no-protocols/build.gradle.kts index 456104b07c..315b49372b 100644 --- a/edc-tests/runtime/runtime-discovery/runtime-discovery-no-protocols/build.gradle.kts +++ b/edc-tests/runtime/runtime-discovery/runtime-discovery-no-protocols/build.gradle.kts @@ -28,8 +28,11 @@ dependencies { exclude(module = "cx-dcp") exclude(module = "tx-dcp-sts-div") exclude(module = "dataspace-protocol") - exclude(module = "dsp-08") - exclude(module = "dsp-2024") + exclude(module = "dsp-catalog-08") + exclude(module = "dsp-http-api-configuration-08") + exclude(module = "dsp-http-dispatcher-08") + exclude(module = "dsp-negotiation-08") + exclude(module = "dsp-transfer-process-08") exclude(module = "dsp-2025") exclude(module = "dsp-http-api-configuration-2025") } diff --git a/edc-tests/runtime/runtime-discovery/runtime-discovery-with-dsp-v08/build.gradle.kts b/edc-tests/runtime/runtime-discovery/runtime-discovery-with-dsp-v08/build.gradle.kts index 87fb81155b..6ba211c59d 100644 --- a/edc-tests/runtime/runtime-discovery/runtime-discovery-with-dsp-v08/build.gradle.kts +++ b/edc-tests/runtime/runtime-discovery/runtime-discovery-with-dsp-v08/build.gradle.kts @@ -28,7 +28,6 @@ dependencies { exclude(module = "cx-dcp") exclude(module = "tx-dcp-sts-div") exclude(module = "dataspace-protocol") - exclude(module= "dsp-2024") exclude(module= "dsp-2025") exclude(module = "dsp-http-api-configuration-2025") } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2306fd9577..e2285331fe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ format.version = "1.1" [versions] -edc = "0.15.1" +edc = "0.16.0" edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.34.0" @@ -59,7 +59,6 @@ edc-spi-participant-context-single = { module = "org.eclipse.edc:participant-con edc-spi-policy = { module = "org.eclipse.edc:policy-spi", version.ref = "edc" } edc-spi-policyengine = { module = "org.eclipse.edc:policy-engine-spi", version.ref = "edc" } edc-spi-protocol = { module = "org.eclipse.edc:protocol-spi", version.ref = "edc" } -edc-spi-request-policy-context = { module = "org.eclipse.edc:request-policy-context-spi", version.ref = "edc" } edc-spi-sts = { module = "org.eclipse.edc:sts-spi", version.ref = "edc" } edc-spi-token = { module = "org.eclipse.edc:token-spi", version.ref = "edc" } edc-spi-transaction-datasource = { module = "org.eclipse.edc:transaction-datasource-spi", version.ref = "edc" } @@ -89,6 +88,7 @@ edc-api-management = { module = "org.eclipse.edc:management-api", version.ref = edc-api-management-test-fixtures = { module = "org.eclipse.edc:management-api-test-fixtures", version.ref = "edc" } edc-iam-mock = { module = "org.eclipse.edc:iam-mock", version.ref = "edc" } edc-iam-decentralized-claims-core = { module = "org.eclipse.edc:decentralized-claims-core", version.ref = "edc" } +edc-iam-decentralized-claims-service = { module = "org.eclipse.edc:decentralized-claims-service", version.ref = "edc" } edc-auth-tokenbased = { module = "org.eclipse.edc:auth-tokenbased", version.ref = "edc" } edc-auth-configuration = { module = "org.eclipse.edc:auth-configuration", version.ref = "edc" } edc-auth-delegated = { module = "org.eclipse.edc:auth-delegated", version.ref = "edc" } @@ -98,7 +98,6 @@ edc-ext-http = { module = "org.eclipse.edc:http", version.ref = "edc" } edc-ext-jsonld = { module = "org.eclipse.edc:json-ld", version.ref = "edc" } edc-validator-data-address-http-data = { module = "org.eclipse.edc:validator-data-address-http-data", version.ref = "edc" } edc-runtime-metamodel = { module = "org.eclipse.edc:runtime-metamodel", version.ref = "edc" } -edc-verifiable-credentials = { module = "org.eclipse.edc:verifiable-credentials", version.ref = "edc" } # EDC lib dependencies edc-lib-api = { module = "org.eclipse.edc:api-lib", version.ref = "edc" } @@ -126,6 +125,7 @@ edc-lib-dsp-transfer-process-validation= { module = "org.eclipse.edc:dsp-transfe edc-lib-dsp-transfer-process-http-api= { module = "org.eclipse.edc:dsp-transfer-process-http-api-lib", version.ref = "edc" } edc-lib-dsp-transfer-process-transform= { module = "org.eclipse.edc:dsp-transfer-process-transform-lib", version.ref = "edc" } edc-lib-dcp = { module = "org.eclipse.edc:decentralized-claims-lib", version.ref = "edc" } +edc-lib-verifiable-credentials = { module = "org.eclipse.edc:verifiable-credentials-lib", version.ref = "edc" } # implementations edc-sql-assetindex = { module = "org.eclipse.edc:asset-index-sql", version.ref = "edc" } diff --git a/settings.gradle.kts b/settings.gradle.kts index cc8b93c55d..491f119c82 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -69,7 +69,6 @@ include(":edc-extensions:migrations:control-plane-migration") include(":edc-extensions:migrations:data-plane-migration") include(":edc-extensions:tokenrefresh-handler") include(":edc-extensions:bdrs-client") -include(":edc-extensions:provision-additional-headers") include(":edc-extensions:event-subscriber") include(":edc-extensions:edr:edr-api-v2") include(":edc-extensions:edr:edr-callback") From 2af73594e751b5e950f4ad2070e66f7a212f3b92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:03:25 +0200 Subject: [PATCH 096/259] chore(deps): bump aws from 2.44.4 to 2.44.6 (#2837) Bumps `aws` from 2.44.4 to 2.44.6. Updates `software.amazon.awssdk:s3` from 2.44.4 to 2.44.6 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.44.4 to 2.44.6 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.44.6 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.44.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e2285331fe..28cd801dfd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.44.4" +aws = "2.44.6" azure-storage-blob = "12.33.4" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" From 861f72e60269a8d7cff2811a69e92519caf3a2d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:03:54 +0200 Subject: [PATCH 097/259] chore(deps): bump org.slf4j:slf4j-api from 2.0.17 to 2.0.18 (#2836) Bumps org.slf4j:slf4j-api from 2.0.17 to 2.0.18. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-version: 2.0.18 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index c26a6cd210..bf726da413 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -63,7 +63,7 @@ allprojects { apply(plugin = "jacoco") dependencies { - implementation("org.slf4j:slf4j-api:2.0.17") + implementation("org.slf4j:slf4j-api:2.0.18") constraints { plugins.apply("org.gradle.java-test-fixtures") From aaf58d857a039085db9ca11f89afe773da37c348 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:04:26 +0200 Subject: [PATCH 098/259] chore(deps): bump zizmorcore/zizmor-action from 0.5.3 to 0.5.5 (#2833) Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.5.3 to 0.5.5. - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/b1d7e1fb5de872772f31590499237e7cce841e8e...a16621b09c6db4281f81a93cb393b05dcd7b7165) --- updated-dependencies: - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/workflow-security-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index ec835fd3f9..a63138d493 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -56,7 +56,7 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 + uses: zizmorcore/zizmor-action@a16621b09c6db4281f81a93cb393b05dcd7b7165 # v0.5.5 with: version: "1.23.1" advanced-security: "true" From 8c0429749f2db37cc18e63073ca01dd2baab22bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:04:54 +0200 Subject: [PATCH 099/259] chore(deps): bump github/codeql-action from 4.35.4 to 4.35.5 (#2832) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.4 to 4.35.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/68bde559dea0fdcac2102bfdf6230c5f70eb485e...9e0d7b8d25671d64c341c19c0152d693099fb5ba) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.35.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 4 ++-- .github/workflows/kics.yml | 2 +- .github/workflows/workflow-security-lint.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index df8c78267c..4b9da7fa8f 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 85c107fd46..01e7c8888d 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index a63138d493..3eabfdb38d 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 + uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 if: always() with: sarif_file: results-fixed.sarif From 548ba2f1a8db2dbb20002e2c6239cf465e60cb67 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:05:19 +0200 Subject: [PATCH 100/259] chore(deps): bump step-security/harden-runner from 2.19.1 to 2.19.3 (#2830) Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.19.1 to 2.19.3. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/a5ad31d6a139d249332a2605b85202e8c0b78450...ab7a9404c0f3da075243ca237b5fac12c98deaa5) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.19.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 2 +- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/deployment-test.yaml | 6 ++--- .github/workflows/draft-release.yaml | 2 +- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 2 +- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 6 ++--- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/stale-bot.yml | 2 +- .github/workflows/triage-issue.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 4 ++-- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 4 ++-- 18 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 4b9da7fa8f..7f888e0103 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -55,7 +55,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index bd994e93a5..1ec4ec891e 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Copy labels from linked issue to PR diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 736b9a0fab..1cd28efd35 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: test-prepare steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -84,7 +84,7 @@ jobs: "v1.33.7" ] steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index dd2bef0b49..ae2b33c035 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -44,7 +44,7 @@ jobs: is_official_release: ${{ steps.validation.outputs.is_official_release }} steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index 69cbc28514..a36f3a374c 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 01a69d4d7c..4a98eec2ad 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit ############## diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 01e7c8888d..f52d16810b 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index dd6e23bc89..0c9be41f8b 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -38,7 +38,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index 47d37c7cfe..29e7977b21 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -72,7 +72,7 @@ jobs: HAS_SWAGGER: ${{ steps.secret-presence.outputs.HAS_SWAGGER }} steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Check whether secrets exist @@ -95,7 +95,7 @@ jobs: DATED: ${{ steps.get-version.outputs.DATED }} steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -165,7 +165,7 @@ jobs: if: ${{ needs.determine-version.outputs.DATED == 'true' }} steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0029a0130..d5f57f6081 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -56,7 +56,7 @@ jobs: update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -148,7 +148,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -188,7 +188,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -251,7 +251,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit @@ -294,7 +294,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Checkout main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 1cace0aba2..2f7ee612e7 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -42,7 +42,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Checkout Repository diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 21f1e4e108..b579b9448f 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -39,7 +39,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 diff --git a/.github/workflows/triage-issue.yml b/.github/workflows/triage-issue.yml index a470f7cfc5..8f3149ce0f 100644 --- a/.github/workflows/triage-issue.yml +++ b/.github/workflows/triage-issue.yml @@ -36,7 +36,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - run: gh issue edit "$NUMBER" --add-label "$LABELS" diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index 5bbe913ecd..7ef4a16e12 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -71,7 +71,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 0d8d934f5d..fafa5e2d8d 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 8a14a7505f..98260067bd 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: [ test-prepare ] steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index dfea67d52b..af7a73fb24 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -36,7 +36,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -152,7 +152,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -172,7 +172,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -192,7 +192,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -214,7 +214,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -248,7 +248,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -265,7 +265,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -287,7 +287,7 @@ jobs: contents: write steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 3eabfdb38d..86b6db2f1a 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -46,7 +46,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit @@ -71,7 +71,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 + uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit From abd77a0474b6265e7029c2aabde3013a78e1b96b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:05:40 +0200 Subject: [PATCH 101/259] chore(deps): bump trufflesecurity/trufflehog from 3.95.2 to 3.95.3 (#2829) Bumps [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) from 3.95.2 to 3.95.3. - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/17456f8c7d042d8c82c9a8ca9e937231f9f42e26...37b77001d0174ebec2fcca2bd83ff83a6d45a3ab) --- updated-dependencies: - dependency-name: trufflesecurity/trufflehog dependency-version: 3.95.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/secrets-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 2f7ee612e7..a21ddc54ea 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -53,7 +53,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@17456f8c7d042d8c82c9a8ca9e937231f9f42e26 + uses: trufflesecurity/trufflehog@37b77001d0174ebec2fcca2bd83ff83a6d45a3ab continue-on-error: true with: path: ./ # Scan the entire repository From ebe99c50c2aa7a1dfcef325e30d688b1a2ad9ee2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:06:03 +0200 Subject: [PATCH 102/259] chore(deps): bump gradle-wrapper from 9.5.0 to 9.5.1 (#2827) Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.5.0 to 9.5.1. - [Release notes](https://github.com/gradle/gradle/releases) - [Commits](https://github.com/gradle/gradle/compare/v9.5.0...v9.5.1) --- updated-dependencies: - dependency-name: gradle-wrapper dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b52fb7e713..df6a6ad763 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip networkTimeout=10000 retries=0 retryBackOffMs=500 From 155205af5fddd7c9d34961797dbe43505027a995 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:06:27 +0200 Subject: [PATCH 103/259] chore(deps): bump peaceiris/actions-gh-pages (#2834) Bumps [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/peaceiris/actions-gh-pages/releases) - [Changelog](https://github.com/peaceiris/actions-gh-pages/blob/main/CHANGELOG.md) - [Commits](https://github.com/peaceiris/actions-gh-pages/compare/4f9cc6602d3f66b9c108549d475ec49e8ef4d45e...84c30a85c19949d7eee79c4ff27748b70285e453) --- updated-dependencies: - dependency-name: peaceiris/actions-gh-pages dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/generate-and-publish-allure-report/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/generate-and-publish-allure-report/action.yml b/.github/actions/generate-and-publish-allure-report/action.yml index eb2ee4a627..eb8e2d99e0 100644 --- a/.github/actions/generate-and-publish-allure-report/action.yml +++ b/.github/actions/generate-and-publish-allure-report/action.yml @@ -49,7 +49,7 @@ runs: allure_report: ${{ inputs.version }} - name: Publish Allure test report to gh-pages - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0 with: github_token: ${{ inputs.token }} publish_dir: ./${{ inputs.version }} From b681283f28d9f8ac61b52d8b4fe3df3f95b4b568 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:06:46 +0200 Subject: [PATCH 104/259] chore(deps): bump io.swagger.core.v3.swagger-gradle-plugin (#2838) Bumps io.swagger.core.v3.swagger-gradle-plugin from 2.2.49 to 2.2.50. --- updated-dependencies: - dependency-name: io.swagger.core.v3.swagger-gradle-plugin dependency-version: 2.2.50 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 28cd801dfd..66f8b07bc1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -250,5 +250,5 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } shadow = { id = "com.gradleup.shadow", version = "9.4.1" } -swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.49" } +swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.50" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From d02bd957f6b0525236e3984ea7ee795081f7de5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:08:29 +0200 Subject: [PATCH 105/259] chore(deps): bump postgres (#2828) Bumps postgres from 18.3 to 18.4. --- updated-dependencies: - dependency-name: postgres dependency-version: '18.4' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile b/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile index 17b167998b..ed298d0373 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile +++ b/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile @@ -1,2 +1,2 @@ -FROM postgres:18.3 +FROM postgres:18.4 USER "Dummy" From b372f8b50e8e613499411b9d9fbacafbb24f4498 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:13:56 +0200 Subject: [PATCH 106/259] chore(deps): bump flyway from 12.5.0 to 12.6.1 (#2826) Bumps `flyway` from 12.5.0 to 12.6.1. Updates `org.flywaydb:flyway-core` from 12.5.0 to 12.6.1 Updates `org.flywaydb:flyway-database-postgresql` from 12.5.0 to 12.6.1 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.6.1 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.6.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 66f8b07bc1..e9b1727739 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ azure-storage-blob = "12.33.4" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" -flyway = "12.5.0" +flyway = "12.6.1" jackson = "2.21.3" jakarta-json = "2.1.3" junit = "6.0.3" From 24ab1383d6d89207af9385251f8e3a7e379fede2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:15:23 +0200 Subject: [PATCH 107/259] chore(deps): bump peaceiris/actions-gh-pages (#2835) Bumps [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/peaceiris/actions-gh-pages/releases) - [Changelog](https://github.com/peaceiris/actions-gh-pages/blob/main/CHANGELOG.md) - [Commits](https://github.com/peaceiris/actions-gh-pages/compare/4f9cc6602d3f66b9c108549d475ec49e8ef4d45e...84c30a85c19949d7eee79c4ff27748b70285e453) --- updated-dependencies: - dependency-name: peaceiris/actions-gh-pages dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-latest-versioned-snapshot/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-latest-versioned-snapshot/action.yml b/.github/actions/publish-latest-versioned-snapshot/action.yml index c023513318..e22a82864d 100644 --- a/.github/actions/publish-latest-versioned-snapshot/action.yml +++ b/.github/actions/publish-latest-versioned-snapshot/action.yml @@ -36,7 +36,7 @@ runs: echo "$VERSION" > lvs/latest-versioned-snapshot.txt - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0 with: github_token: ${{ env.GITHUB_TOKEN }} publish_dir: ./lvs From 6bb2986e7e153ae15d603c89cd19a0ffbffdeb1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 09:15:50 +0200 Subject: [PATCH 108/259] chore(deps): bump peaceiris/actions-gh-pages from 4.0.0 to 4.1.0 (#2831) Bumps [peaceiris/actions-gh-pages](https://github.com/peaceiris/actions-gh-pages) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/peaceiris/actions-gh-pages/releases) - [Changelog](https://github.com/peaceiris/actions-gh-pages/blob/main/CHANGELOG.md) - [Commits](https://github.com/peaceiris/actions-gh-pages/compare/4f9cc6602d3f66b9c108549d475ec49e8ef4d45e...84c30a85c19949d7eee79c4ff27748b70285e453) --- updated-dependencies: - dependency-name: peaceiris/actions-gh-pages dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/generate-and-publish-dependencies.yaml | 2 +- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-openapi-ui.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index a36f3a374c..c59209906d 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -65,7 +65,7 @@ jobs: cp DEPENDENCIES public/ - name: Publish to GitHub Pages if: ${{ github.ref_name == 'main' }} - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: public diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index 0c9be41f8b..e05946cd9d 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -50,7 +50,7 @@ jobs: cp core/json-ld-core/src/main/resources/document/tx-auth-v1.jsonld public/context/ - name: deploy to gh-pages - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./public diff --git a/.github/workflows/publish-openapi-ui.yml b/.github/workflows/publish-openapi-ui.yml index 1c48ead0ef..378912aeac 100644 --- a/.github/workflows/publish-openapi-ui.yml +++ b/.github/workflows/publish-openapi-ui.yml @@ -142,7 +142,7 @@ jobs: path: openapi pattern: "*-api" - name: Deploy to GitHub Pages - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: . From 8ce1d96e570b4f2843988984c538b9d64027095a Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Fri, 22 May 2026 09:47:11 +0200 Subject: [PATCH 109/259] fix: skip run "publish snapshot" during release (#2825) --- .github/workflows/release.yml | 2 ++ .github/workflows/run-all-tests.yml | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d5f57f6081..7ae32a535f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,6 +46,8 @@ jobs: run-all-tests: name: "Run All Tests" uses: ./.github/workflows/run-all-tests.yml + with: + publish: false # Gate validation: name: "Workflow Validation" diff --git a/.github/workflows/run-all-tests.yml b/.github/workflows/run-all-tests.yml index 8e5ab4d98d..5d9326432f 100644 --- a/.github/workflows/run-all-tests.yml +++ b/.github/workflows/run-all-tests.yml @@ -32,7 +32,19 @@ on: paths-ignore: - docs/** workflow_dispatch: + inputs: + publish: + description: "Publish snapshot" + required: false + type: boolean + default: false workflow_call: + inputs: + publish: + description: "Publish snapshot" + required: false + type: boolean + default: false schedule: - cron: 0 3 * * 1 # run on 03:00 UTC every Monday @@ -78,7 +90,7 @@ jobs: needs: [ summary ] permissions: contents: write - if: ${{ github.ref_name == 'main' || startsWith(github.ref_name, 'release/') }} + if: ${{ (github.ref_name == 'main' || startsWith(github.ref_name, 'release/')) && (github.event_name == 'push' || github.event_name == 'schedule' || inputs.publish == true) }} uses: ./.github/workflows/publish-new-snapshot.yaml with: dated_snapshot: ${{ github.event_name == 'schedule' }} From 0d1a6e707791a4d85a93cbe85ed656f833898228 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Fri, 22 May 2026 11:15:52 +0200 Subject: [PATCH 110/259] fix: write permission for release process (#2842) --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ae32a535f..a14825452a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,6 +45,8 @@ permissions: jobs: run-all-tests: name: "Run All Tests" + permissions: + contents: write uses: ./.github/workflows/run-all-tests.yml with: publish: false From dbc23fb4c51062a7ccc2dfdbc0602b463f02d33b Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Thu, 28 May 2026 17:24:48 +0200 Subject: [PATCH 111/259] chore: Change deprecated setting usage (#2843) * Change deprecated setting usage Signed-off-by: Lars Geyer-Blaumeiser * Fix build issues Signed-off-by: Lars Geyer-Blaumeiser * Adapt dcp default scope configuration Signed-off-by: Lars Geyer-Blaumeiser * Fix migration tests Signed-off-by: Lars Geyer-Blaumeiser * Fix sca issues Signed-off-by: Lars Geyer-Blaumeiser * Revert a change to fix the test Signed-off-by: Lars Geyer-Blaumeiser * Fix checkstyle Signed-off-by: Lars Geyer-Blaumeiser * Fix last settings issue Signed-off-by: Lars Geyer-Blaumeiser * Fix review issues Signed-off-by: Lars Geyer-Blaumeiser * Include review comments Signed-off-by: Lars Geyer-Blaumeiser --------- Signed-off-by: Lars Geyer-Blaumeiser --- .../tractusx/edc/core/utils/PathUtils.java | 2 +- .../edc/vault/memory/VaultSeedExtension.java | 11 ++- .../vault/memory/VaultSeedExtensionTest.java | 16 +++- .../SqlAgreementsBpnsStoreExtension.java | 5 +- ...SqlAgreementsRetirementStoreExtension.java | 5 +- .../identity/mapper/BdrsClientExtension.java | 41 ++++----- .../mapper/BdrsClientImplExtensionTest.java | 56 +++---------- ...SqlBusinessPartnerGroupStoreExtension.java | 7 +- .../DataPlaneProxyConsumerApiExtension.java | 36 ++++---- ...DataPlaneTokenRefreshServiceExtension.java | 83 ++++++++++--------- .../RemoteTokenServiceClientExtension.java | 7 +- .../sts/StsClientConfigurationExtension.java | 40 +++------ ...RemoteTokenServiceClientExtensionTest.java | 30 ++++--- .../StsClientConfigurationExtensionTest.java | 23 +++-- .../edc/iam/dcp/DcpDefaultScopeExtension.java | 7 +- .../index/sql/lock/SqlEdrLockExtension.java | 8 +- .../AbstractPostgresqlMigrationExtension.java | 9 +- .../TokenRefreshHandlerExtension.java | 20 +++-- 18 files changed, 204 insertions(+), 202 deletions(-) diff --git a/core/core-utils/src/main/java/org/eclipse/tractusx/edc/core/utils/PathUtils.java b/core/core-utils/src/main/java/org/eclipse/tractusx/edc/core/utils/PathUtils.java index f439ab596c..95501d8892 100644 --- a/core/core-utils/src/main/java/org/eclipse/tractusx/edc/core/utils/PathUtils.java +++ b/core/core-utils/src/main/java/org/eclipse/tractusx/edc/core/utils/PathUtils.java @@ -26,7 +26,7 @@ private PathUtils() { public static String removeTrailingSlash(String path) { var fixedPath = path; - if (fixedPath.endsWith("/")) { + if (fixedPath != null && fixedPath.endsWith("/")) { fixedPath = fixedPath.substring(0, fixedPath.length() - 1); } return fixedPath; diff --git a/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java b/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java index e0e43c2d00..be6598e149 100644 --- a/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java +++ b/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java @@ -37,8 +37,14 @@ @BaseExtension public class VaultSeedExtension implements ServiceExtension { - @Setting(value = "Secrets with which the vault gets initially populated. Specify as comma-separated list of key:secret pairs.") - public static final String VAULT_MEMORY_SECRETS_PROPERTY = "tx.edc.vault.secrets"; + static final String VAULT_MEMORY_SECRETS_PROPERTY = "tx.edc.vault.secrets"; + + @Setting( + key = VAULT_MEMORY_SECRETS_PROPERTY, + description = "Secrets with which the vault gets initially populated. Specify as comma-separated list of key:secret pairs.", + required = false) + private String seedSecrets; + public static final String NAME = "Vault Seed Extension"; @Inject @@ -54,7 +60,6 @@ public String name() { @Provider public Vault createInMemVault(ServiceExtensionContext context) { - var seedSecrets = context.getSetting(VAULT_MEMORY_SECRETS_PROPERTY, null); if (seedSecrets != null) { singleParticipantContextSupplier.get().map(ParticipantContext::getParticipantContextId) .onSuccess(participantContextId -> { diff --git a/edc-controlplane/edc-runtime-memory/src/test/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtensionTest.java b/edc-controlplane/edc-runtime-memory/src/test/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtensionTest.java index 3649ad5832..acac3629e1 100644 --- a/edc-controlplane/edc-runtime-memory/src/test/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtensionTest.java +++ b/edc-controlplane/edc-runtime-memory/src/test/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtensionTest.java @@ -19,6 +19,7 @@ package org.eclipse.tractusx.edc.vault.memory; +import org.eclipse.edc.boot.system.injection.ObjectFactory; import org.eclipse.edc.boot.vault.InMemoryVault; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; @@ -27,15 +28,17 @@ import org.eclipse.edc.spi.result.ServiceResult; import org.eclipse.edc.spi.security.Vault; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; +import java.util.Map; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -62,8 +65,15 @@ void name(VaultSeedExtension extension) { @ParameterizedTest @ValueSource(strings = { "key1:", "key1:value1", "key1:value1;", ";key1:value1", ";sdf;key1:value1" }) - void createInMemVault_validString(String secret, ServiceExtensionContext context, VaultSeedExtension extension) { - when(context.getSetting(eq(VaultSeedExtension.VAULT_MEMORY_SECRETS_PROPERTY), eq(null))).thenReturn(secret); + void createInMemVault_validString(String secret, ServiceExtensionContext context, ObjectFactory factory) { + var configMap = Map.of( + VaultSeedExtension.VAULT_MEMORY_SECRETS_PROPERTY, secret + ); + var config = ConfigFactory.fromMap(configMap); + when(context.getConfig()).thenReturn(config); + + var extension = factory.constructInstance(VaultSeedExtension.class); + extension.createInMemVault(context); verify(monitor, times(1)).debug(anyString()); } diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/SqlAgreementsBpnsStoreExtension.java b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/SqlAgreementsBpnsStoreExtension.java index 8a9fb4c72f..ea0a2e1f57 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/SqlAgreementsBpnsStoreExtension.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/SqlAgreementsBpnsStoreExtension.java @@ -39,9 +39,11 @@ public class SqlAgreementsBpnsStoreExtension implements ServiceExtension { protected static final String NAME = "SQL Agreement BPNs Store."; - @Setting(description = "Datasource name for the SQL AgreementsBpns store", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) private static final String DATASOURCE_SETTING_NAME = "edc.sql.store.contractnegotiation.datasource"; + @Setting(key = DATASOURCE_SETTING_NAME, description = "Datasource name for the SQL AgreementsBpns store", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + private String dataSourceName; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -59,7 +61,6 @@ public class SqlAgreementsBpnsStoreExtension implements ServiceExtension { @Provider public AgreementsBpnsStore sqlStore(ServiceExtensionContext context) { - var dataSourceName = context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); return new SqlAgreementsBpnsStore(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), queryExecutor, getStatements()); } diff --git a/edc-extensions/agreements/retirement-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/retirement/store/SqlAgreementsRetirementStoreExtension.java b/edc-extensions/agreements/retirement-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/retirement/store/SqlAgreementsRetirementStoreExtension.java index 543aa6c7f0..7d80f0f941 100644 --- a/edc-extensions/agreements/retirement-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/retirement/store/SqlAgreementsRetirementStoreExtension.java +++ b/edc-extensions/agreements/retirement-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/retirement/store/SqlAgreementsRetirementStoreExtension.java @@ -39,9 +39,11 @@ public class SqlAgreementsRetirementStoreExtension implements ServiceExtension { protected static final String NAME = "SQL Agreement Retirement Store."; - @Setting(value = "Datasource name for the SQL AgreementsRetirement store", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) private static final String DATASOURCE_SETTING_NAME = "tx.edc.sql.store.agreementretirement.datasource"; + @Setting(key = DATASOURCE_SETTING_NAME, description = "Datasource name for the SQL AgreementsRetirement store", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + private String dataSourceName; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -59,7 +61,6 @@ public class SqlAgreementsRetirementStoreExtension implements ServiceExtension { @Provider public AgreementsRetirementStore sqlStore(ServiceExtensionContext context) { - var dataSourceName = context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); return new SqlAgreementsRetirementStore(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), queryExecutor, getStatements()); } diff --git a/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java b/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java index 675949f89b..bbefa82c68 100644 --- a/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java +++ b/edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java @@ -25,10 +25,12 @@ import org.eclipse.edc.iam.decentralizedclaims.spi.SecureTokenService; import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Setting; +import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; @@ -36,7 +38,6 @@ import java.util.function.Supplier; -import static org.eclipse.tractusx.edc.core.utils.ConfigUtil.missingMandatoryProperty; import static org.eclipse.tractusx.edc.identity.mapper.BdrsClientExtension.NAME; @Extension(value = NAME) @@ -44,17 +45,21 @@ public class BdrsClientExtension implements ServiceExtension { public static final String NAME = "BPN/DID Resolution Service Client Extension"; public static final int DEFAULT_BDRS_CACHE_VALIDITY = 15 * 60; // 15 minutes - @Setting(value = "Base URL of the BDRS service", required = true) - public static final String BDRS_SERVER_URL_PROPERTY = "tx.edc.iam.dcp.bdrs.server.url"; - @Setting(value = "Base URL of the CredentialService, that belongs to this connector runtime. If not specified, the URL is resolved from this participant's DID document.") - public static final String CREDENTIAL_SERVICE_BASE_URL_PROPERTY = "tx.edc.iam.dcp.credentialservice.url"; + static final String BDRS_SERVER_URL_PROPERTY = "tx.edc.iam.dcp.bdrs.server.url"; - @Setting(value = "Validity period in seconds for the cached BPN/DID mappings. After this period a new resolution request will hit the server.", defaultValue = DEFAULT_BDRS_CACHE_VALIDITY + "") - public static final String BDRS_SERVER_CACHE_VALIDITY_PERIOD = "tx.edc.iam.dcp.bdrs.cache.validity"; + @Setting(key = BDRS_SERVER_URL_PROPERTY, description = "Base URL of the BDRS service") + private String bdrsServerUrl; - // this setting is already defined in IdentityAndTrustExtension - public static final String CONNECTOR_DID_PROPERTY = "edc.iam.issuer.id"; + static final String CREDENTIAL_SERVICE_BASE_URL_PROPERTY = "tx.edc.iam.dcp.credentialservice.url"; + + @Setting(key = CREDENTIAL_SERVICE_BASE_URL_PROPERTY, description = "Base URL of the CredentialService, that belongs to this connector runtime. If not specified, the URL is resolved from this participant's DID document.", required = false) + private String credentialServiceBaseUrl; + + private static final String BDRS_SERVER_CACHE_VALIDITY_PERIOD = "tx.edc.iam.dcp.bdrs.cache.validity"; + + @Setting(key = BDRS_SERVER_CACHE_VALIDITY_PERIOD, description = "Validity period in seconds for the cached BPN/DID mappings. After this period a new resolution request will hit the server.", defaultValue = DEFAULT_BDRS_CACHE_VALIDITY + "") + private int cacheValidityPeriod; @Inject private EdcHttpClient httpClient; @@ -76,21 +81,19 @@ public String name() { @Provider public BdrsClient getBdrsClient(ServiceExtensionContext context) { - var baseUrl = context.getConfig().getString(BDRS_SERVER_URL_PROPERTY); var monitor = context.getMonitor(); - var cacheValidity = context.getSetting(BDRS_SERVER_CACHE_VALIDITY_PERIOD, DEFAULT_BDRS_CACHE_VALIDITY); // get DID - var ownDid = context.getConfig().getString(CONNECTOR_DID_PROPERTY, null); - if (ownDid == null) { - missingMandatoryProperty(monitor, CONNECTOR_DID_PROPERTY); - } + var ownDid = participantContextSupplier.get().map(ParticipantContext::getIdentity).onFailure(f -> { + var message = "This connector is not configured properly, cannot continue. Error is: %s".formatted(f.getFailureDetail()); + monitor.severe(message); + throw new EdcException(message); + }).getContent(); // get CS URL Supplier urlSupplier; - var configuredUrl = context.getSetting(CREDENTIAL_SERVICE_BASE_URL_PROPERTY, null); - if (configuredUrl != null) { - urlSupplier = () -> configuredUrl; + if (credentialServiceBaseUrl != null) { + urlSupplier = () -> credentialServiceBaseUrl; } else { monitor.warning("No config value found for '%s'. As a fallback, the credentialService URL from this connector's DID document will be resolved.".formatted(CREDENTIAL_SERVICE_BASE_URL_PROPERTY)); @@ -104,7 +107,7 @@ public BdrsClient getBdrsClient(ServiceExtensionContext context) { } - return new BdrsClientImpl(baseUrl, cacheValidity, ownDid, urlSupplier, httpClient, monitor, typeManager.getMapper(), + return new BdrsClientImpl(bdrsServerUrl, cacheValidityPeriod, ownDid, urlSupplier, httpClient, monitor, typeManager.getMapper(), secureTokenService, credentialServiceClient, participantContextSupplier); } diff --git a/edc-extensions/bdrs-client/src/test/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImplExtensionTest.java b/edc-extensions/bdrs-client/src/test/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImplExtensionTest.java index 5711a2d93c..69acaae510 100644 --- a/edc-extensions/bdrs-client/src/test/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImplExtensionTest.java +++ b/edc-extensions/bdrs-client/src/test/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientImplExtensionTest.java @@ -23,28 +23,25 @@ import org.eclipse.edc.iam.did.spi.document.Service; import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.result.ServiceResult; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.system.configuration.Config; +import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; +import java.util.Map; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.tractusx.edc.identity.mapper.BdrsClientExtension.BDRS_SERVER_URL_PROPERTY; -import static org.eclipse.tractusx.edc.identity.mapper.BdrsClientExtension.CONNECTOR_DID_PROPERTY; -import static org.eclipse.tractusx.edc.identity.mapper.BdrsClientExtension.CREDENTIAL_SERVICE_BASE_URL_PROPERTY; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @ExtendWith(DependencyInjectionExtension.class) @@ -52,50 +49,32 @@ class BdrsClientImplExtensionTest { private final Monitor monitor = mock(); private final DidResolverRegistry resolverRegistry = mock(); + private final SingleParticipantContextSupplier participantContextSupplier = mock(SingleParticipantContextSupplier.class); @BeforeEach void setup(ServiceExtensionContext context) { context.registerService(Monitor.class, monitor); context.registerService(DidResolverRegistry.class, resolverRegistry); - } - - @Test - void createClient_whenUrlMissing_expectException(ServiceExtensionContext context, BdrsClientExtension extension) { - var cfg = mock(Config.class); - when(cfg.getString(eq(BDRS_SERVER_URL_PROPERTY))).thenThrow(new EdcException(BDRS_SERVER_URL_PROPERTY)); - when(context.getConfig()).thenReturn(cfg); - when(cfg.getString(eq(BDRS_SERVER_URL_PROPERTY), isNull())).thenReturn(null); - when(cfg.getString(eq(CONNECTOR_DID_PROPERTY), isNull())).thenReturn("did:web:self"); - when(cfg.getString(eq(CREDENTIAL_SERVICE_BASE_URL_PROPERTY), isNull())).thenReturn("https://credential.service"); - - assertThatThrownBy(() -> extension.getBdrsClient(context)).isInstanceOf(EdcException.class) - .hasMessageContaining(BDRS_SERVER_URL_PROPERTY); + context.registerService(SingleParticipantContextSupplier.class, participantContextSupplier); + var config = ConfigFactory.fromMap(Map.of(BDRS_SERVER_URL_PROPERTY, "https://bdrs.server")); + when(context.getConfig()).thenReturn(config); } @Test void createClient_whenNoCredentialServiceUrl_shouldInvokeResolver(ServiceExtensionContext context, BdrsClientExtension extension) { - var cfg = mock(Config.class); - when(context.getConfig()).thenReturn(cfg); - when(cfg.getString(eq(BDRS_SERVER_URL_PROPERTY), isNull())).thenReturn("https://bdrs.server"); - when(cfg.getString(eq(CREDENTIAL_SERVICE_BASE_URL_PROPERTY), isNull())).thenReturn(null); - when(cfg.getString(eq(CONNECTOR_DID_PROPERTY), isNull())).thenReturn("did:web:self"); when(resolverRegistry.resolve(anyString())).thenReturn(Result.success(DidDocument.Builder.newInstance().service(List.of(new Service(null, "CredentialService", "http://credential.service"))).build())); + when(participantContextSupplier.get()).thenReturn(ServiceResult.success(ParticipantContext.Builder.newInstance().identity("did:example:123").participantContextId("uuid").build())); extension.getBdrsClient(context); verify(monitor).withPrefix(anyString()); verify(monitor).warning("No config value found for 'tx.edc.iam.dcp.credentialservice.url'. As a fallback, the credentialService URL from this connector's DID document will be resolved."); - verifyNoMoreInteractions(monitor); } @Test void createClient_whenResolverFails_expectLogError(ServiceExtensionContext context, BdrsClientExtension extension) { - var cfg = mock(Config.class); - when(context.getConfig()).thenReturn(cfg); - when(cfg.getString(eq(BDRS_SERVER_URL_PROPERTY), isNull())).thenReturn("https://bdrs.server"); - when(cfg.getString(eq(CREDENTIAL_SERVICE_BASE_URL_PROPERTY), isNull())).thenReturn(null); - when(cfg.getString(eq(CONNECTOR_DID_PROPERTY), isNull())).thenReturn("did:web:self"); when(resolverRegistry.resolve(anyString())).thenReturn(Result.failure("test failure")); + when(participantContextSupplier.get()).thenReturn(ServiceResult.success(ParticipantContext.Builder.newInstance().identity("did:example:123").participantContextId("uuid").build())); var client = extension.getBdrsClient(context); @@ -104,18 +83,5 @@ void createClient_whenResolverFails_expectLogError(ServiceExtensionContext conte // the DID url resolver is only invoked on-demand, so no eager-loading of the DID document verify(monitor, never()).severe("Resolving the credentialService URL failed. This runtime won't be able to communicate with BDRS. Error: test failure."); - verifyNoMoreInteractions(monitor); - } - - @Test - void createClient_whenNoDid_expectLogError(ServiceExtensionContext context, BdrsClientExtension extension) { - var cfg = mock(Config.class); - when(context.getConfig()).thenReturn(cfg); - when(cfg.getString(eq(BDRS_SERVER_URL_PROPERTY), isNull())).thenReturn("https://bdrs.server"); - when(cfg.getString(eq(CREDENTIAL_SERVICE_BASE_URL_PROPERTY), isNull())).thenReturn("https://credential.service"); - when(cfg.getString(eq(CONNECTOR_DID_PROPERTY), isNull())).thenReturn(null); - - assertThatThrownBy(() -> extension.getBdrsClient(context)).isInstanceOf(EdcException.class) - .hasMessageContaining(CONNECTOR_DID_PROPERTY); } } \ No newline at end of file diff --git a/edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java b/edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java index 1cd5c389ac..4c92243875 100644 --- a/edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java +++ b/edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java @@ -37,8 +37,10 @@ @Extension("Registers an SQL implementation for the BusinessPartnerGroupStore") public class SqlBusinessPartnerGroupStoreExtension implements ServiceExtension { - @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) - public static final String DATASOURCE_NAME = "edc.sql.store.bpn.datasource"; + private static final String DATASOURCE_NAME = "edc.sql.store.bpn.datasource"; + + @Setting(key = DATASOURCE_NAME, description = "The datasource for the BusinessPartnerGroupStore", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + private String dataSourceName; private static final String NAME = "SQL Business Partner Store"; @Inject @@ -54,7 +56,6 @@ public class SqlBusinessPartnerGroupStoreExtension implements ServiceExtension { @Provider public BusinessPartnerStore sqlStore(ServiceExtensionContext context) { - var dataSourceName = context.getConfig().getString(DATASOURCE_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); return new SqlBusinessPartnerStore(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), queryExecutor, getStatements()); } diff --git a/edc-extensions/dataplane/dataplane-proxy/edc-dataplane-proxy-consumer-api/src/main/java/org/eclipse/tractusx/edc/dataplane/proxy/consumer/api/DataPlaneProxyConsumerApiExtension.java b/edc-extensions/dataplane/dataplane-proxy/edc-dataplane-proxy-consumer-api/src/main/java/org/eclipse/tractusx/edc/dataplane/proxy/consumer/api/DataPlaneProxyConsumerApiExtension.java index 65b987d40e..2ade052d43 100644 --- a/edc-extensions/dataplane/dataplane-proxy/edc-dataplane-proxy-consumer-api/src/main/java/org/eclipse/tractusx/edc/dataplane/proxy/consumer/api/DataPlaneProxyConsumerApiExtension.java +++ b/edc-extensions/dataplane/dataplane-proxy/edc-dataplane-proxy-consumer-api/src/main/java/org/eclipse/tractusx/edc/dataplane/proxy/consumer/api/DataPlaneProxyConsumerApiExtension.java @@ -42,7 +42,6 @@ import java.util.UUID; import java.util.concurrent.ExecutorService; -import static java.util.Optional.ofNullable; import static java.util.concurrent.Executors.newFixedThreadPool; /** @@ -57,15 +56,22 @@ public class DataPlaneProxyConsumerApiExtension implements ServiceExtension { private static final String DEFAULT_PROXY_PATH = "/proxy"; private static final int DEFAULT_THREAD_POOL = 10; - @Setting("Vault alias for the Consumer Proxy API key") - public static final String AUTH_SETTING_CONSUMER_PROXY_APIKEY_ALIAS = "tx.edc.dpf.consumer.proxy.auth.apikey.alias"; - @Setting("API key for the Consumer Proxy API") - public static final String AUTH_SETTING_CONSUMER_PROXY_APIKEY = "tx.edc.dpf.consumer.proxy.auth.apikey"; - - @Setting(value = "Data plane proxy API consumer port", type = "int") private static final String CONSUMER_PORT = "tx.edc.dpf.consumer.proxy.port"; - @Setting(value = "Thread pool size for the consumer data plane proxy gateway", type = "int") private static final String THREAD_POOL_SIZE = "tx.edc.dpf.consumer.proxy.thread.pool"; + private static final String AUTH_SETTING_CONSUMER_PROXY_APIKEY = "tx.edc.dpf.consumer.proxy.auth.apikey"; + private static final String AUTH_SETTING_CONSUMER_PROXY_APIKEY_ALIAS = "tx.edc.dpf.consumer.proxy.auth.apikey.alias"; + + @Setting(key = AUTH_SETTING_CONSUMER_PROXY_APIKEY_ALIAS, description = "Vault alias for the Consumer Proxy API key", required = false) + private String apiKeyAlias; + + @Setting(key = AUTH_SETTING_CONSUMER_PROXY_APIKEY, description = "API key for the Consumer Proxy API", required = false) + private String configuredApiKey; + + @Setting(key = CONSUMER_PORT, description = "Data plane proxy API consumer port", defaultValue = DEFAULT_PROXY_PORT + "") + private int port; + + @Setting(key = THREAD_POOL_SIZE, description = "Thread pool size for the consumer data plane proxy gateway", defaultValue = DEFAULT_THREAD_POOL + "") + private int poolSize; @Configuration private DataPlaneProxyConsumerApiConfiguration apiConfiguration; @@ -95,11 +101,9 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { // when deprecated port will be purged, just assign `apiConfiguration.port()` to `port` - var port = context.getSetting(CONSUMER_PORT, DEFAULT_PROXY_PORT); var portMapping = new PortMapping(PROXY, port, apiConfiguration.path()); portMappingRegistry.register(portMapping); - var poolSize = context.getSetting(THREAD_POOL_SIZE, DEFAULT_THREAD_POOL); executorService = newFixedThreadPool(poolSize); var authenticationService = createAuthenticationService(context); @@ -120,10 +124,14 @@ public void shutdown() { } private AuthenticationService createAuthenticationService(ServiceExtensionContext context) { - - var apiKey = ofNullable(context.getSetting(AUTH_SETTING_CONSUMER_PROXY_APIKEY_ALIAS, null)) - .map(alias -> vault.resolveSecret(alias)) - .orElseGet(() -> context.getSetting(AUTH_SETTING_CONSUMER_PROXY_APIKEY, UUID.randomUUID().toString())); + String apiKey; + if (apiKeyAlias != null) { + apiKey = vault.resolveSecret(apiKeyAlias); + } else if (configuredApiKey != null) { + apiKey = configuredApiKey; + } else { + apiKey = UUID.randomUUID().toString(); + } return new TokenBasedAuthenticationService(context.getMonitor().withPrefix("ConsumerProxyAPI"), apiKey); } diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java index 9fa4feb770..cabadfaf82 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java @@ -25,10 +25,12 @@ import org.eclipse.edc.jwt.signer.spi.JwsSignerProvider; import org.eclipse.edc.keys.spi.LocalPublicKeyService; import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Setting; +import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.security.Vault; import org.eclipse.edc.spi.system.Hostname; @@ -42,32 +44,48 @@ import java.time.Clock; -import static org.eclipse.tractusx.edc.core.utils.ConfigUtil.missingMandatoryProperty; import static org.eclipse.tractusx.edc.dataplane.tokenrefresh.core.DataPlaneTokenRefreshServiceExtension.NAME; @Extension(value = NAME) public class DataPlaneTokenRefreshServiceExtension implements ServiceExtension { public static final String NAME = "DataPlane Token Refresh Service extension"; - public static final int DEFAULT_TOKEN_EXPIRY_TOLERANCE_SECONDS = 5; - public static final long DEFAULT_TOKEN_EXPIRY_SECONDS = 300L; - @Setting(value = "Token expiry tolerance period in seconds to allow for clock skew", defaultValue = "" + DEFAULT_TOKEN_EXPIRY_TOLERANCE_SECONDS) - public static final String TOKEN_EXPIRY_TOLERANCE_SECONDS_PROPERTY = "tx.edc.dataplane.token.expiry.tolerance"; - @Setting(value = "The HTTP endpoint where clients can request a renewal of their access token for the public dataplane API") - public static final String REFRESH_ENDPOINT_PROPERTY = "tx.edc.dataplane.token.refresh.endpoint"; + private static final int DEFAULT_TOKEN_EXPIRY_TOLERANCE_SECONDS = 5; + private static final long DEFAULT_TOKEN_EXPIRY_SECONDS = 300L; + private static final int DEFAULT_WEB_PORT = 8185; + private static final String DEFAULT_WEB_PATH = "/api/v2/public"; - @Setting(value = "Alias of private key used for signing tokens, retrieved from private key resolver") - public static final String TOKEN_SIGNER_PRIVATE_KEY_ALIAS = "edc.transfer.proxy.token.signer.privatekey.alias"; + private static final String TOKEN_SIGNER_PRIVATE_KEY_ALIAS = "edc.transfer.proxy.token.signer.privatekey.alias"; + private static final String TOKEN_VERIFIER_PUBLIC_KEY_ALIAS = "edc.transfer.proxy.token.verifier.publickey.alias"; + private static final String TOKEN_EXPIRY_TOLERANCE_SECONDS_PROPERTY = "tx.edc.dataplane.token.expiry.tolerance"; + private static final String TOKEN_EXPIRY_SECONDS_PROPERTY = "tx.edc.dataplane.token.expiry"; + private static final String REFRESH_ENDPOINT_PROPERTY = "tx.edc.dataplane.token.refresh.endpoint"; + private static final String WEB_PORT = "web.http.public.port"; + private static final String WEB_PATH = "web.http.public.path"; - @Setting(value = "Alias of public key used for verifying the tokens, retrieved from the vault") - public static final String TOKEN_VERIFIER_PUBLIC_KEY_ALIAS = "edc.transfer.proxy.token.verifier.publickey.alias"; + @Setting(key = REFRESH_ENDPOINT_PROPERTY, description = "The HTTP endpoint where clients can request a renewal of their access token for the public dataplane API", required = false) + private String refreshEndpointConfig; - @Setting(value = "Expiry time of access token in seconds", defaultValue = DEFAULT_TOKEN_EXPIRY_SECONDS + "") - public static final String TOKEN_EXPIRY_SECONDS_PROPERTY = "tx.edc.dataplane.token.expiry"; + @Setting(key = TOKEN_SIGNER_PRIVATE_KEY_ALIAS, description = "Alias of private key used for signing tokens, retrieved from private key resolver") + private String tokenSignerPrivateKeyAlias; - @Setting(value = "DID of this connector", required = true) - private static final String PARTICIPANT_DID_PROPERTY = "edc.iam.issuer.id"; + @Setting(key = TOKEN_VERIFIER_PUBLIC_KEY_ALIAS, description = "Alias of public key used for verifying the tokens, retrieved from the vault") + private String tokenVerifierPublicKeyAlias; + @Setting(key = TOKEN_EXPIRY_TOLERANCE_SECONDS_PROPERTY, description = "Token expiry tolerance period in seconds to allow for clock skew", defaultValue = DEFAULT_TOKEN_EXPIRY_TOLERANCE_SECONDS + "") + private int tokenExpiryToleranceSeconds; + + @Setting(key = TOKEN_EXPIRY_SECONDS_PROPERTY, description = "Expiry time of access token in seconds", defaultValue = DEFAULT_TOKEN_EXPIRY_SECONDS + "") + private long tokenExpirySeconds; + + @Setting (key = WEB_PORT, defaultValue = DEFAULT_WEB_PORT + "") + private int webPort; + + @Setting (key = WEB_PATH, defaultValue = DEFAULT_WEB_PATH) + private String webPath; + + @Inject + private Monitor monitor; @Inject private TokenValidationService tokenValidationService; @Inject @@ -87,7 +105,7 @@ public class DataPlaneTokenRefreshServiceExtension implements ServiceExtension { @Inject private JwsSignerProvider jwsSignerProvider; @Inject - private SingleParticipantContextSupplier singleParticipantContextSupplier; + private SingleParticipantContextSupplier participantContextSupplier; private DataPlaneTokenRefreshServiceImpl tokenRefreshService; @@ -108,47 +126,34 @@ public DataPlaneTokenRefreshService createRefreshTokenService(ServiceExtensionCo return getTokenRefreshService(context); } - private int getExpiryToleranceConfig(ServiceExtensionContext context) { - return context.getSetting(TOKEN_EXPIRY_TOLERANCE_SECONDS_PROPERTY, DEFAULT_TOKEN_EXPIRY_TOLERANCE_SECONDS); - } - @NotNull private DataPlaneTokenRefreshServiceImpl getTokenRefreshService(ServiceExtensionContext context) { if (tokenRefreshService == null) { var monitor = context.getMonitor().withPrefix("DataPlane Token Refresh"); - var expiryTolerance = getExpiryToleranceConfig(context); var refreshEndpoint = getRefreshEndpointConfig(context, monitor); - var tokenExpiry = getExpiryConfig(context); monitor.debug("Token refresh endpoint: %s".formatted(refreshEndpoint)); - monitor.debug("Token refresh time tolerance: %d s".formatted(expiryTolerance)); + monitor.debug("Token refresh time tolerance: %d s".formatted(tokenExpiryToleranceSeconds)); tokenRefreshService = new DataPlaneTokenRefreshServiceImpl(clock, tokenValidationService, didPkResolver, localPublicKeyService, accessTokenDataStore, new JwtGenerationService(jwsSignerProvider), - () -> context.getConfig().getString(TOKEN_SIGNER_PRIVATE_KEY_ALIAS), context.getMonitor(), refreshEndpoint, expiryTolerance, tokenExpiry, - () -> context.getConfig().getString(TOKEN_VERIFIER_PUBLIC_KEY_ALIAS), vault, typeManager.getMapper(), singleParticipantContextSupplier); + () -> tokenSignerPrivateKeyAlias, context.getMonitor(), refreshEndpoint, tokenExpiryToleranceSeconds, tokenExpirySeconds, + () -> tokenVerifierPublicKeyAlias, vault, typeManager.getMapper(), participantContextSupplier); } return tokenRefreshService; } - private Long getExpiryConfig(ServiceExtensionContext context) { - return context.getSetting(TOKEN_EXPIRY_SECONDS_PROPERTY, DEFAULT_TOKEN_EXPIRY_SECONDS); - } - private String getRefreshEndpointConfig(ServiceExtensionContext context, Monitor monitor) { - var refreshEndpoint = context.getSetting(REFRESH_ENDPOINT_PROPERTY, null); + var refreshEndpoint = refreshEndpointConfig; if (refreshEndpoint == null) { - var port = context.getConfig().getInteger("web.http.public.port", 8185); - var path = context.getConfig().getString("web.http.public.path", "/api/v2/public"); - refreshEndpoint = "http://%s:%d%s".formatted(hostname.get(), port, path); + refreshEndpoint = "http://%s:%d%s".formatted(hostname.get(), webPort, webPath); monitor.warning("Config property '%s' was not specified, the default '%s' will be used.".formatted(REFRESH_ENDPOINT_PROPERTY, refreshEndpoint)); } return refreshEndpoint; } private String getOwnDid(ServiceExtensionContext context) { - var did = context.getConfig().getString(PARTICIPANT_DID_PROPERTY, null); - if (did == null) { - missingMandatoryProperty(context.getMonitor().withPrefix("DataPlane Token Refresh"), PARTICIPANT_DID_PROPERTY); - } - return did; + return participantContextSupplier.get().map(ParticipantContext::getIdentity).onFailure(f -> { + var message = "This connector is not configured properly, cannot continue. Error is: %s".formatted(f.getFailureDetail()); + monitor.severe(message); + throw new EdcException(message); + }).getContent(); } - } diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java index 7ff3d5452f..904bc160da 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java @@ -43,8 +43,10 @@ @Extension(RemoteTokenServiceClientExtension.NAME) public class RemoteTokenServiceClientExtension implements ServiceExtension { - @Setting(value = "STS Div endpoint") - public static final String DIV_URL = "tx.edc.iam.sts.div.url"; + static final String DIV_URL = "tx.edc.iam.sts.div.url"; + + @Setting(key = DIV_URL, description = "STS Div endpoint", required = false) + private String divUrlConfig; protected static final String NAME = "Secure Token Service (STS) client extension"; @@ -70,7 +72,6 @@ public String name() { @Provider public SecureTokenService secureTokenService(ServiceExtensionContext context) { - var divUrlConfig = context.getSetting(DIV_URL, null); return ofNullable(divUrlConfig) .map(PathUtils::removeTrailingSlash) .map(divUrl -> { diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java index 4994e281a5..7e4bf9e187 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java @@ -27,26 +27,26 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.tractusx.edc.core.utils.PathUtils; -import static java.util.Optional.ofNullable; -import static org.eclipse.tractusx.edc.core.utils.ConfigUtil.missingMandatoryProperty; - /** * Configuration Extension for the STS OAuth2 client */ @Extension(StsClientConfigurationExtension.NAME) public class StsClientConfigurationExtension implements ServiceExtension { - @Setting(value = "STS OAuth2 endpoint for requesting a token") - public static final String TOKEN_URL = "edc.iam.sts.oauth.token.url"; + static final String TOKEN_URL = "edc.iam.sts.oauth.token.url"; + static final String CLIENT_ID = "edc.iam.sts.oauth.client.id"; + static final String CLIENT_SECRET_ALIAS = "edc.iam.sts.oauth.client.secret.alias"; - @Setting(value = "STS OAuth2 client id") - public static final String CLIENT_ID = "edc.iam.sts.oauth.client.id"; + @Setting(key = TOKEN_URL, description = "STS OAuth2 endpoint for requesting a token") + private String tokenUrl; - @Setting(value = "Vault alias of STS OAuth2 client secret") - public static final String CLIENT_SECRET_ALIAS = "edc.iam.sts.oauth.client.secret.alias"; + @Setting(key = CLIENT_ID, description = "STS OAuth2 client id") + private String clientId; - protected static final String NAME = "Secure Token Service (STS) client configuration extension"; + @Setting(key = CLIENT_SECRET_ALIAS, description = "Vault alias of STS OAuth2 client secret") + private String clientSecretAlias; + protected static final String NAME = "Secure Token Service (STS) client configuration extension"; @Override public String name() { @@ -55,24 +55,6 @@ public String name() { @Provider public StsRemoteClientConfiguration clientConfiguration(ServiceExtensionContext context) { - - var tokenUrl = ofNullable(context.getConfig().getString(TOKEN_URL, null)) - .map(PathUtils::removeTrailingSlash).orElse(null); - var clientId = context.getConfig().getString(CLIENT_ID, null); - var clientSecretAlias = context.getConfig().getString(CLIENT_SECRET_ALIAS, null); - - var monitor = context.getMonitor().withPrefix("STS Client for DIV"); - if (tokenUrl == null) { - missingMandatoryProperty(monitor, TOKEN_URL); - } - if (clientId == null) { - missingMandatoryProperty(monitor, CLIENT_ID); - } - if (clientSecretAlias == null) { - missingMandatoryProperty(monitor, CLIENT_SECRET_ALIAS); - } - return new StsRemoteClientConfiguration(tokenUrl, clientId, clientSecretAlias); + return new StsRemoteClientConfiguration(PathUtils.removeTrailingSlash(tokenUrl), clientId, clientSecretAlias); } - - } diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java index ae5ab124ef..1ec6ca98a0 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java @@ -19,40 +19,46 @@ package org.eclipse.tractusx.edc.iam.dcp.sts; +import org.eclipse.edc.boot.system.injection.ObjectFactory; import org.eclipse.edc.iam.decentralizedclaims.sts.remote.RemoteSecureTokenService; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.system.configuration.Config; +import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.eclipse.tractusx.edc.iam.dcp.sts.div.DivSecureTokenService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import java.util.HashMap; +import java.util.Map; + import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.tractusx.edc.iam.dcp.sts.RemoteTokenServiceClientExtension.DIV_URL; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @ExtendWith(DependencyInjectionExtension.class) public class RemoteTokenServiceClientExtensionTest { @Test - void initialize(ServiceExtensionContext context, RemoteTokenServiceClientExtension extension) { - var config = mock(Config.class); + void initialize(ServiceExtensionContext context, ObjectFactory factory) { + var configMap = Map.of( + DIV_URL, "url" + ); + var config = ConfigFactory.fromMap(configMap); when(context.getConfig()).thenReturn(config); - when(config.getString(DIV_URL, null)).thenReturn("url"); + + var extension = factory.constructInstance(RemoteTokenServiceClientExtension.class); assertThat(extension.secureTokenService(context)).isInstanceOf(DivSecureTokenService.class); } @Test - void initialize_whenUrlIsMissing_fallsBackToRemoteSts(ServiceExtensionContext context, RemoteTokenServiceClientExtension extension) { - var monitor = context.getMonitor(); - var prefixeMonitor = mock(Monitor.class); - when(monitor.withPrefix(anyString())).thenReturn(prefixeMonitor); + void initialize_whenUrlIsMissing_fallsBackToRemoteSts(ServiceExtensionContext context, ObjectFactory f) { + var configMap = new HashMap(); + var config = ConfigFactory.fromMap(configMap); + when(context.getConfig()).thenReturn(config); + + var extension = f.constructInstance(RemoteTokenServiceClientExtension.class); assertThat(extension.secureTokenService(context)) .isInstanceOf(RemoteSecureTokenService.class); } - } diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java index 92414a90a2..8fe3e2e101 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java @@ -21,28 +21,35 @@ import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.system.configuration.Config; +import org.eclipse.edc.spi.system.configuration.ConfigFactory; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import java.util.Map; + import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.tractusx.edc.iam.dcp.sts.StsClientConfigurationExtension.CLIENT_ID; import static org.eclipse.tractusx.edc.iam.dcp.sts.StsClientConfigurationExtension.CLIENT_SECRET_ALIAS; import static org.eclipse.tractusx.edc.iam.dcp.sts.StsClientConfigurationExtension.TOKEN_URL; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @ExtendWith(DependencyInjectionExtension.class) public class StsClientConfigurationExtensionTest { - @Test - void initialize(ServiceExtensionContext context, StsClientConfigurationExtension extension) { - var config = mock(Config.class); + @BeforeEach + void setup(ServiceExtensionContext context) { + var configMap = Map.of( + TOKEN_URL, "url", + CLIENT_ID, "clientId", + CLIENT_SECRET_ALIAS, "clientSecretAlias" + ); + var config = ConfigFactory.fromMap(configMap); when(context.getConfig()).thenReturn(config); - when(config.getString(TOKEN_URL, null)).thenReturn("url"); - when(config.getString(CLIENT_ID, null)).thenReturn("clientId"); - when(config.getString(CLIENT_SECRET_ALIAS, null)).thenReturn("clientSecretAlias"); + } + @Test + void initialize(ServiceExtensionContext context, StsClientConfigurationExtension extension) { assertThat(extension.clientConfiguration(context)).satisfies(stsConfig -> { assertThat(stsConfig.clientId()).isEqualTo("clientId"); assertThat(stsConfig.clientSecretAlias()).isEqualTo("clientSecretAlias"); diff --git a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtension.java b/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtension.java index 6a4b773c1f..e9f9d8c490 100644 --- a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtension.java +++ b/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/DcpDefaultScopeExtension.java @@ -50,14 +50,15 @@ public class DcpDefaultScopeExtension implements ServiceExtension { public static final String TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS = TX_DCP_DEFAULT_SCOPE_PREFIX + ".."; - @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. org.eclipse.edc.vc.type", required = true) + @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, description = "The alias of the scope e.g. org.eclipse.edc.vc.type") public static final String ALIAS = "alias"; - @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. MembershipCredential", required = true) + @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, description = "The alias of the scope e.g. MembershipCredential") public static final String TYPE = "type"; - @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, value = "The alias of the scope e.g. read", required = true) + @Setting(context = TX_DCP_DEFAULT_SCOPE_PREFIX_CONFIG_ALIAS, description = "The alias of the scope e.g. read") public static final String OPERATION = "operation"; + static final String NAME = "Tractusx default scope extension"; @Inject private PolicyEngine policyEngine; diff --git a/edc-extensions/edr/edr-index-lock-sql/src/main/java/org/eclipse/tractusx/edc/edr/index/sql/lock/SqlEdrLockExtension.java b/edc-extensions/edr/edr-index-lock-sql/src/main/java/org/eclipse/tractusx/edc/edr/index/sql/lock/SqlEdrLockExtension.java index 009a7d20d9..fe456f7a0b 100644 --- a/edc-extensions/edr/edr-index-lock-sql/src/main/java/org/eclipse/tractusx/edc/edr/index/sql/lock/SqlEdrLockExtension.java +++ b/edc-extensions/edr/edr-index-lock-sql/src/main/java/org/eclipse/tractusx/edc/edr/index/sql/lock/SqlEdrLockExtension.java @@ -37,8 +37,10 @@ @Extension(value = "Database-level EDR Lock extension (PostgreSQL)") public class SqlEdrLockExtension implements ServiceExtension { - @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) - public static final String DATASOURCE_NAME = "edc.sql.store.edr.datasource"; + private static final String DATASOURCE_NAME = "edc.sql.store.edr.datasource"; + + @Setting(key = DATASOURCE_NAME, description = "Datasource of edr lock", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + private String dataSourceName; @Inject private DataSourceRegistry dataSourceRegistry; @@ -56,8 +58,6 @@ public class SqlEdrLockExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - var dataSourceName = context.getConfig().getString(DATASOURCE_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); - var statements = new PostgresEdrLockStatements(); var sqlStore = new SqlEdrLock(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), queryExecutor, statements); diff --git a/edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java b/edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java index e04c6f917d..feac61695a 100644 --- a/edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java +++ b/edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java @@ -46,13 +46,17 @@ public abstract class AbstractPostgresqlMigrationExtension implements ServiceExtension { private static final String DEFAULT_MIGRATION_ENABLED_TEMPLATE = "true"; - @Setting(value = "Enable/disables subsystem schema migration", defaultValue = DEFAULT_MIGRATION_ENABLED_TEMPLATE, type = "boolean") + + // TODO: Make this a context aware setting after 0.17.0 upstream update. + @Setting(description = "Enable/disables subsystem schema migration", defaultValue = DEFAULT_MIGRATION_ENABLED_TEMPLATE, type = "boolean") private static final String MIGRATION_ENABLED_TEMPLATE = "tx.edc.postgresql.migration.%s.enabled"; private static final String DEFAULT_MIGRATION_SCHEMA = "public"; - @Setting(value = "Schema used for the migration", defaultValue = DEFAULT_MIGRATION_SCHEMA) private static final String MIGRATION_SCHEMA = "tx.edc.postgresql.migration.schema"; + @Setting(key = MIGRATION_SCHEMA, description = "Schema used for the migration", defaultValue = DEFAULT_MIGRATION_SCHEMA) + private String defaultSchema; + private Supplier migrationExecutor; private boolean enabled; @@ -83,7 +87,6 @@ public void initialize(final ServiceExtensionContext context) { jdbcProperties.putAll(datasourceConfig.getRelativeEntries()); var driverManagerConnectionFactory = new DriverManagerConnectionFactory(); var dataSource = new ConnectionFactoryDataSource(driverManagerConnectionFactory, jdbcUrl, jdbcProperties); - var defaultSchema = config.getString(MIGRATION_SCHEMA, DEFAULT_MIGRATION_SCHEMA); migrationExecutor = () -> FlywayManager.migrate(dataSource, getMigrationSubsystem(), defaultSchema, LATEST); } diff --git a/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerExtension.java b/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerExtension.java index 2c8f469b4b..147a1ba04f 100644 --- a/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerExtension.java +++ b/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerExtension.java @@ -23,23 +23,25 @@ import org.eclipse.edc.http.spi.EdcHttpClient; import org.eclipse.edc.iam.decentralizedclaims.spi.SecureTokenService; import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; +import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.tractusx.edc.core.utils.ConfigUtil; import org.eclipse.tractusx.edc.spi.tokenrefresh.common.TokenRefreshHandler; import static org.eclipse.tractusx.edc.common.tokenrefresh.TokenRefreshHandlerExtension.NAME; - @Extension(value = NAME) public class TokenRefreshHandlerExtension implements ServiceExtension { public static final String NAME = "Token Refresh Handler Extension"; - // this setting is defined by the IdentityAndTrustExtension - private static final String PARTICIPANT_DID_PROPERTY = "edc.iam.issuer.id"; + + @Inject + private Monitor monitor; @Inject private EndpointDataReferenceCache edrStore; @Inject @@ -63,10 +65,10 @@ public TokenRefreshHandler createTokenRefreshHander(ServiceExtensionContext cont } private String getOwnDid(ServiceExtensionContext context) { - var did = context.getConfig().getString(PARTICIPANT_DID_PROPERTY, null); - if (did == null) { - ConfigUtil.missingMandatoryProperty(context.getMonitor().withPrefix("Token Refresh Handler"), PARTICIPANT_DID_PROPERTY); - } - return did; + return participantContextSupplier.get().map(ParticipantContext::getIdentity).onFailure(f -> { + var message = "This connector is not configured properly, cannot continue. Error is: %s".formatted(f.getFailureDetail()); + monitor.withPrefix(getClass().getSimpleName()).severe(message); + throw new EdcException(message); + }).getContent(); } } From 83e528b422343cb0fc67ff237add6e4364d6b28b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:22:29 +0200 Subject: [PATCH 112/259] chore(deps): bump io.opentelemetry.javaagent:opentelemetry-javaagent (#2860) Bumps [io.opentelemetry.javaagent:opentelemetry-javaagent](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.27.0 to 2.28.1. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.27.0...v2.28.1) --- updated-dependencies: - dependency-name: io.opentelemetry.javaagent:opentelemetry-javaagent dependency-version: 2.28.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e9b1727739..2065afc288 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,7 +18,7 @@ jakarta-json = "2.1.3" junit = "6.0.3" nimbus = "10.9" okhttp = "5.3.2" -opentelemetry = "2.27.0" +opentelemetry = "2.28.1" opentelemetry-instrumentation = "2.27.0" opentelemetry-log4j-appender = "2.27.0-alpha" postgres = "42.7.11" From 632c88ade0300441557ec5fede4421caded04720 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:24:57 +0200 Subject: [PATCH 113/259] chore(deps): bump docker/build-push-action (#2854) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.1.0 to 7.2.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/bcafcacb16a39f128d818304e6c9c0c18556b85f...f9f3042f7e2789586610d6e8b85c8f03e5195baf) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-version: 7.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 7c86e823a8..373bd1b3e6 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -105,7 +105,7 @@ runs: # Build and push the image ############################### - name: Build and push - uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 + uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 env: ROOT_DIR: ${{ inputs.rootDir }} IMAGE_NAME: ${{ inputs.imagename }} From 007b213eb5a10c857bd2e149e72198f3d49d4cdd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:25:34 +0200 Subject: [PATCH 114/259] chore(deps): bump docker/setup-buildx-action (#2856) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd...d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 373bd1b3e6..9e0980312f 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -60,7 +60,7 @@ runs: # Use Docker Buildx (required for multi-arch) ############################################### - name: Set up Docker Buildx - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 ##################### # Login to DockerHub From 37c87df85a89fb0d3cae94f075308a6468a89109 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:26:18 +0200 Subject: [PATCH 115/259] chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 (#2855) Bumps [io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.27.0-alpha to 2.28.1-alpha. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/commits) --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 dependency-version: 2.28.1-alpha dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2065afc288..8c3fe91299 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ nimbus = "10.9" okhttp = "5.3.2" opentelemetry = "2.28.1" opentelemetry-instrumentation = "2.27.0" -opentelemetry-log4j-appender = "2.27.0-alpha" +opentelemetry-log4j-appender = "2.28.1-alpha" postgres = "42.7.11" restAssured = "6.0.0" rsApi = "4.0.0" From 7e68835b099d60b177b5e9a9af9a9efbc47215d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:26:54 +0200 Subject: [PATCH 116/259] chore(deps): bump docker/login-action (#2853) Bumps [docker/login-action](https://github.com/docker/login-action) from 4.1.0 to 4.2.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/4907a6ddec9925e35a0a9e82d7399ccc52663121...650006c6eb7dba73a995cc03b0b2d7f5ca915bee) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 9e0980312f..b882abdce1 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -66,7 +66,7 @@ runs: # Login to DockerHub ##################### - name: DockerHub login - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 with: username: ${{ inputs.docker_user }} password: ${{ inputs.docker_token }} From 236585f689aa395cf21886b7003b025bb811b6bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:47:41 +0200 Subject: [PATCH 117/259] chore(deps): bump actions/stale from 10.2.0 to 10.3.0 (#2852) Bumps [actions/stale](https://github.com/actions/stale) from 10.2.0 to 10.3.0. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/b5d41d4e1d5dceea10e7104786b73624c18a190f...eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899) --- updated-dependencies: - dependency-name: actions/stale dependency-version: 10.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale-bot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index b579b9448f..3f0dd7a07d 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -42,7 +42,7 @@ jobs: uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 with: egress-policy: audit - - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 + - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 with: operations-per-run: 1000 days-before-issue-stale: 32 From b1bc54177d01e9768e8d3e8f7d79d7a7e1c94c32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:48:19 +0200 Subject: [PATCH 118/259] chore(deps): bump zizmorcore/zizmor-action from 0.5.5 to 0.5.6 (#2851) Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.5.5 to 0.5.6. - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/a16621b09c6db4281f81a93cb393b05dcd7b7165...5f14fd08f7cf1cb1609c1e344975f152c7ee938d) --- updated-dependencies: - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/workflow-security-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 86b6db2f1a..76f801bfd7 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -56,7 +56,7 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@a16621b09c6db4281f81a93cb393b05dcd7b7165 # v0.5.5 + uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 with: version: "1.23.1" advanced-security: "true" From ebf90f1bb4d2cd40f00d2f9f04fbfb6ac1f524a5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:48:50 +0200 Subject: [PATCH 119/259] chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations (#2859) Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.27.0 to 2.28.1. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.27.0...v2.28.1) --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations dependency-version: 2.28.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8c3fe91299..23e3b214ef 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ junit = "6.0.3" nimbus = "10.9" okhttp = "5.3.2" opentelemetry = "2.28.1" -opentelemetry-instrumentation = "2.27.0" +opentelemetry-instrumentation = "2.28.1" opentelemetry-log4j-appender = "2.28.1-alpha" postgres = "42.7.11" restAssured = "6.0.0" From 4a58e7d36091219af73b68197e7963da09aad2dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:49:38 +0200 Subject: [PATCH 120/259] chore(deps): bump github/codeql-action from 4.35.5 to 4.36.0 (#2850) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.5 to 4.36.0. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/9e0d7b8d25671d64c341c19c0152d693099fb5ba...7211b7c8077ea37d8641b6271f6a365a22a5fbfa) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.36.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 4 ++-- .github/workflows/kics.yml | 2 +- .github/workflows/workflow-security-lint.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 7f888e0103..e3c4137f56 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 + uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 + uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index f52d16810b..142bc19c7c 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 + uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 76f801bfd7..f406d9e6b4 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5 + uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 if: always() with: sarif_file: results-fixed.sarif From f6e49c83db6107172d1a2f93a8dfed181c46d6dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:50:50 +0200 Subject: [PATCH 121/259] chore(deps): bump org.junit.platform:junit-platform-launcher (#2847) Bumps [org.junit.platform:junit-platform-launcher](https://github.com/junit-team/junit-framework) from 6.0.3 to 6.1.0. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.0.3...r6.1.0) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-launcher dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 23e3b214ef..ae0972c468 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ dsp-tck = "1.0.0-RC6" flyway = "12.6.1" jackson = "2.21.3" jakarta-json = "2.1.3" -junit = "6.0.3" +junit = "6.1.0" nimbus = "10.9" okhttp = "5.3.2" opentelemetry = "2.28.1" From 2a83505a90fa26efd0666f8631075bef0f50ffbd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 08:59:36 +0200 Subject: [PATCH 122/259] chore(deps): bump docker/metadata-action (#2857) Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 6.0.0 to 6.1.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/030e881283bb7a6894de51c315a6bfe6a94e05cf...80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index b882abdce1..9e26d6c4e1 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -88,7 +88,7 @@ runs: # Create SemVer or ref tags dependent of trigger event - name: Docker meta id: meta - uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 + uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 with: images: | ${{ inputs.namespace }}/${{ inputs.imagename }} From beed7c2c2f22c6f0344973f3b86207b2a0df68bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 09:03:00 +0200 Subject: [PATCH 123/259] chore(deps): bump aws from 2.44.6 to 2.44.11 (#2858) Bumps `aws` from 2.44.6 to 2.44.11. Updates `software.amazon.awssdk:s3` from 2.44.6 to 2.44.11 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.44.6 to 2.44.11 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.44.11 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.44.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ae0972c468..6a6e5934f0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.44.6" +aws = "2.44.11" azure-storage-blob = "12.33.4" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" From fa33f76cdccc108f9b410c6e62288b00460350cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 09:04:01 +0200 Subject: [PATCH 124/259] chore(deps): bump step-security/harden-runner from 2.19.3 to 2.19.4 (#2848) Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.19.3 to 2.19.4. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/ab7a9404c0f3da075243ca237b5fac12c98deaa5...9af89fc71515a100421586dfdb3dc9c984fbf411) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.19.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 2 +- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/deployment-test.yaml | 6 ++--- .github/workflows/draft-release.yaml | 2 +- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 2 +- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 6 ++--- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/stale-bot.yml | 2 +- .github/workflows/triage-issue.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 4 ++-- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 4 ++-- 18 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index e3c4137f56..fa2b175149 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -55,7 +55,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index 1ec4ec891e..016d6f07b8 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Copy labels from linked issue to PR diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 1cd28efd35..605f678929 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: test-prepare steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -84,7 +84,7 @@ jobs: "v1.33.7" ] steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index ae2b33c035..6356560801 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -44,7 +44,7 @@ jobs: is_official_release: ${{ steps.validation.outputs.is_official_release }} steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index c59209906d..2d89d634f4 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 4a98eec2ad..217fd68251 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit ############## diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 142bc19c7c..158dfba228 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index e05946cd9d..165b3ab259 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -38,7 +38,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index 29e7977b21..6b595298d4 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -72,7 +72,7 @@ jobs: HAS_SWAGGER: ${{ steps.secret-presence.outputs.HAS_SWAGGER }} steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Check whether secrets exist @@ -95,7 +95,7 @@ jobs: DATED: ${{ steps.get-version.outputs.DATED }} steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -165,7 +165,7 @@ jobs: if: ${{ needs.determine-version.outputs.DATED == 'true' }} steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a14825452a..3f0453ee9d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,7 +60,7 @@ jobs: update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -152,7 +152,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -192,7 +192,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -255,7 +255,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit @@ -298,7 +298,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Checkout main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index a21ddc54ea..a892b5adf0 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -42,7 +42,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Checkout Repository diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 3f0dd7a07d..b0cdae23af 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -39,7 +39,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 diff --git a/.github/workflows/triage-issue.yml b/.github/workflows/triage-issue.yml index 8f3149ce0f..b4103c5161 100644 --- a/.github/workflows/triage-issue.yml +++ b/.github/workflows/triage-issue.yml @@ -36,7 +36,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - run: gh issue edit "$NUMBER" --add-label "$LABELS" diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index 7ef4a16e12..d35829dd1b 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -71,7 +71,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index fafa5e2d8d..891a35bf3a 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 98260067bd..60d00164cf 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: [ test-prepare ] steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index af7a73fb24..5af9f72003 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -36,7 +36,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -152,7 +152,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -172,7 +172,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -192,7 +192,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -214,7 +214,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -248,7 +248,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -265,7 +265,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -287,7 +287,7 @@ jobs: contents: write steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index f406d9e6b4..1ddecbe359 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -46,7 +46,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit @@ -71,7 +71,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3 + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit From 2cfb5c51885d42c307a654b3fe8d7e88016e797d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 May 2026 09:10:17 +0200 Subject: [PATCH 125/259] chore(deps): bump flyway from 12.6.1 to 12.6.2 (#2849) Bumps `flyway` from 12.6.1 to 12.6.2. Updates `org.flywaydb:flyway-core` from 12.6.1 to 12.6.2 Updates `org.flywaydb:flyway-database-postgresql` from 12.6.1 to 12.6.2 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.6.2 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.6.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6a6e5934f0..df6abd64b2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ azure-storage-blob = "12.33.4" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" -flyway = "12.6.1" +flyway = "12.6.2" jackson = "2.21.3" jakarta-json = "2.1.3" junit = "6.1.0" From 7821964d95dcdb149ba825fd3e049431336f45c2 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Tue, 2 Jun 2026 15:40:22 +0200 Subject: [PATCH 126/259] Fix sca issues (#2861) Signed-off-by: Lars Geyer-Blaumeiser --- .../edc/vault/memory/VaultSeedExtension.java | 3 +-- .../edc/vault/memory/VaultSeedExtensionTest.java | 2 +- .../store/SqlAgreementsBpnsStoreExtension.java | 3 +-- .../SqlAgreementsRetirementStoreExtension.java | 3 +-- .../SqlBusinessPartnerGroupStoreExtension.java | 3 +-- .../DataPlaneTokenRefreshServiceExtension.java | 14 ++------------ .../edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java | 4 ++-- .../dcp/sts/RemoteTokenServiceClientExtension.java | 3 +-- .../dcp/sts/StsClientConfigurationExtension.java | 3 +-- .../sts/RemoteTokenServiceClientExtensionTest.java | 4 ++-- .../sts/StsClientConfigurationExtensionTest.java | 2 +- .../tokenrefresh/TokenRefreshHandlerExtension.java | 4 ++-- 12 files changed, 16 insertions(+), 32 deletions(-) diff --git a/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java b/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java index be6598e149..8e9b7dcc08 100644 --- a/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java +++ b/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java @@ -29,7 +29,6 @@ import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.security.Vault; import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; import java.util.stream.Stream; @@ -58,7 +57,7 @@ public String name() { } @Provider - public Vault createInMemVault(ServiceExtensionContext context) { + public Vault createInMemVault() { if (seedSecrets != null) { singleParticipantContextSupplier.get().map(ParticipantContext::getParticipantContextId) diff --git a/edc-controlplane/edc-runtime-memory/src/test/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtensionTest.java b/edc-controlplane/edc-runtime-memory/src/test/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtensionTest.java index acac3629e1..d36c126260 100644 --- a/edc-controlplane/edc-runtime-memory/src/test/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtensionTest.java +++ b/edc-controlplane/edc-runtime-memory/src/test/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtensionTest.java @@ -74,7 +74,7 @@ void createInMemVault_validString(String secret, ServiceExtensionContext context var extension = factory.constructInstance(VaultSeedExtension.class); - extension.createInMemVault(context); + extension.createInMemVault(); verify(monitor, times(1)).debug(anyString()); } } diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/SqlAgreementsBpnsStoreExtension.java b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/SqlAgreementsBpnsStoreExtension.java index ea0a2e1f57..061ab8235f 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/SqlAgreementsBpnsStoreExtension.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/store/SqlAgreementsBpnsStoreExtension.java @@ -24,7 +24,6 @@ import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; @@ -60,7 +59,7 @@ public class SqlAgreementsBpnsStoreExtension implements ServiceExtension { private SqlAgreementsBpnsStatements statements; @Provider - public AgreementsBpnsStore sqlStore(ServiceExtensionContext context) { + public AgreementsBpnsStore sqlStore() { return new SqlAgreementsBpnsStore(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), queryExecutor, getStatements()); } diff --git a/edc-extensions/agreements/retirement-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/retirement/store/SqlAgreementsRetirementStoreExtension.java b/edc-extensions/agreements/retirement-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/retirement/store/SqlAgreementsRetirementStoreExtension.java index 7d80f0f941..8e6c149628 100644 --- a/edc-extensions/agreements/retirement-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/retirement/store/SqlAgreementsRetirementStoreExtension.java +++ b/edc-extensions/agreements/retirement-evaluation-store-sql/src/main/java/org/eclipse/tractusx/edc/agreements/retirement/store/SqlAgreementsRetirementStoreExtension.java @@ -24,7 +24,6 @@ import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; @@ -60,7 +59,7 @@ public class SqlAgreementsRetirementStoreExtension implements ServiceExtension { private SqlAgreementsRetirementStatements statements; @Provider - public AgreementsRetirementStore sqlStore(ServiceExtensionContext context) { + public AgreementsRetirementStore sqlStore() { return new SqlAgreementsRetirementStore(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), queryExecutor, getStatements()); } diff --git a/edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java b/edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java index 4c92243875..0160b7de05 100644 --- a/edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java +++ b/edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java @@ -24,7 +24,6 @@ import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; @@ -55,7 +54,7 @@ public class SqlBusinessPartnerGroupStoreExtension implements ServiceExtension { private BusinessPartnerGroupStatements statements; @Provider - public BusinessPartnerStore sqlStore(ServiceExtensionContext context) { + public BusinessPartnerStore sqlStore() { return new SqlBusinessPartnerStore(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), queryExecutor, getStatements()); } diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java index cabadfaf82..ee2b1de5bd 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java @@ -25,12 +25,10 @@ import org.eclipse.edc.jwt.signer.spi.JwsSignerProvider; import org.eclipse.edc.keys.spi.LocalPublicKeyService; import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; -import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Setting; -import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.security.Vault; import org.eclipse.edc.spi.system.Hostname; @@ -130,7 +128,7 @@ public DataPlaneTokenRefreshService createRefreshTokenService(ServiceExtensionCo private DataPlaneTokenRefreshServiceImpl getTokenRefreshService(ServiceExtensionContext context) { if (tokenRefreshService == null) { var monitor = context.getMonitor().withPrefix("DataPlane Token Refresh"); - var refreshEndpoint = getRefreshEndpointConfig(context, monitor); + var refreshEndpoint = getRefreshEndpointConfig(monitor); monitor.debug("Token refresh endpoint: %s".formatted(refreshEndpoint)); monitor.debug("Token refresh time tolerance: %d s".formatted(tokenExpiryToleranceSeconds)); tokenRefreshService = new DataPlaneTokenRefreshServiceImpl(clock, tokenValidationService, didPkResolver, localPublicKeyService, accessTokenDataStore, new JwtGenerationService(jwsSignerProvider), @@ -140,7 +138,7 @@ private DataPlaneTokenRefreshServiceImpl getTokenRefreshService(ServiceExtension return tokenRefreshService; } - private String getRefreshEndpointConfig(ServiceExtensionContext context, Monitor monitor) { + private String getRefreshEndpointConfig(Monitor monitor) { var refreshEndpoint = refreshEndpointConfig; if (refreshEndpoint == null) { refreshEndpoint = "http://%s:%d%s".formatted(hostname.get(), webPort, webPath); @@ -148,12 +146,4 @@ private String getRefreshEndpointConfig(ServiceExtensionContext context, Monitor } return refreshEndpoint; } - - private String getOwnDid(ServiceExtensionContext context) { - return participantContextSupplier.get().map(ParticipantContext::getIdentity).onFailure(f -> { - var message = "This connector is not configured properly, cannot continue. Error is: %s".formatted(f.getFailureDetail()); - monitor.severe(message); - throw new EdcException(message); - }).getContent(); - } } diff --git a/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java index ffd40d17da..3439038ff7 100644 --- a/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java +++ b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java @@ -59,13 +59,13 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - var defaultScopes = defaultScopes(context); + var defaultScopes = defaultScopes(); policyEngine.registerPostValidator(RequestCatalogPolicyContext.class, new DefaultScopeExtractor<>(defaultScopes)); policyEngine.registerPostValidator(RequestContractNegotiationPolicyContext.class, new DefaultScopeExtractor<>(defaultScopes)); policyEngine.registerPostValidator(RequestTransferProcessPolicyContext.class, new DefaultScopeExtractor<>(defaultScopes)); } - private Map> defaultScopes(ServiceExtensionContext context) { + private Map> defaultScopes() { var scopesByVersion = new HashMap>(); scopesByVersion.put(DSP_SCOPE_V_08, V08_DEFAULT_SCOPES); scopesByVersion.put(DSP_SCOPE_V_2025_1, DEFAULT_SCOPES); diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java index 904bc160da..75fd503aac 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java @@ -32,7 +32,6 @@ import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.security.Vault; import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.tractusx.edc.core.utils.PathUtils; import org.eclipse.tractusx.edc.iam.dcp.sts.div.DivSecureTokenService; @@ -71,7 +70,7 @@ public String name() { } @Provider - public SecureTokenService secureTokenService(ServiceExtensionContext context) { + public SecureTokenService secureTokenService() { return ofNullable(divUrlConfig) .map(PathUtils::removeTrailingSlash) .map(divUrl -> { diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java index 7e4bf9e187..7d9e8961a6 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java @@ -24,7 +24,6 @@ import org.eclipse.edc.runtime.metamodel.annotation.Provider; import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.tractusx.edc.core.utils.PathUtils; /** @@ -54,7 +53,7 @@ public String name() { } @Provider - public StsRemoteClientConfiguration clientConfiguration(ServiceExtensionContext context) { + public StsRemoteClientConfiguration clientConfiguration() { return new StsRemoteClientConfiguration(PathUtils.removeTrailingSlash(tokenUrl), clientId, clientSecretAlias); } } diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java index 1ec6ca98a0..8ce2ba4d33 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java @@ -47,7 +47,7 @@ void initialize(ServiceExtensionContext context, ObjectFactory factory) { when(context.getConfig()).thenReturn(config); var extension = factory.constructInstance(RemoteTokenServiceClientExtension.class); - assertThat(extension.secureTokenService(context)).isInstanceOf(DivSecureTokenService.class); + assertThat(extension.secureTokenService()).isInstanceOf(DivSecureTokenService.class); } @Test @@ -58,7 +58,7 @@ void initialize_whenUrlIsMissing_fallsBackToRemoteSts(ServiceExtensionContext co var extension = f.constructInstance(RemoteTokenServiceClientExtension.class); - assertThat(extension.secureTokenService(context)) + assertThat(extension.secureTokenService()) .isInstanceOf(RemoteSecureTokenService.class); } } diff --git a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java index 8fe3e2e101..22326a93d9 100644 --- a/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java @@ -50,7 +50,7 @@ void setup(ServiceExtensionContext context) { @Test void initialize(ServiceExtensionContext context, StsClientConfigurationExtension extension) { - assertThat(extension.clientConfiguration(context)).satisfies(stsConfig -> { + assertThat(extension.clientConfiguration()).satisfies(stsConfig -> { assertThat(stsConfig.clientId()).isEqualTo("clientId"); assertThat(stsConfig.clientSecretAlias()).isEqualTo("clientSecretAlias"); assertThat(stsConfig.tokenUrl()).isEqualTo("url"); diff --git a/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerExtension.java b/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerExtension.java index 147a1ba04f..13637b6e58 100644 --- a/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerExtension.java +++ b/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerExtension.java @@ -60,11 +60,11 @@ public String name() { @Provider public TokenRefreshHandler createTokenRefreshHander(ServiceExtensionContext context) { - return new TokenRefreshHandlerImpl(edrStore, httpClient, getOwnDid(context), context.getMonitor(), + return new TokenRefreshHandlerImpl(edrStore, httpClient, getOwnDid(), context.getMonitor(), secureTokenService, typeManager.getMapper(), participantContextSupplier); } - private String getOwnDid(ServiceExtensionContext context) { + private String getOwnDid() { return participantContextSupplier.get().map(ParticipantContext::getIdentity).onFailure(f -> { var message = "This connector is not configured properly, cannot continue. Error is: %s".formatted(f.getFailureDetail()); monitor.withPrefix(getClass().getSimpleName()).severe(message); From b9f9170fc4f9130d0693320cc59831ad3e61cdfb Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Wed, 3 Jun 2026 12:57:09 +0200 Subject: [PATCH 127/259] Remove mock connector (#2866) Signed-off-by: Lars Geyer-Blaumeiser --- .github/workflows/trigger-docker-publish.yaml | 3 +- .github/workflows/verify.yaml | 1 - docs/development/mock-edc.md | 220 ------------------ .../runtime/mock-connector/build.gradle.kts | 71 ------ edc-tests/runtime/mock-connector/notice.md | 28 --- .../eclipse/tractusx/edc/mock/MatchType.java | 35 --- .../edc/mock/MockServiceExtension.java | 126 ---------- .../tractusx/edc/mock/RecordedRequest.java | 103 -------- .../mock/RecordedResponseDeserializer.java | 80 ------- .../tractusx/edc/mock/ResponseQueue.java | 147 ------------ .../edc/mock/ServiceFailureDeserializer.java | 58 ----- .../instrumentation/InstrumentationApi.java | 71 ------ .../InstrumentationApiController.java | 76 ------ .../mock/services/AbstractServiceStub.java | 36 --- .../edc/mock/services/AssetServiceStub.java | 70 ------ .../ContractAgreementServiceStub.java | 60 ----- .../ContractDefinitionServiceStub.java | 70 ------ .../ContractNegotiationServiceStub.java | 84 ------- .../services/PolicyDefinitionServiceStub.java | 83 ------- .../services/TransferProcessServiceStub.java | 102 -------- ...rg.eclipse.edc.spi.system.ServiceExtension | 21 -- .../edc/mock/RecordedRequestTest.java | 73 ------ .../src/test/resources/asset.creation.json | 24 -- .../src/test/resources/asset.failure.json | 24 -- .../build.gradle.kts | 38 --- .../mockedc/UseMockConnectorSampleTest.java | 141 ----------- .../resources/asset.creation.failure.json | 24 -- .../src/test/resources/asset.creation.json | 23 -- .../src/test/resources/asset.request.json | 22 -- .../test/resources/contractdef.creation.json | 33 --- .../resources/transferprocess.request.json | 21 -- settings.gradle.kts | 5 - 32 files changed, 1 insertion(+), 1972 deletions(-) delete mode 100644 docs/development/mock-edc.md delete mode 100644 edc-tests/runtime/mock-connector/build.gradle.kts delete mode 100644 edc-tests/runtime/mock-connector/notice.md delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/MatchType.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/MockServiceExtension.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/RecordedRequest.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/RecordedResponseDeserializer.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/ResponseQueue.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/ServiceFailureDeserializer.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/api/instrumentation/InstrumentationApi.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/api/instrumentation/InstrumentationApiController.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/AbstractServiceStub.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/AssetServiceStub.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractAgreementServiceStub.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractDefinitionServiceStub.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractNegotiationServiceStub.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/PolicyDefinitionServiceStub.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/TransferProcessServiceStub.java delete mode 100644 edc-tests/runtime/mock-connector/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension delete mode 100644 edc-tests/runtime/mock-connector/src/test/java/org/eclipse/tractusx/edc/mock/RecordedRequestTest.java delete mode 100644 edc-tests/runtime/mock-connector/src/test/resources/asset.creation.json delete mode 100644 edc-tests/runtime/mock-connector/src/test/resources/asset.failure.json delete mode 100644 samples/testing-with-mocked-connector/build.gradle.kts delete mode 100644 samples/testing-with-mocked-connector/src/test/java/org/eclipse/tractusx/edc/samples/mockedc/UseMockConnectorSampleTest.java delete mode 100644 samples/testing-with-mocked-connector/src/test/resources/asset.creation.failure.json delete mode 100644 samples/testing-with-mocked-connector/src/test/resources/asset.creation.json delete mode 100644 samples/testing-with-mocked-connector/src/test/resources/asset.request.json delete mode 100644 samples/testing-with-mocked-connector/src/test/resources/contractdef.creation.json delete mode 100644 samples/testing-with-mocked-connector/src/test/resources/transferprocess.request.json diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index d35829dd1b..166907cc40 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -65,8 +65,7 @@ jobs: matrix: variant: [ { dir: edc-controlplane, img: edc-runtime-memory }, { dir: edc-controlplane, img: edc-controlplane-postgresql-hashicorp-vault }, - { dir: edc-dataplane, img: edc-dataplane-hashicorp-vault }, - { dir: edc-tests/runtime, img: mock-connector }] + { dir: edc-dataplane, img: edc-dataplane-hashicorp-vault }] permissions: contents: read steps: diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 5af9f72003..d14ceb3e55 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -163,7 +163,6 @@ jobs: - name: Run Integration tests run: | - ./gradlew :edc-tests:runtime:mock-connector:dockerize ./gradlew test -DincludeTags="ComponentTest" api-tests: diff --git a/docs/development/mock-edc.md b/docs/development/mock-edc.md deleted file mode 100644 index 76a4b0fc71..0000000000 --- a/docs/development/mock-edc.md +++ /dev/null @@ -1,220 +0,0 @@ -# Using the Mock-Connector for contract-based testing - -Modern testing methodologies are based on small, independent units of code that have a defined behaviour. -Implementations as well as testing should be fast, repeatable, continuous and easily maintainable. In the context of EDC -that means, that downstream projects that are based on EDC should not need to run a fully-fledged connector runtime to -test their workflows. While the Tractus-X EDC project did provide a pure in-memory runtime for testing, that still -requires all the configuration and a complex runtime environment to work, which may be a high barrier of entry. - -For this reason, and to developers who primarily interact with the Management API of a connector, the Tractus-X EDC -project provides a testing framework with an even smaller footprint called the "Mock-Connector". It is a Docker image, that -contains just the Management API plus an instrumentation interface to enable developers to use this in their -unit/component testing and in continuous integration. - -We call this "contract-based testing", as it defines the specified behaviour of an application (here: the connector). -The Mock-Connector's Management API is guaranteed to behave exactly the same, in fact, it even runs the -same code as a "real" EDC. - -## 1. The contract - -The [Management API spec](https://eclipse-edc.github.io/Connector/openapi/management-api/). - -### 1.1 Definition of terms - -- connector: runnable Java application that contains Tractus-X modules. Also referred to as: EDC, runtime, tx-edc -- mock: a replacement for a collaborator object (class, component, application), where the behaviour can be - controlled -- stub: very similar to a mock, but while a mock oftentimes is a drop-in _replacement_, a stub would be a - re-implementation with a fixed behaviour. Also referred to as: dummy -- instrumentation: the process of setting up a mock to behave a certain way. Also referred to as priming the mock. - -## 2. Intended audience - -Developers who build their applications and systems based on EDC, and interact with EDC through the Management API can -use the Mock-Connector to decrease friction by not having to spin up and configure a fully-fledged connector runtime. - -Developers who plan to work with (Tractus-X) EDC in another way, like directly using its Maven artifacts, or even by -implementing a DSP protocol head are kindly redirected to -the [additional references section](#5-references-and-further-reading). - -## 3. Use with TestContainers - -Mock-Connector should be used as Docker image, we publish it as `tractusx/edc-mock`. - -Using the Mock-Connector is very easy, we recommend usage via Testcontainers. For example, setting up a JUnit test for a -client application using Testcontainers could be done as follows: - -```java - -@Testcontainers -@ComponentTest -public class UseMockedEdcSampleTest { - @Container - protected static GenericContainer edcContainer = new GenericContainer<>("tractusx/edc-mock:latest") - .withEnv("WEB_HTTP_PORT", "8080") - .withEnv("WEB_HTTP_PATH", "/api") - .withEnv("WEB_HTTP_MANAGEMENT_PORT", "8081") - .withEnv("WEB_HTTP_MANAGEMENT_PATH", "/api/management") - .withExposedPorts(8080, 8081); - private int managementPort; - private int defaultPort; - - @BeforeEach - void setup() { - managementPort = edcContainer.getMappedPort(8081); - defaultPort = edcContainer.getMappedPort(8080); - } -} -``` - -This downloads and runs the Docker image for the Mock-Connector and supplies it with minimal configuration. Specifically, it -exposes the Management API and the default context, because that is needed to set up the mock. - -> Please note that in -> the [example](../../samples/testing-with-mocked-edc/src/test/java/org/eclipse/tractusx/edc/samples/mockedc/UseMockedEdcSampleTest.java), -> the image name is `mock-edc` - that is because in our CI testing we build the image and then run the tests, so we -> can't use the official image. - -### 3.1 Running a simple positive test - -Executing a simple request against the Management API of EDC can be done like this: - -```java - -@Test -void test_getAsset() { - //prime the mock - post a RecordedRequest - setupNextResponse("asset.request.json"); - - // perform the actual Asset API request. In a real test scenario, this would be the client code we're testing, i.e. the - // System-under-Test (SuT). - var assetArray = mgmtRequest() - .contentType(ContentType.JSON) - .body(""" - { - "@context": { - "@vocab": "https://w3id.org/edc/v0.0.1/ns/" - }, - "@type": "QuerySpec" - } - """) - .post("/v3/assets/request") - .then() - .log().ifError() - .statusCode(200) - .extract().body().as(JsonArray.class); - - // assert the response - assertThat(assetArray).hasSize(1); - assertThat(assetArray.get(0).asJsonObject().get("properties")) - .hasFieldOrProperty("prop1") - .hasFieldOrProperty("id") - .hasFieldOrProperty("contenttype"); -} -``` - -### 3.2 Running a test expecting a failure - -```java - -@Test -void test_apiNotAuthenticated_expect400() { - //prime the mock - post a RecordedRequest - setupNextResponse("asset.creation.failure.json"); - - // perform the actual Asset API request. In a real test scenario, this would be the client code we're testing, i.e. the - // System-under-Test (SuT). - var assetArray = mgmtRequest() - .contentType(ContentType.JSON) - .body(""" - { - "@context": { - "@vocab": "https://w3id.org/edc/v0.0.1/ns/" - }, - "@type": "QuerySpec" - } - """) - .post("/v3/assets/request") - .then() - .log().ifError() - .statusCode(400) - .extract().body().as(JsonArray.class); - - // assert the response contains error information - assertThat(assetArray).hasSize(1); - var errorObject = assetArray.get(0).asJsonObject(); - assertThat(errorObject.get("message").toString()).contains("This user is not authorized, This is just a second error message"); -} -``` - -Note that the difference here is that we prime the mock with a different JSON file (more on that later), we expect a -different HTTP response code, i.e. 400, and the response body contains an error object instead of an array of Assets. - -## 4. Request pipeline and the instrumentation API - -The Mock-Connector internally contains a pipeline of "recorded requests", much like mocked HTTP webservers, like -WireMock or OkHttp MockWebServer. Out-of-the-box, that pipeline is empty, which means the Management API would always -respond with an error like the following: - -```json -[ - { - "message": "Failure: no recorded request left in queue.", - "type": "InvalidRequest", - "path": null, - "invalidValue": null - } -] -``` - -To get beyond that, we need to _prime_ the mock. That means, we need to tell it how to respond to the next request by -inserting a "recorded request" into its request pipeline. In previous code examples, this was done using -the `setupNextResponse()` method. Mock-Connector offers an instrumentation API which can be used to insert recorded requests, -to clear the queue and to get a count. - -### 4.1 Recorded requests - -A `RecordedRequest` is a POJO, that tells the Mock-Connector how to respond to the _next_ Management API request. To that end, -it contains the input parameter type, the data associated with it, plus the return value type plus - most importantly - -the data that is supposed to be returned. - -Recall the [previous example](#31-running-a-simple-positive-test), which tests an Asset request. Thus, we have to prime -the mock such that it responds with a list of `Asset` objects. The semantic being: "on the next request, respond -with ...". - -The contents of the [asset.request.json](../../samples/testing-with-mocked-edc/src/test/resources/asset.request.json) -contains a section that defines the `input`, which in this case is a `QuerySpec`, and the `output` is a list of `Asset` -objects. The `data` section must then contain serialized JSON that matches the `class` property. For instance, -the `data` section of the `input` must contain JSON that can be deserialized into an `Asset`. - -> _Note that the information about input and output datatypes must currently be obtained from the aggregate services. -Here, that would be the `AssetService` interface. In future iterations there will be a more convenient way to obtain -that information._ - -> _Note that input argument type matching is currently not supported, it will come in future releases._ - -### 4.2 Instrumentation API - -The instrumentation is done via a simple REST API: - -```shell -GET /api/instrumentation/count -> returns the number of requests in the queue -GET /api/instrumentation -> returns the list of queued requests -DELETE /api/instrumentation -> clears the queue -POST /api/instrumentation -> adds a new RecordedRequest, JSON must be in the request body -``` - -## 5. References and further reading - -- A complete sample how to run a test using the Mock-Connector in a Testcontainer can be - found [here](../../samples/testing-with-mocked-edc) -- To test compliance with DSP, use the [TCK](https://github.com/eclipse-dataspacetck/cvf) -- A Mock-DCP runtime is planned for future releases. - -## 6. Future improvements - -- matching requests to endpoints to allow for a "from-now-on" semantic -- introducing placeholders for domain objects to increase refactoring robustness -- abstract description of the endpoint's inputs and outputs, so developers don't need to know about service signatures - anymore -- request input matching \ No newline at end of file diff --git a/edc-tests/runtime/mock-connector/build.gradle.kts b/edc-tests/runtime/mock-connector/build.gradle.kts deleted file mode 100644 index d65d60a3f9..0000000000 --- a/edc-tests/runtime/mock-connector/build.gradle.kts +++ /dev/null @@ -1,71 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -plugins { - `java-library` - id("application") - alias(libs.plugins.shadow) - id(libs.plugins.swagger.get().pluginId) -} - - -dependencies { - // compile-time dependencies - implementation(libs.edc.spi.web) - implementation(libs.edc.spi.boot) - implementation(libs.edc.spi.controlplane) - implementation(libs.edc.lib.util) - - // runtime dependencies - runtimeOnly(libs.edc.core.runtime) - runtimeOnly(libs.edc.core.connector) - runtimeOnly(libs.edc.core.participant.context.single) - runtimeOnly(libs.edc.boot) - runtimeOnly(libs.edc.api.management) { - exclude("org.eclipse.edc", "edr-cache-api") - } - runtimeOnly(libs.edc.api.management.config) - - runtimeOnly(libs.edc.ext.http) - runtimeOnly(libs.bundles.edc.monitoring) - - // edc libs - runtimeOnly(libs.edc.ext.jsonld) - - testImplementation(libs.edc.junit) -} - -application { - mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") -} - -edcBuild { - publish.set(false) -} - -tasks.shadowJar { - mergeServiceFiles() - duplicatesStrategy = DuplicatesStrategy.INCLUDE - archiveFileName.set("${project.name}.jar") -} - - -application { - mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") -} diff --git a/edc-tests/runtime/mock-connector/notice.md b/edc-tests/runtime/mock-connector/notice.md deleted file mode 100644 index 1bfe0a6234..0000000000 --- a/edc-tests/runtime/mock-connector/notice.md +++ /dev/null @@ -1,28 +0,0 @@ -# Notice for Docker image - -A mocked EDC Management API providing an instrumentation API for configuration. - -DockerHub: - -Eclipse Tractus-X product(s) installed within the image: - -## Tractus-X EDC Control Plane - -- GitHub: -- Project home: -- Dockerfile: -- Project license: [Apache License, Version 2.0](https://github.com/eclipse-tractusx/tractusx-edc/blob/main/LICENSE) - -## Used base image - -- [eclipse-temurin:25.0.1_8-jre-alpine](https://github.com/adoptium/containers) -- Official Eclipse Temurin DockerHub page: -- Eclipse Temurin Project: -- Additional information about the Eclipse Temurin - images: - -As with all Docker images, these likely also contain other software which may be under other licenses (such as Bash, etc -from the base distribution, along with any direct or indirect dependencies of the primary software being contained). - -As for any pre-built image usage, it is the image user's responsibility to ensure that any use of this image complies -with any relevant licenses for all software contained within. diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/MatchType.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/MatchType.java deleted file mode 100644 index 348a09b70a..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/MatchType.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock; - -/** - * Represents how arguments are matched. - *

- * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public enum MatchType { - CLASS, PARTIAL, EXACT -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/MockServiceExtension.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/MockServiceExtension.java deleted file mode 100644 index eb3c788cee..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/MockServiceExtension.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock; - -import com.fasterxml.jackson.databind.module.SimpleModule; -import org.eclipse.edc.connector.controlplane.services.spi.asset.AssetService; -import org.eclipse.edc.connector.controlplane.services.spi.catalog.CatalogService; -import org.eclipse.edc.connector.controlplane.services.spi.contractagreement.ContractAgreementService; -import org.eclipse.edc.connector.controlplane.services.spi.contractdefinition.ContractDefinitionService; -import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationService; -import org.eclipse.edc.connector.controlplane.services.spi.policydefinition.PolicyDefinitionService; -import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessService; -import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; -import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.runtime.metamodel.annotation.Provider; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.query.QuerySpec; -import org.eclipse.edc.spi.response.StatusResult; -import org.eclipse.edc.spi.result.ServiceFailure; -import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.web.spi.WebService; -import org.eclipse.tractusx.edc.mock.api.instrumentation.InstrumentationApiController; -import org.eclipse.tractusx.edc.mock.services.AssetServiceStub; -import org.eclipse.tractusx.edc.mock.services.ContractAgreementServiceStub; -import org.eclipse.tractusx.edc.mock.services.ContractDefinitionServiceStub; -import org.eclipse.tractusx.edc.mock.services.ContractNegotiationServiceStub; -import org.eclipse.tractusx.edc.mock.services.PolicyDefinitionServiceStub; -import org.eclipse.tractusx.edc.mock.services.TransferProcessServiceStub; - -import java.util.Queue; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * Extension for the mock connector - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class MockServiceExtension implements ServiceExtension { - private final Queue> recordedRequests = new ConcurrentLinkedQueue<>(); - @Inject - private TypeManager typeManager; - - @Inject - private WebService webService; - - private Monitor monitor; - - @Override - public void initialize(ServiceExtensionContext context) { - monitor = context.getMonitor().withPrefix("ResponseQueue"); - webService.registerResource(new InstrumentationApiController(new ResponseQueue(recordedRequests, monitor))); - - // register custom deserializer for the ServiceFailure - var mapper = typeManager.getMapper(); - var module = new SimpleModule(); - module.addDeserializer(ServiceFailure.class, new ServiceFailureDeserializer()); - mapper.registerModule(module); - } - - @Provider - public AssetService mockAssetService(ServiceExtensionContext context) { - return new AssetServiceStub(new ResponseQueue(recordedRequests, monitor)); - } - - @Provider - public CatalogService mockCatalogService() { - return new CatalogService() { - @Override - public CompletableFuture> requestCatalog(ParticipantContext participantContext, String counterPartyId, String counterPartyAddress, String protocol, QuerySpec querySpec, String... additionalScopes) { - return null; - } - - @Override - public CompletableFuture> requestDataset(ParticipantContext participantContext, String id, String counterPartyId, String counterPartyAddress, String protocol) { - return null; - } - }; - } - - @Provider - public ContractAgreementService mockContractAgreementService() { - return new ContractAgreementServiceStub(new ResponseQueue(recordedRequests, monitor)); - } - - @Provider - public ContractDefinitionService mockContractDefService() { - return new ContractDefinitionServiceStub(new ResponseQueue(recordedRequests, monitor)); - } - - @Provider - public ContractNegotiationService mockContractNegService() { - return new ContractNegotiationServiceStub(new ResponseQueue(recordedRequests, monitor)); - } - - @Provider - public PolicyDefinitionService mockPolicyDefService() { - return new PolicyDefinitionServiceStub(new ResponseQueue(recordedRequests, monitor)); - } - - @Provider - public TransferProcessService mockTransferProcessService() { - return new TransferProcessServiceStub(new ResponseQueue(recordedRequests, monitor)); - } - -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/RecordedRequest.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/RecordedRequest.java deleted file mode 100644 index 40ec1bd09e..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/RecordedRequest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import org.eclipse.edc.spi.result.ServiceFailure; - -/** - * Represents a request, that the service stub will replay. It has an input object (can be null), an output object, some metadata - * like name and description and a {@link MatchType}. - * In addition, it can have a {@link ServiceFailure}, in which case the {@code output} object is disregarded and the failure is always returned. - * This can be used to mock a failed API call. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -@JsonDeserialize(using = RecordedResponseDeserializer.class) -public final class RecordedRequest { - private final I input; - private final O output; - private String description; - private String name; - private MatchType inputMatchType; - private ServiceFailure failure; - - private RecordedRequest(I input, O output) { - this.input = input; - this.output = output; - } - - public I getInput() { - return input; - } - - public O getOutput() { - return output; - } - - public MatchType getInputMatchType() { - return inputMatchType; - } - - public ServiceFailure getFailure() { - return failure; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public static class Builder { - private final RecordedRequest instance; - - public Builder(I input, O output) { - instance = new RecordedRequest<>(input, output); - } - - public Builder inputMatchType(MatchType input) { - instance.inputMatchType = input; - return this; - } - - public Builder name(String name) { - instance.name = name; - return this; - } - - public Builder description(String description) { - instance.description = description; - return this; - } - - public Builder failure(ServiceFailure failure) { - instance.failure = failure; - return this; - } - - public RecordedRequest build() { - return instance; - } - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/RecordedResponseDeserializer.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/RecordedResponseDeserializer.java deleted file mode 100644 index 78958fcaa2..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/RecordedResponseDeserializer.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import org.eclipse.edc.spi.result.ServiceFailure; - -import java.io.IOException; -import java.util.Optional; - -/** - * Custom deserializer for a {@link RecordedRequest} object, to be able to instantiate the input and output objects according - * to their class description. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -class RecordedResponseDeserializer extends StdDeserializer> { - - public static final String INPUT_OBJECT = "input"; - public static final String OUTPUT_OBJECT = "output"; - public static final String CLASS_FIELD = "class"; - public static final String DATA_FIELD = "data"; - public static final String INPUT_MATCH_TYPE_FIELD = "match_type"; - public static final String NAME_FIELD = "name"; - public static final String DESCRIPTION_FIELD = "description"; - private static final String FAILURE_OBJECT = "failure"; - - RecordedResponseDeserializer() { - this(null); - } - - protected RecordedResponseDeserializer(Class vc) { - super(vc); - } - - @Override - public RecordedRequest deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { - JsonNode node = jp.getCodec().readTree(jp); - var input = node.get(INPUT_OBJECT); - var output = node.get(OUTPUT_OBJECT); - try { - var inputClass = Class.forName(input.get(CLASS_FIELD).asText()); - var outputClass = Class.forName(output.get(CLASS_FIELD).asText()); - - var inputObj = ctxt.readTreeAsValue(input.get(DATA_FIELD), inputClass); - var matchType = Optional.ofNullable(input.get("matchType")).map(JsonNode::asText).map(MatchType::valueOf).orElse(MatchType.CLASS); - var outputObj = ctxt.readTreeAsValue(output.get(DATA_FIELD), outputClass); - - return new RecordedRequest.Builder(inputObj, outputObj) - .inputMatchType(matchType) - .failure(ctxt.readTreeAsValue(node.get(FAILURE_OBJECT), ServiceFailure.class)) - .name(Optional.ofNullable(node.get(NAME_FIELD)).map(JsonNode::asText).orElse(null)) - .description(Optional.ofNullable(node.get(DESCRIPTION_FIELD)).map(JsonNode::asText).orElse(null)) - .build(); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/ResponseQueue.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/ResponseQueue.java deleted file mode 100644 index 6e4db2b674..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/ResponseQueue.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock; - -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.spi.result.ServiceFailure; -import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.edc.web.spi.exception.InvalidRequestException; - -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.List; -import java.util.Queue; - -/** - * Container object that maintains the queue of {@link RecordedRequest} objects and grants high-level access to it. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class ResponseQueue { - private final Queue> recordedRequests; // todo guard access with locks? - private final Monitor monitor; - - public ResponseQueue(Queue> recordedRequests, Monitor monitor) { - this.recordedRequests = recordedRequests; - this.monitor = monitor.withPrefix(getClass().getSimpleName()); - } - - public ServiceResult getNext(Class outputClass, String errorMessageTemplate) { - try { - return getNext(outputClass); - } catch (ClassCastException ex) { - var message = errorMessageTemplate.formatted(ex.getMessage()); - monitor.severe(message); // no need for the entire stack trace - return ServiceResult.badRequest(message); - } - } - - /** - * Gets the next item from the request queue and wraps it in a {@link ServiceResult}, where the generic type is a list type. - * To do that, the class of list type is expected as parameter. - * - * @param arrayElementClass The type of elements that are expected to be in the list - * @param errorMessageTemplate An error string template that should contain the '%s' placeholder to receive additional information - * @return A {@link ServiceResult} that contains the payload of the next request - */ - @SuppressWarnings("unchecked") - public ServiceResult> getNextAsList(Class arrayElementClass, String errorMessageTemplate) { - if (arrayElementClass.isArray()) { - return ServiceResult.badRequest("First parameter must be type of list elements. For example, pass Object.class if a List is expected, but '%s' was passed".formatted(arrayElementClass.getName())); - } - var r = Result.ofThrowable(() -> { - T[] serviceResult = (T[]) getNext(arrayElementClass.arrayType(), errorMessageTemplate).orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); - return Arrays.asList(serviceResult); - }); - if (r.succeeded()) { - return ServiceResult.success(r.getContent()); - } - monitor.severe(errorMessageTemplate.formatted(r.getFailureDetail())); - return ServiceResult.badRequest(r.getFailureDetail()); - } - - /** - * clear the queue - */ - public void clear() { - recordedRequests.clear(); - } - - /** - * adds a {@link RecordedRequest} - */ - public void append(RecordedRequest recordedRequest) { - recordedRequests.offer(recordedRequest); - } - - /** - * provides the contents of the queue as a list - */ - public List> toList() { - return recordedRequests.stream().toList(); //immutable - } - - /** - * Takes the next element from the queue and converts it into a {@link ServiceResult} - * - * @param outputType The desired output type. If the type description in the {@link RecordedRequest} does not match, a failure is returned. - */ - @SuppressWarnings("unchecked") - private ServiceResult getNext(Class outputType) { - monitor.debug("Get next recorded request, expect output of type %s".formatted(outputType)); - var r = recordedRequests.poll(); - - - if (r != null) { - - if (r.getFailure() != null) { - return createResult(r.getFailure()); - } - - monitor.debug("Recorded request fetched, %d remaining.".formatted(recordedRequests.size())); - var recipeOutputType = r.getOutput().getClass(); - if (!recipeOutputType.isAssignableFrom(outputType)) { - return ServiceResult.badRequest("Type mismatch: service invocation requires output type '%s', but Recipe specifies '%s'".formatted(outputType, recipeOutputType)); - } - var output = (T) r.getOutput(); - return ServiceResult.success(output); - } - var message = "Failure: no recorded request left in queue."; - monitor.debug(message); - return ServiceResult.badRequest(message); - } - - // hack to access a protected constructor of the ServiceFailure - private ServiceResult createResult(ServiceFailure failure) { - try { - var ctor = ServiceResult.class.getDeclaredConstructor(Object.class, ServiceFailure.class); - ctor.setAccessible(true); // hack hack hack! I feel dirty doing this... - return (ServiceResult) ctor.newInstance(null, failure); - } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | - InvocationTargetException e) { - throw new EdcException(e); - } - } - - //todo: add method getNextWithMatch that accepts an input and a match type -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/ServiceFailureDeserializer.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/ServiceFailureDeserializer.java deleted file mode 100644 index 26755cb012..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/ServiceFailureDeserializer.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import org.eclipse.edc.spi.result.ServiceFailure; - -import java.io.IOException; -import java.util.Arrays; - -/** - * Custom deserializer for {@link ServiceFailure}. We need this because there is no default - * CTor, and the public constructor with args is not annotated with {@link com.fasterxml.jackson.annotation.JsonProperty}. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class ServiceFailureDeserializer extends StdDeserializer { - public static final String REASON_FIELD = "reason"; - public static final String MESSAGES_FIELD = "messages"; - - protected ServiceFailureDeserializer(Class vc) { - super(vc); - } - - public ServiceFailureDeserializer() { - this(null); - } - - @Override - public ServiceFailure deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { - JsonNode node = jp.getCodec().readTree(jp); - var reason = ServiceFailure.Reason.valueOf(node.get(REASON_FIELD).asText()); - var msgs = Arrays.asList(ctxt.readTreeAsValue(node.get(MESSAGES_FIELD), String[].class)); - - return new ServiceFailure(msgs, reason); - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/api/instrumentation/InstrumentationApi.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/api/instrumentation/InstrumentationApi.java deleted file mode 100644 index 0f74690552..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/api/instrumentation/InstrumentationApi.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.api.instrumentation; - -import io.swagger.v3.oas.annotations.OpenAPIDefinition; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.info.Info; -import io.swagger.v3.oas.annotations.media.ArraySchema; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.eclipse.edc.web.spi.ApiErrorDetail; -import org.eclipse.tractusx.edc.mock.RecordedRequest; - -import java.util.List; - -/** - * Instrumentation API for the mock connector. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -@OpenAPIDefinition(info = @Info(description = "This API allows to insert ", title = "Business Partner Group API")) -@Tag(name = "Business Partner Group") -public interface InstrumentationApi { - - @Operation(description = "Adds a new RecordedRequest to the end of the queue.", - responses = { - @ApiResponse(responseCode = "204", description = "The negotiation was successfully initiated."), - @ApiResponse(responseCode = "400", description = "Request body was malformed", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))), - }) - void addNewRequest(RecordedRequest recordedRequest); - - @Operation(description = "Clears the entire request queue.", - responses = { - @ApiResponse(responseCode = "204", description = "The queue was successfully cleared.") - }) - void clearQueue(); - - @Operation(description = "Return the entire request queue.", - responses = { - @ApiResponse(responseCode = "200", description = "The list of RecordedRequest objects.", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = RecordedRequest.class)))), - }) - List> getRequests(); - - @Operation(description = "Return amount of items currently in the queue.", - responses = { - @ApiResponse(responseCode = "200") - }) - int count(); -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/api/instrumentation/InstrumentationApiController.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/api/instrumentation/InstrumentationApiController.java deleted file mode 100644 index eaca4abe60..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/api/instrumentation/InstrumentationApiController.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.api.instrumentation; - - -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import org.eclipse.tractusx.edc.mock.RecordedRequest; -import org.eclipse.tractusx.edc.mock.ResponseQueue; - -import java.util.List; - -/** - * Instrumentation controller for the mock connector. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -@Consumes({ MediaType.APPLICATION_JSON }) -@Produces({ MediaType.APPLICATION_JSON }) -@Path("/instrumentation") -public class InstrumentationApiController implements InstrumentationApi { - - private final ResponseQueue responseQueue; - - public InstrumentationApiController(ResponseQueue responseQueue) { - this.responseQueue = responseQueue; - } - - @Override - @POST - public void addNewRequest(RecordedRequest recordedRequest) { - responseQueue.append(recordedRequest); - } - - @Override - @DELETE - public void clearQueue() { - responseQueue.clear(); - } - - @Override - @GET - public List> getRequests() { - return responseQueue.toList(); - } - - @Override - @GET - @Path("/count") - public int count() { - return responseQueue.toList().size(); - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/AbstractServiceStub.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/AbstractServiceStub.java deleted file mode 100644 index 83f26a9899..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/AbstractServiceStub.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.services; - -import org.eclipse.tractusx.edc.mock.ResponseQueue; - -/** - * For abstract service stubs. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public abstract class AbstractServiceStub { - protected final ResponseQueue responseQueue; - - public AbstractServiceStub(ResponseQueue responseQueue) { - this.responseQueue = responseQueue; - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/AssetServiceStub.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/AssetServiceStub.java deleted file mode 100644 index 64a746302d..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/AssetServiceStub.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.services; - -import org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset; -import org.eclipse.edc.connector.controlplane.services.spi.asset.AssetService; -import org.eclipse.edc.spi.query.QuerySpec; -import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.mock.ResponseQueue; - -import java.util.List; - -/** - * Stub implementation of the {@link AssetService} for testing purposes. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class AssetServiceStub implements AssetService { - - private final ResponseQueue responseQueue; - - public AssetServiceStub(ResponseQueue responseQueue) { - this.responseQueue = responseQueue; - } - - @Override - public Asset findById(String assetId) { - return responseQueue.getNext(Asset.class, "Error finding asset by ID: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public ServiceResult> search(QuerySpec query) { - return responseQueue.getNextAsList(Asset.class, "Error executing asset search: %s"); - } - - @Override - public ServiceResult create(Asset asset) { - return responseQueue.getNext(Asset.class, "Error executing asset creation: %s"); - } - - @Override - public ServiceResult delete(String assetId) { - return responseQueue.getNext(Asset.class, "Error executing asset deletion: %s"); - } - - @Override - public ServiceResult update(Asset asset) { - return responseQueue.getNext(Asset.class, "Error executing asset update: %s"); - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractAgreementServiceStub.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractAgreementServiceStub.java deleted file mode 100644 index b03cf11d5e..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractAgreementServiceStub.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.services; - -import org.eclipse.edc.connector.controlplane.contract.spi.types.agreement.ContractAgreement; -import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiation; -import org.eclipse.edc.connector.controlplane.services.spi.contractagreement.ContractAgreementService; -import org.eclipse.edc.spi.query.QuerySpec; -import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.mock.ResponseQueue; - -import java.util.List; - -/** - * Stub implementation of the {@link ContractAgreementService} for testing purposes. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class ContractAgreementServiceStub extends AbstractServiceStub implements ContractAgreementService { - - public ContractAgreementServiceStub(ResponseQueue responseQueue) { - super(responseQueue); - } - - @Override - public ContractAgreement findById(String contractAgreementId) { - return responseQueue.getNext(ContractAgreement.class, "Error finding ContractAgreement: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public ServiceResult> search(QuerySpec query) { - return responseQueue.getNextAsList(ContractAgreement.class, "Error searching ContractAgreement: %s"); - } - - @Override - public ContractNegotiation findNegotiation(String contractAgreementId) { - return responseQueue.getNext(ContractNegotiation.class, "Error finding ContractNegotiation: %s") - .orElseThrow(InvalidRequestException::new); - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractDefinitionServiceStub.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractDefinitionServiceStub.java deleted file mode 100644 index 83c3ae19e1..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractDefinitionServiceStub.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.services; - -import org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition; -import org.eclipse.edc.connector.controlplane.services.spi.contractdefinition.ContractDefinitionService; -import org.eclipse.edc.spi.query.QuerySpec; -import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.mock.ResponseQueue; - -import java.util.List; - -/** - * Stub implementation of the {@link ContractDefinitionService}. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class ContractDefinitionServiceStub extends AbstractServiceStub implements ContractDefinitionService { - - - public ContractDefinitionServiceStub(ResponseQueue responseQueue) { - super(responseQueue); - - } - - @Override - public ContractDefinition findById(String contractDefinitionId) { - return responseQueue.getNext(ContractDefinition.class, "Error finding ContractDefinition: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public ServiceResult> search(QuerySpec query) { - return responseQueue.getNextAsList(ContractDefinition.class, "Error searching ContractDefinition: %s"); - } - - @Override - public ServiceResult create(ContractDefinition contractDefinition) { - return responseQueue.getNext(ContractDefinition.class, "Error creating ContractDefinition: %s"); - } - - @Override - public ServiceResult update(ContractDefinition contractDefinition) { - return responseQueue.getNext(Void.class, "Error updating ContractDefinition: %s"); - } - - @Override - public ServiceResult delete(String contractDefinitionId) { - return responseQueue.getNext(ContractDefinition.class, "Error deleting ContractDefinition: %s"); - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractNegotiationServiceStub.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractNegotiationServiceStub.java deleted file mode 100644 index d4009dcd67..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/ContractNegotiationServiceStub.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.services; - -import org.eclipse.edc.connector.controlplane.contract.spi.types.agreement.ContractAgreement; -import org.eclipse.edc.connector.controlplane.contract.spi.types.command.TerminateNegotiationCommand; -import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiation; -import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractRequest; -import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationService; -import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; -import org.eclipse.edc.spi.query.QuerySpec; -import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.mock.ResponseQueue; - -import java.util.List; - -/** - * Stub implementation of the {@link ContractNegotiationService} for testing purposes. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class ContractNegotiationServiceStub extends AbstractServiceStub implements ContractNegotiationService { - public ContractNegotiationServiceStub(ResponseQueue responseQueue) { - super(responseQueue); - } - - @Override - public ContractNegotiation findbyId(String contractNegotiationId) { - return responseQueue.getNext(ContractNegotiation.class, "Error finding ContractNegotiation: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public ServiceResult> search(QuerySpec query) { - return responseQueue.getNextAsList(ContractNegotiation.class, "Error searching for ContractNegotiation: %s"); - } - - @Override - public String getState(String negotiationId) { - return responseQueue.getNext(String.class, "Error getting state of ContractNegotiation: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public ContractAgreement getForNegotiation(String negotiationId) { - return responseQueue.getNext(ContractAgreement.class, "Error getting ContractAgreement: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public ContractNegotiation initiateNegotiation(ParticipantContext participantContext, ContractRequest request) { - return responseQueue.getNext(ContractNegotiation.class, "Error initiating ContractNegotiation: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public ServiceResult terminate(TerminateNegotiationCommand command) { - return responseQueue.getNext(Void.class, "Error terminating ContractAgreement: %s"); - } - - @Override - public ServiceResult delete(String negotiationId) { - return responseQueue.getNext(Void.class, "Error deleting ContractAgreement: %s"); - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/PolicyDefinitionServiceStub.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/PolicyDefinitionServiceStub.java deleted file mode 100644 index 424c48fe4b..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/PolicyDefinitionServiceStub.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.services; - -import org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition; -import org.eclipse.edc.connector.controlplane.services.spi.policydefinition.PolicyDefinitionService; -import org.eclipse.edc.policy.engine.spi.plan.PolicyEvaluationPlan; -import org.eclipse.edc.policy.model.Policy; -import org.eclipse.edc.spi.query.QuerySpec; -import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.mock.ResponseQueue; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -/** - * Stub implementation of the PolicyDefinitionService. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class PolicyDefinitionServiceStub extends AbstractServiceStub implements PolicyDefinitionService { - - public PolicyDefinitionServiceStub(ResponseQueue responseQueue) { - super(responseQueue); - } - - @Override - public PolicyDefinition findById(String policyId) { - return responseQueue.getNext(PolicyDefinition.class, "Error finding PolicyDefinition by id: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public ServiceResult> search(QuerySpec query) { - return responseQueue.getNextAsList(PolicyDefinition.class, "Error executing PolicyDefinition search: %s"); - } - - @Override - public @NotNull ServiceResult deleteById(String policyId) { - return responseQueue.getNext(PolicyDefinition.class, "Error deleting PolicyDefinition: %s"); - } - - @Override - public @NotNull ServiceResult create(PolicyDefinition policy) { - return responseQueue.getNext(PolicyDefinition.class, "Error creating PolicyDefinition: %s"); - } - - @Override - public ServiceResult update(PolicyDefinition policy) { - return responseQueue.getNext(PolicyDefinition.class, "Error updating PolicyDefinition: %s"); - } - - @Override - public ServiceResult validate(Policy policy) { - return responseQueue.getNext(Void.class, "Error validating PolicyDefinition: %s"); - } - - @Override - public ServiceResult createEvaluationPlan(String s, Policy policy) { - return responseQueue.getNext(PolicyEvaluationPlan.class, "Error creating evaluation plan for PolicyDefinition: %s"); - } - - -} diff --git a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/TransferProcessServiceStub.java b/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/TransferProcessServiceStub.java deleted file mode 100644 index 1ecf47bcee..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/java/org/eclipse/tractusx/edc/mock/services/TransferProcessServiceStub.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock.services; - -import org.eclipse.edc.connector.controlplane.services.spi.transferprocess.TransferProcessService; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferRequest; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.NotifyPreparedCommand; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.NotifyStartedCommand; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.ResumeTransferCommand; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.SuspendTransferCommand; -import org.eclipse.edc.connector.controlplane.transfer.spi.types.command.TerminateTransferCommand; -import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; -import org.eclipse.edc.spi.query.QuerySpec; -import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.mock.ResponseQueue; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; - -/** - * Stub implementation of the {@link TransferProcessService} for testing purposes. - * - * @deprecated since 0.11.0 - */ -@Deprecated(since = "0.11.0") -public class TransferProcessServiceStub extends AbstractServiceStub implements TransferProcessService { - - public TransferProcessServiceStub(ResponseQueue responseQueue) { - super(responseQueue); - } - - @Override - public @Nullable TransferProcess findById(String transferProcessId) { - return responseQueue.getNext(TransferProcess.class, "Error finding TransferProcess: %s").orElseThrow(f -> new InvalidRequestException(f.getFailureDetail())); - } - - @Override - public ServiceResult> search(QuerySpec query) { - return responseQueue.getNextAsList(TransferProcess.class, "Error executing TransferProcess search: %s"); - } - - @Override - public @Nullable String getState(String transferProcessId) { - return responseQueue.getNext(String.class, "Error obtaining TransferProcess status: %s") - .orElseThrow(InvalidRequestException::new); - } - - @Override - public @NotNull ServiceResult complete(String transferProcessId) { - return responseQueue.getNext(Void.class, "Error completing TransferProcess: %s"); - } - - @Override - public @NotNull ServiceResult terminate(TerminateTransferCommand command) { - return responseQueue.getNext(Void.class, "Error terminating TransferProcess: %s"); - } - - @Override - public @NotNull ServiceResult suspend(SuspendTransferCommand command) { - return responseQueue.getNext(Void.class, "Error suspending TransferProcess: %s"); - } - - @Override - public @NotNull ServiceResult resume(ResumeTransferCommand command) { - return responseQueue.getNext(Void.class, "Error resuming TransferProcess: %s"); - } - - @Override - public @NotNull ServiceResult initiateTransfer(ParticipantContext participantContext, TransferRequest request) { - return responseQueue.getNext(TransferProcess.class, "Error initiating TransferProcess: %s"); - } - - @Override - public ServiceResult notifyPrepared(NotifyPreparedCommand command) { - return responseQueue.getNext(Void.class, "Error notifying prepared on TransferProcess: %s"); - } - - @Override - public ServiceResult notifyStarted(NotifyStartedCommand command) { - return responseQueue.getNext(Void.class, "Error notifying started on TransferProcess: %s"); - } -} diff --git a/edc-tests/runtime/mock-connector/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-tests/runtime/mock-connector/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension deleted file mode 100644 index 3de76bc517..0000000000 --- a/edc-tests/runtime/mock-connector/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ /dev/null @@ -1,21 +0,0 @@ -################################################################################# -# Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# 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. -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# SPDX-License-Identifier: Apache-2.0 -################################################################################# - -org.eclipse.tractusx.edc.mock.MockServiceExtension - diff --git a/edc-tests/runtime/mock-connector/src/test/java/org/eclipse/tractusx/edc/mock/RecordedRequestTest.java b/edc-tests/runtime/mock-connector/src/test/java/org/eclipse/tractusx/edc/mock/RecordedRequestTest.java deleted file mode 100644 index e8e2853eef..0000000000 --- a/edc-tests/runtime/mock-connector/src/test/java/org/eclipse/tractusx/edc/mock/RecordedRequestTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.mock; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; -import org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset; -import org.eclipse.edc.junit.testfixtures.TestUtils; -import org.eclipse.edc.spi.result.ServiceFailure; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class RecordedRequestTest { - - private final ObjectMapper mapper = new ObjectMapper(); - - @BeforeEach - void setup() { - var module = new SimpleModule(); - module.addDeserializer(ServiceFailure.class, new ServiceFailureDeserializer()); - mapper.registerModule(module); - } - - @Test - void verifySerDes() throws JsonProcessingException { - var json = TestUtils.getResourceFileContentAsString("asset.creation.json"); - var rr = mapper.readValue(json, RecordedRequest.class); - - assertThat(rr).isNotNull(); - assertThat(rr.getInput()).isInstanceOf(Asset.class); - assertThat(rr.getOutput()).isInstanceOf(Asset.class); - assertThat(rr.getInputMatchType()).isEqualTo(MatchType.CLASS); - assertThat(rr.getFailure()).isNull(); - assertThat(rr.getName()).isEqualTo("Asset Creation V3"); - assertThat(rr.getDescription()).isEqualTo("test description"); - } - - @Test - void verifySerDes_withFailure() throws JsonProcessingException { - var json = TestUtils.getResourceFileContentAsString("asset.failure.json"); - var rr = mapper.readValue(json, RecordedRequest.class); - - assertThat(rr).isNotNull(); - assertThat(rr.getInput()).isInstanceOf(Asset.class); - assertThat(rr.getOutput()).isNull(); - assertThat(rr.getInputMatchType()).isEqualTo(MatchType.CLASS); - assertThat(rr.getName()).isEqualTo("Some failed asset request"); - assertThat(rr.getDescription()).isEqualTo("test description"); - assertThat(rr.getFailure()).isInstanceOf(ServiceFailure.class); - assertThat(rr.getFailure().getReason()).isEqualTo(ServiceFailure.Reason.UNAUTHORIZED); - assertThat(rr.getFailure().getMessages()).containsExactlyInAnyOrder("message 1", "message 2"); - } -} \ No newline at end of file diff --git a/edc-tests/runtime/mock-connector/src/test/resources/asset.creation.json b/edc-tests/runtime/mock-connector/src/test/resources/asset.creation.json deleted file mode 100644 index e22569a120..0000000000 --- a/edc-tests/runtime/mock-connector/src/test/resources/asset.creation.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "Asset Creation V3", - "description": "test description", - "input": { - "class": "org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset", - "data": { - "id": "asset-1", - "properties": { - "https://w3id.org/edc/v0.0.1/ns/contenttype": "application/json", - "https://w3id.org/edc/v0.0.1/ns/prop1": "value1" - } - } - }, - "output": { - "class": "org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset", - "data": { - "id": "asset-1", - "properties": { - "https://w3id.org/edc/v0.0.1/ns/contenttype": "application/json", - "https://w3id.org/edc/v0.0.1/ns/prop1": "value1" - } - } - } -} \ No newline at end of file diff --git a/edc-tests/runtime/mock-connector/src/test/resources/asset.failure.json b/edc-tests/runtime/mock-connector/src/test/resources/asset.failure.json deleted file mode 100644 index 22af583514..0000000000 --- a/edc-tests/runtime/mock-connector/src/test/resources/asset.failure.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "Some failed asset request", - "description": "test description", - "input": { - "class": "org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset", - "data": { - "id": "asset-1", - "properties": { - "https://w3id.org/edc/v0.0.1/ns/contenttype": "application/json", - "https://w3id.org/edc/v0.0.1/ns/prop1": "value1" - } - } - }, - "output": { - "class": "org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset" - }, - "failure": { - "reason": "UNAUTHORIZED", - "messages": [ - "message 1", - "message 2" - ] - } -} \ No newline at end of file diff --git a/samples/testing-with-mocked-connector/build.gradle.kts b/samples/testing-with-mocked-connector/build.gradle.kts deleted file mode 100644 index c66ca63fd4..0000000000 --- a/samples/testing-with-mocked-connector/build.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -plugins { - `java-library` - `java-test-fixtures` -} - -dependencies { - testImplementation(testFixtures(project(":edc-tests:e2e-fixtures"))) - - testImplementation(libs.testcontainers.junit) - testImplementation(libs.wiremock) - testImplementation(libs.edc.junit) - testImplementation(libs.restAssured) - testImplementation(libs.awaitility) -} - -// do not publish -edcBuild { - publish.set(false) -} diff --git a/samples/testing-with-mocked-connector/src/test/java/org/eclipse/tractusx/edc/samples/mockedc/UseMockConnectorSampleTest.java b/samples/testing-with-mocked-connector/src/test/java/org/eclipse/tractusx/edc/samples/mockedc/UseMockConnectorSampleTest.java deleted file mode 100644 index 93756903e1..0000000000 --- a/samples/testing-with-mocked-connector/src/test/java/org/eclipse/tractusx/edc/samples/mockedc/UseMockConnectorSampleTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.samples.mockedc; - -import io.restassured.http.ContentType; -import io.restassured.specification.RequestSpecification; -import jakarta.json.JsonArray; -import org.eclipse.edc.junit.annotations.ComponentTest; -import org.eclipse.edc.junit.testfixtures.TestUtils; -import org.junit.jupiter.api.Test; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.junit.jupiter.Container; -import org.testcontainers.junit.jupiter.Testcontainers; - -import static io.restassured.RestAssured.given; -import static org.assertj.core.api.Assertions.assertThat; - -/** - * This example demonstrates how to use the Mock-Connector as a drop-in replacement runtime for testing client code that uses EDC's - * Management API. While this is written in Java, the concepts are easily translatable into any language where test containers are - * supported. - */ -@Testcontainers -@ComponentTest -public class UseMockConnectorSampleTest { - - private static final int DEFAULT_PORT = 8080; - private static final int MANAGEMENT_PORT = 8081; - - @Container - private final GenericContainer edcContainer = new GenericContainer<>("mock-connector") - .withEnv("WEB_HTTP_PORT", String.valueOf(DEFAULT_PORT)) - .withEnv("WEB_HTTP_PATH", "/api") - .withEnv("WEB_HTTP_MANAGEMENT_PORT", String.valueOf(MANAGEMENT_PORT)) - .withEnv("WEB_HTTP_MANAGEMENT_PATH", "/api/management") - .withExposedPorts(DEFAULT_PORT, MANAGEMENT_PORT) - .withLogConsumer(o -> System.out.println(o.getUtf8StringWithoutLineEnding())) - .waitingFor(Wait.forLogMessage(".* ready.*", 1)); - - @Test - void test_getAsset() { - //prime the mock - post a RecordedRequest - setupNextResponse("asset.request.json"); - - // perform the actual Asset API request. In a real test scenario, this would be the client code we're testing, i.e. the - // System-under-Test (SuT). - var assetArray = mgmtRequest() - .contentType(ContentType.JSON) - .body(""" - { - "@context": { - "@vocab": "https://w3id.org/edc/v0.0.1/ns/" - }, - "@type": "QuerySpec" - } - """) - .post("/v3/assets/request") - .then() - .log().ifValidationFails() - .statusCode(200) - .extract().body().as(JsonArray.class); - - // assert the response - assertThat(assetArray).hasSize(1); - assertThat(assetArray.get(0).asJsonObject().get("properties")) - .hasFieldOrProperty("prop1") - .hasFieldOrProperty("id") - .hasFieldOrProperty("contenttype"); - } - - @Test - void test_apiNotAuthenticated_expect400() { - //prime the mock - post a RecordedRequest - setupNextResponse("asset.creation.failure.json"); - - // perform the actual Asset API request. In a real test scenario, this would be the client code we're testing, i.e. the - // System-under-Test (SuT). - var assetArray = mgmtRequest() - .contentType(ContentType.JSON) - .body(""" - { - "@context": { - "@vocab": "https://w3id.org/edc/v0.0.1/ns/" - }, - "@type": "QuerySpec" - } - """) - .post("/v3/assets/request") - .then() - .log().ifValidationFails() - .statusCode(400) - .extract().body().as(JsonArray.class); - - // assert the response contains error information - assertThat(assetArray).hasSize(1); - var errorObject = assetArray.get(0).asJsonObject(); - assertThat(errorObject.get("message").toString()).contains("This user is not authorized, This is just a second error message"); - } - - private void setupNextResponse(String resourceFileName) { - var json = TestUtils.getResourceFileContentAsString(resourceFileName); - - apiRequest() - .contentType(ContentType.JSON) - .body(json) - .post("/instrumentation") - .then() - .log().ifValidationFails() - .statusCode(204); - } - - private RequestSpecification apiRequest() { - return given() - .baseUri("http://localhost:" + edcContainer.getMappedPort(DEFAULT_PORT) + "/api") - .when(); - } - - private RequestSpecification mgmtRequest() { - return given() - .baseUri("http://localhost:" + edcContainer.getMappedPort(MANAGEMENT_PORT) + "/api/management") - .when(); - } -} diff --git a/samples/testing-with-mocked-connector/src/test/resources/asset.creation.failure.json b/samples/testing-with-mocked-connector/src/test/resources/asset.creation.failure.json deleted file mode 100644 index 32d5b8459e..0000000000 --- a/samples/testing-with-mocked-connector/src/test/resources/asset.creation.failure.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "Some failed asset request", - "description": "test description", - "input": { - "class": "org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset", - "data": { - "id": "asset-1", - "properties": { - "https://w3id.org/edc/v0.0.1/ns/contenttype": "application/json", - "https://w3id.org/edc/v0.0.1/ns/prop1": "value1" - } - } - }, - "output": { - "class": "org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset" - }, - "failure": { - "reason": "UNAUTHORIZED", - "messages": [ - "This user is not authorized", - "This is just a second error message" - ] - } -} \ No newline at end of file diff --git a/samples/testing-with-mocked-connector/src/test/resources/asset.creation.json b/samples/testing-with-mocked-connector/src/test/resources/asset.creation.json deleted file mode 100644 index 1f26e3e33c..0000000000 --- a/samples/testing-with-mocked-connector/src/test/resources/asset.creation.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "Asset Creation V3", - "input": { - "class": "org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset", - "data": { - "id": "asset-1", - "properties": { - "https://w3id.org/edc/v0.0.1/ns/contenttype": "application/json", - "https://w3id.org/edc/v0.0.1/ns/prop1": "value1" - } - } - }, - "output": { - "class": "org.eclipse.edc.connector.controlplane.asset.spi.domain.Asset", - "data": { - "id": "asset-1", - "properties": { - "https://w3id.org/edc/v0.0.1/ns/contenttype": "application/json", - "https://w3id.org/edc/v0.0.1/ns/prop1": "value1" - } - } - } -} \ No newline at end of file diff --git a/samples/testing-with-mocked-connector/src/test/resources/asset.request.json b/samples/testing-with-mocked-connector/src/test/resources/asset.request.json deleted file mode 100644 index 1f3dcafd88..0000000000 --- a/samples/testing-with-mocked-connector/src/test/resources/asset.request.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "Asset Query v3", - "input": { - "class": "org.eclipse.edc.spi.query.QuerySpec", - "data": { - "offset": 0, - "sortOrder": "DESC" - } - }, - "output": { - "class": "[Lorg.eclipse.edc.connector.controlplane.asset.spi.domain.Asset;", - "data": [ - { - "id": "asset-1", - "properties": { - "https://w3id.org/edc/v0.0.1/ns/contenttype": "application/json", - "https://w3id.org/edc/v0.0.1/ns/prop1": "value1" - } - } - ] - } -} \ No newline at end of file diff --git a/samples/testing-with-mocked-connector/src/test/resources/contractdef.creation.json b/samples/testing-with-mocked-connector/src/test/resources/contractdef.creation.json deleted file mode 100644 index 855ca8b1a5..0000000000 --- a/samples/testing-with-mocked-connector/src/test/resources/contractdef.creation.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "Asset Creation V3", - "input": { - "class": "org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition", - "data": { - "id": "asset-1", - "accessPolicyId": "test-policy1", - "contractPolicyId": "test-policy2", - "assetsSelector": [ - { - "operandLeft": "id", - "operator": "=", - "operandRight": "some-asset-id" - } - ] - } - }, - "output": { - "class": "org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition", - "data": { - "id": "asset-1", - "accessPolicyId": "test-policy1", - "contractPolicyId": "test-policy2", - "assetsSelector": [ - { - "operandLeft": "id", - "operator": "=", - "operandRight": "some-asset-id" - } - ] - } - } -} \ No newline at end of file diff --git a/samples/testing-with-mocked-connector/src/test/resources/transferprocess.request.json b/samples/testing-with-mocked-connector/src/test/resources/transferprocess.request.json deleted file mode 100644 index 898eea501d..0000000000 --- a/samples/testing-with-mocked-connector/src/test/resources/transferprocess.request.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "TransferProcess Query v3", - "input": { - "class": "org.eclipse.edc.spi.query.QuerySpec", - "data": { - "offset": 0, - "sortOrder": "DESC" - } - }, - "output": { - "class": "[Lorg.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcess;", - "data": [ - { - "id": "transferprocess-1", - "type": "CONSUMER", - "assetId": "some-asset-id", - "contractId": "some-contract-id" - } - ] - } -} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 491f119c82..e105e220d8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -149,7 +149,6 @@ include(":edc-tests:runtime:dcp:dcp-extensions") include(":edc-tests:runtime:dcp:runtime-memory-dcp-div-ih") include(":edc-tests:runtime:dcp:runtime-memory-dcp-ih") include(":edc-tests:runtime:dcp:runtime-memory-sts") -include(":edc-tests:runtime:mock-connector") include(":edc-tests:runtime:runtime-postgresql") include(":edc-tests:runtime:runtime-dcp-tck") include("edc-tests:runtime:runtime-discovery:runtime-discovery-base") @@ -159,8 +158,6 @@ include("edc-tests:runtime:runtime-compatibility:stable:extensions") include("edc-tests:runtime:runtime-compatibility:stable:connector-stable") include("edc-tests:runtime:runtime-compatibility:snapshot:connector-snapshot") - - // modules for controlplane artifacts include(":edc-controlplane") include(":edc-controlplane:edc-controlplane-base") @@ -172,5 +169,3 @@ include(":edc-dataplane") include(":edc-dataplane:edc-dataplane-base") include(":edc-dataplane:edc-dataplane-hashicorp-vault") -include(":samples:testing-with-mocked-connector") - From 27a800657703e4662954c02bc1ac5927210d7083 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 08:41:04 +0200 Subject: [PATCH 128/259] chore(deps): bump com.networknt:json-schema-validator (#2871) Bumps [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) from 3.0.2 to 3.0.3. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/3.0.2...3.0.3) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-version: 3.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts index eabd9e0265..962f2d397d 100644 --- a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts @@ -43,7 +43,7 @@ dependencies { } constraints { - implementation("com.networknt:json-schema-validator:3.0.2") { + implementation("com.networknt:json-schema-validator:3.0.3") { because("older versions cause runtime issues") } } From 40f09410b4c3e3de5cf610153650b087589b65b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 08:41:27 +0200 Subject: [PATCH 129/259] chore(deps): bump docker/setup-qemu-action (#2870) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/ce360397dd3f832beb865e1373c09c0e9f86d70a...06116385d9baf250c9f4dcb4858b16962ea869c3) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 9e26d6c4e1..7ae4d286cf 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -54,7 +54,7 @@ runs: # Enable emulation for cross-arch builds ############################################### - name: Set up QEMU - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0 + uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0 ############################################### # Use Docker Buildx (required for multi-arch) From 95ffdd94eeb35ad5414d5e7203f4f627888f51ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 08:41:45 +0200 Subject: [PATCH 130/259] chore(deps): bump com.gradleup.shadow from 9.4.1 to 9.4.2 (#2869) Bumps [com.gradleup.shadow](https://github.com/GradleUp/shadow) from 9.4.1 to 9.4.2. - [Release notes](https://github.com/GradleUp/shadow/releases) - [Commits](https://github.com/GradleUp/shadow/compare/9.4.1...9.4.2) --- updated-dependencies: - dependency-name: com.gradleup.shadow dependency-version: 9.4.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index df6abd64b2..8922772ea1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -249,6 +249,6 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } -shadow = { id = "com.gradleup.shadow", version = "9.4.1" } +shadow = { id = "com.gradleup.shadow", version = "9.4.2" } swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.50" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From d0d1860004e8d555318bf63c09c394429a46eb8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 08:42:09 +0200 Subject: [PATCH 131/259] chore(deps): bump simple-elf/allure-report-action (#2868) Bumps [simple-elf/allure-report-action](https://github.com/simple-elf/allure-report-action) from 1.13 to 1.14. - [Release notes](https://github.com/simple-elf/allure-report-action/releases) - [Commits](https://github.com/simple-elf/allure-report-action/compare/53ebb757a2097edc77c53ecef4d454fc2f2f774c...e463a472d3b1d750f9544369d60589ff1964c820) --- updated-dependencies: - dependency-name: simple-elf/allure-report-action dependency-version: '1.14' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/generate-and-publish-allure-report/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/generate-and-publish-allure-report/action.yml b/.github/actions/generate-and-publish-allure-report/action.yml index eb8e2d99e0..d5709660e5 100644 --- a/.github/actions/generate-and-publish-allure-report/action.yml +++ b/.github/actions/generate-and-publish-allure-report/action.yml @@ -42,7 +42,7 @@ runs: path: allure-results - name: Build Allure test report - uses: simple-elf/allure-report-action@53ebb757a2097edc77c53ecef4d454fc2f2f774c # v1.13 + uses: simple-elf/allure-report-action@e463a472d3b1d750f9544369d60589ff1964c820 # v1.14 with: gh_pages: gh-pages allure_results: allure-results From 6228cc7c32d4ab1e4c52b83173ae420af46b7e8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 08:42:33 +0200 Subject: [PATCH 132/259] chore(deps): bump aws from 2.44.11 to 2.45.0 (#2867) Bumps `aws` from 2.44.11 to 2.45.0. Updates `software.amazon.awssdk:s3` from 2.44.11 to 2.45.0 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.44.11 to 2.45.0 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.45.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.45.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8922772ea1..38200f053a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.34.0" awaitility = "4.3.0" -aws = "2.44.11" +aws = "2.45.0" azure-storage-blob = "12.33.4" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" From b223d940b8785b6dcd0556b93ca5e650dbb2728c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 09:01:21 +0200 Subject: [PATCH 133/259] chore(deps): bump io.qameta.allure:allure-junit5 from 2.34.0 to 2.35.1 (#2872) Bumps [io.qameta.allure:allure-junit5](https://github.com/allure-framework/allure-java) from 2.34.0 to 2.35.1. - [Release notes](https://github.com/allure-framework/allure-java/releases) - [Commits](https://github.com/allure-framework/allure-java/compare/2.34.0...2.35.1) --- updated-dependencies: - dependency-name: io.qameta.allure:allure-junit5 dependency-version: 2.35.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 38200f053a..bf1907656c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ format.version = "1.1" edc = "0.16.0" edc-next = "0.16.0" edc-build = "1.5.2" -allure = "2.34.0" +allure = "2.35.1" awaitility = "4.3.0" aws = "2.45.0" azure-storage-blob = "12.33.4" From cd2f01d63e3c4bf81832e12f6012f8b30b77daf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 09:10:47 +0200 Subject: [PATCH 134/259] chore(deps): bump com.azure:azure-storage-blob from 12.33.4 to 12.34.0 (#2846) Bumps [com.azure:azure-storage-blob](https://github.com/Azure/azure-sdk-for-java) from 12.33.4 to 12.34.0. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/com.azure+azure-storage-blob_12.33.4...com.azure+azure-storage-blob_12.34.0) --- updated-dependencies: - dependency-name: com.azure:azure-storage-blob dependency-version: 12.34.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bf1907656c..90b7e80f3d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ edc-build = "1.5.2" allure = "2.35.1" awaitility = "4.3.0" aws = "2.45.0" -azure-storage-blob = "12.33.4" +azure-storage-blob = "12.34.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" From 6db290cfd96def1db3cb9dfcc190db5020907bf5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:08:51 +0200 Subject: [PATCH 135/259] chore(deps): bump aws from 2.45.0 to 2.46.4 (#2877) Bumps `aws` from 2.45.0 to 2.46.4. Updates `software.amazon.awssdk:s3` from 2.45.0 to 2.46.4 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.45.0 to 2.46.4 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.46.4 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.46.4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 90b7e80f3d..621defdadb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-next = "0.16.0" edc-build = "1.5.2" allure = "2.35.1" awaitility = "4.3.0" -aws = "2.45.0" +aws = "2.46.4" azure-storage-blob = "12.34.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" From d5ecbdadffe708ee518752928ae0285a06188e9e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:09:09 +0200 Subject: [PATCH 136/259] chore(deps): bump flyway from 12.6.2 to 12.8.0 (#2885) Bumps `flyway` from 12.6.2 to 12.8.0. Updates `org.flywaydb:flyway-core` from 12.6.2 to 12.8.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.6.2 to 12.8.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.8.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.8.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 621defdadb..35e7121a70 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ azure-storage-blob = "12.34.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" -flyway = "12.6.2" +flyway = "12.8.0" jackson = "2.21.3" jakarta-json = "2.1.3" junit = "6.1.0" From 25c797a8762a8e85667524984eb928988337a0ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:09:26 +0200 Subject: [PATCH 137/259] chore(deps): bump com.nimbusds:nimbus-jose-jwt from 10.9 to 10.9.1 (#2884) Bumps [com.nimbusds:nimbus-jose-jwt](https://bitbucket.org/connect2id/nimbus-jose-jwt) from 10.9 to 10.9.1. - [Changelog](https://bitbucket.org/connect2id/nimbus-jose-jwt/src/master/CHANGELOG.txt) - [Commits](https://bitbucket.org/connect2id/nimbus-jose-jwt/branches/compare/10.9.1..10.9) --- updated-dependencies: - dependency-name: com.nimbusds:nimbus-jose-jwt dependency-version: 10.9.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 35e7121a70..9d5393fc36 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ flyway = "12.8.0" jackson = "2.21.3" jakarta-json = "2.1.3" junit = "6.1.0" -nimbus = "10.9" +nimbus = "10.9.1" okhttp = "5.3.2" opentelemetry = "2.28.1" opentelemetry-instrumentation = "2.28.1" From 37aff52141151aae753ff4b9404e1e67f9b5e187 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:09:44 +0200 Subject: [PATCH 138/259] chore(deps): bump io.qameta.allure:allure-junit5 from 2.35.1 to 2.35.2 (#2883) Bumps [io.qameta.allure:allure-junit5](https://github.com/allure-framework/allure-java) from 2.35.1 to 2.35.2. - [Release notes](https://github.com/allure-framework/allure-java/releases) - [Commits](https://github.com/allure-framework/allure-java/compare/2.35.1...2.35.2) --- updated-dependencies: - dependency-name: io.qameta.allure:allure-junit5 dependency-version: 2.35.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9d5393fc36..70fcff567a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ format.version = "1.1" edc = "0.16.0" edc-next = "0.16.0" edc-build = "1.5.2" -allure = "2.35.1" +allure = "2.35.2" awaitility = "4.3.0" aws = "2.46.4" azure-storage-blob = "12.34.0" From bd04def6b8f20b5167febd6f79a54e3d2af28a72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:10:06 +0200 Subject: [PATCH 139/259] chore(deps): bump actions/checkout (#2881) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...df4cb1c069e1874edd31b4311f1884172cec0e10) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 7ae4d286cf..cddf0d8794 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -46,7 +46,7 @@ inputs: runs: using: "composite" steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false From 51d1b6ae3ec482471f14918b2925c1b6c802e830 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:10:23 +0200 Subject: [PATCH 140/259] chore(deps): bump trufflesecurity/trufflehog from 3.95.3 to 3.95.5 (#2879) Bumps [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) from 3.95.3 to 3.95.5. - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/37b77001d0174ebec2fcca2bd83ff83a6d45a3ab...d411fff7b8879a62509f3fa98c07f247ac089a51) --- updated-dependencies: - dependency-name: trufflesecurity/trufflehog dependency-version: 3.95.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/secrets-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index a892b5adf0..906f11ae88 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -53,7 +53,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@37b77001d0174ebec2fcca2bd83ff83a6d45a3ab + uses: trufflesecurity/trufflehog@d411fff7b8879a62509f3fa98c07f247ac089a51 continue-on-error: true with: path: ./ # Scan the entire repository From fb2a07aa32f165aa585a9701bc824c64f40ab667 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:10:42 +0200 Subject: [PATCH 141/259] chore(deps): bump github/codeql-action from 4.36.0 to 4.36.2 (#2878) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.36.0 to 4.36.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7211b7c8077ea37d8641b6271f6a365a22a5fbfa...8aad20d150bbac5944a9f9d289da16a4b0d87c1e) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.36.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 4 ++-- .github/workflows/kics.yml | 2 +- .github/workflows/workflow-security-lint.yaml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index fa2b175149..6006c73260 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 158dfba228..bf737b823e 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 1ddecbe359..a2cd821d42 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 if: always() with: sarif_file: results-fixed.sarif From 7ec5add078031f6dd155dd47fef9d4b656157e5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:11:04 +0200 Subject: [PATCH 142/259] chore(deps): bump actions/checkout (#2882) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...df4cb1c069e1874edd31b4311f1884172cec0e10) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/run-deployment-test/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/run-deployment-test/action.yml b/.github/actions/run-deployment-test/action.yml index 655dde9377..e0b4636405 100644 --- a/.github/actions/run-deployment-test/action.yml +++ b/.github/actions/run-deployment-test/action.yml @@ -49,7 +49,7 @@ inputs: runs: using: "composite" steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/setup-java From 18960f3668d1c1f21e597f4452553f5382c2c743 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:20:45 +0200 Subject: [PATCH 143/259] chore(deps): bump com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp (#2886) Bumps [com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp](https://github.com/FasterXML/jackson-datatypes-misc) from 2.21.3 to 2.22.0. - [Commits](https://github.com/FasterXML/jackson-datatypes-misc/compare/jackson-datatypes-misc-parent-2.21.3...jackson-datatypes-misc-parent-2.22.0) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp dependency-version: 2.22.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 70fcff567a..e6c83a300e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" flyway = "12.8.0" -jackson = "2.21.3" +jackson = "2.22.0" jakarta-json = "2.1.3" junit = "6.1.0" nimbus = "10.9.1" From 718312c65b5affad97724ed18184e161d56d3f72 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jun 2026 09:28:05 +0200 Subject: [PATCH 144/259] chore(deps): bump actions/checkout from 6.0.2 to 6.0.3 (#2880) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...df4cb1c069e1874edd31b4311f1884172cec0e10) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 2 +- .github/workflows/deployment-test.yaml | 4 ++-- .github/workflows/draft-release.yaml | 4 ++-- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 2 +- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 4 ++-- .github/workflows/publish-openapi-ui.yml | 4 ++-- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 2 +- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 4 ++-- 16 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 6006c73260..64e9bf7ec2 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -59,7 +59,7 @@ jobs: with: egress-policy: audit - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 605f678929..97b7edb750 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -53,7 +53,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/run-deployment-test @@ -88,7 +88,7 @@ jobs: with: egress-policy: audit - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/run-deployment-test diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 6356560801..f5852db39d 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -47,7 +47,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 persist-credentials: false @@ -120,7 +120,7 @@ jobs: packages: write pages: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # zizmor: ignore[artipacked] + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.2 # zizmor: ignore[artipacked] with: persist-credentials: true - name: Create Release branch diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index 2d89d634f4..b16343142c 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -38,7 +38,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: true - uses: ./.github/actions/setup-java diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 217fd68251..647122388d 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -52,7 +52,7 @@ jobs: ############## ### Set-Up ### ############## - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index bf737b823e..37c2781472 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -48,7 +48,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index 165b3ab259..0ce1a3efe0 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -41,7 +41,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: copy contexts into public folder diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index 6b595298d4..f5f4c07acd 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -98,7 +98,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: "Get version" @@ -168,7 +168,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/publish-latest-versioned-snapshot diff --git a/.github/workflows/publish-openapi-ui.yml b/.github/workflows/publish-openapi-ui.yml index 378912aeac..137aebe16e 100644 --- a/.github/workflows/publish-openapi-ui.yml +++ b/.github/workflows/publish-openapi-ui.yml @@ -53,7 +53,7 @@ jobs: generate-openapi-spec: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -75,7 +75,7 @@ jobs: { name: "data-plane", folder: "edc-dataplane/edc-dataplane-base" } ] steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/setup-java diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3f0453ee9d..a8b927f1c3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,7 +63,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 persist-credentials: false @@ -155,7 +155,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 persist-credentials: true @@ -195,7 +195,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: true - name: Prepare Git Config @@ -259,7 +259,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false @@ -302,7 +302,7 @@ jobs: with: egress-policy: audit - name: Checkout main - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 ref: main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 906f11ae88..dca9109df8 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -46,7 +46,7 @@ jobs: with: egress-policy: audit - name: Checkout Repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 # Ensure full clone for pull request workflows persist-credentials: false diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index 166907cc40..db94d2d9f6 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -73,7 +73,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: Log inputs diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 891a35bf3a..f1f1b0136f 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -62,7 +62,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/setup-java diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 60d00164cf..b43ac1cb05 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -54,7 +54,7 @@ jobs: with: egress-policy: audit - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index d14ceb3e55..b60fddbd8d 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -39,7 +39,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - run: | @@ -62,7 +62,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false @@ -80,7 +80,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -97,7 +97,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false @@ -155,7 +155,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false @@ -174,7 +174,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false @@ -194,7 +194,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: get api groups and create matrix for next job @@ -216,7 +216,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -250,7 +250,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -267,7 +267,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -290,7 +290,7 @@ jobs: with: egress-policy: audit - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index a2cd821d42..bc51f80e51 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -51,7 +51,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false @@ -76,7 +76,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false From 48419541952ab0d58a517ea7db4a5c20cc31b4ed Mon Sep 17 00:00:00 2001 From: Tom Meyer Date: Mon, 15 Jun 2026 09:10:04 +0200 Subject: [PATCH 145/259] feat(tractusx-connector): add postgres custom user and secrets (#2845) * feat(chart): add customUser directives and use secrets * feat(tractusx-connector chart): differentiate customUser and adminUser for postgres with secrets * chore(migration docs): added note where to find information for the database configuration * chore(chart): update license headers * fix(deployment-dataplane): added carelessly removed postgresql section * chore(tractusx connector chart): added CHANGEME for mandatory fields --- charts/tractusx-connector/README.md | 85 +++++++++++++++++-- charts/tractusx-connector/README.md.gotmpl | 59 +++++++++++++ .../tractusx-connector/templates/_helpers.tpl | 36 ++++++++ .../templates/deployment-controlplane.yaml | 59 ++++++++++++- .../templates/deployment-dataplane.yaml | 59 ++++++++++++- charts/tractusx-connector/values.yaml | 52 ++++++++++-- .../2026_06-Version_0.12.x_0.13.x.md | 11 ++- 7 files changed, 337 insertions(+), 24 deletions(-) diff --git a/charts/tractusx-connector/README.md b/charts/tractusx-connector/README.md index 39122368c1..7965a38775 100644 --- a/charts/tractusx-connector/README.md +++ b/charts/tractusx-connector/README.md @@ -36,6 +36,64 @@ In addition, in order to map BPNs to DIDs, a new service is required, called the must be configured: - `controlplane.bdrs.server.url`: base URL of the BPN-DID Resolution Service ("BDRS") +#### Database configuration + +When bringing your own database, respectively not installing postgres (`install.postgresql: false`), use the following information: + +```yaml +postgresql: + jdbcUrl: "jdbc:postgresql://{{ .Release.Name }}-postgresql:5432/edc" + auth: + username: "postgres" + password: "password" +``` + +When installing postgres with the chart, it is **RECOMMENDED** to use a custom user beside the admin user: + +> [!note] +> The value `postgresql.jdbUrl` is composed in the deployments using a dependent variable of the database name and the name of the postgress deployment. + +```yaml +postgresql: + auth: + database: "postgres" + username: "postgres" + password: "password" # generated if empty + customUser: # name or exisitng secret must be set + name: "edc" + database: "edc" # must ge different than postgresql.auth.database + password: "password" # generated if empty +``` + +When installing postgres with the chart, you can alteratively not create and use a custom user (**NOT RECOMMENDED**). + +```yaml +postgresql: + auth: + database: "postgres" + username: "postgres" + password: "password" # generated if empty + customUser: + existingSecret: "" # explicitly set to empty + name: "" # explicitly set to empty +``` + +Further you can also reuse existing secrets instead: + +```yaml +postgresql: + auth: + existingSecret: "my-existing-secret-name" + secretKeys: + adminPasswordKey: "postgres-password" + customUser: + existingSecret: "my-existing-secret-name" + secretKeys: + password: "CUSTOM_PASSWORD" + name: "CUSTOM_USER" + database: "CUSTOM_DB" +``` + ### Launching the application As an easy starting point, please consider using [this example configuration](https://github.com/eclipse-tractusx/tractusx-edc/blob/main/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml) @@ -70,7 +128,7 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | controlplane.autoscaling.targetCPUUtilizationPercentage | int | `80` | targetAverageUtilization of cpu provided to a pod | | controlplane.autoscaling.targetMemoryUtilizationPercentage | int | `80` | targetAverageUtilization of memory provided to a pod | | controlplane.bdrs.cache_validity_seconds | int | `600` | Time that a cached BPN/DID resolution map is valid in seconds, default is 600 seconds (10 min) | -| controlplane.bdrs.server.url | string | `nil` | URL of the BPN/DID Resolution Service | +| controlplane.bdrs.server.url | string | `"CHANGEME"` | URL of the BPN/DID Resolution Service | | controlplane.debug.enabled | bool | `false` | Enables java debugging mode. | | controlplane.debug.port | int | `1044` | Port where the debuggee can connect to. | | controlplane.debug.suspendOnStart | bool | `false` | Defines if the JVM should wait with starting the application until someone connected to the debugging port. | @@ -251,8 +309,8 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | dataplane.token.refresh.expiry_seconds | int | `300` | TTL in seconds for access tokens (also known as EDR token) | | dataplane.token.refresh.expiry_tolerance_seconds | int | `10` | Tolerance for token expiry in seconds | | dataplane.token.refresh.refresh_endpoint | string | `nil` | Optional endpoint for an OAuth2 token refresh. Default endpoint is `/token` | -| dataplane.token.signer.privatekey_alias | string | `nil` | Alias under which the private key (JWK or PEM format) is stored in the vault | -| dataplane.token.verifier.publickey_alias | string | `nil` | Alias under which the public key (JWK or PEM format) is stored in the vault, that belongs to the private key which was referred to at `dataplane.token.signer.privatekey_alias` | +| dataplane.token.signer.privatekey_alias | string | `"CHANGEME"` | Alias under which the private key (JWK or PEM format) is stored in the vault | +| dataplane.token.verifier.publickey_alias | string | `"CHANGEME"` | Alias under which the public key (JWK or PEM format) is stored in the vault, that belongs to the private key which was referred to at `dataplane.token.signer.privatekey_alias` | | dataplane.tolerations | list | `[]` | [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to configure preferred nodes | | dataplane.url.public | string | `""` | Explicitly declared url for reaching the public api (e.g. if ingresses not used) | | dataplane.volumeMounts | string | `nil` | declare where to mount [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) into the container | @@ -261,9 +319,9 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | dcp.cache.validity | int | `86400` | Validity of the Verifiable Presentation cache in seconds | | dcp.didService.selfRegistration.enabled | bool | `false` | Whether Service Self Registration is enabled | | dcp.sts.div.url | string | `nil` | URL where connectors can request SI tokens | -| dcp.sts.oauth.client.id | string | `nil` | Client ID for requesting OAuth2 access token for DIV access | -| dcp.sts.oauth.client.secret_alias | string | `nil` | Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access | -| dcp.sts.oauth.token_url | string | `nil` | URL where connectors can request OAuth2 access tokens for DIV access | +| dcp.sts.oauth.client.id | string | `"CHANGEME"` | Client ID for requesting OAuth2 access token for DIV access | +| dcp.sts.oauth.client.secret_alias | string | `"CHANGEME"` | Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access | +| dcp.sts.oauth.token_url | string | `"CHANGEME"` | URL where connectors can request OAuth2 access tokens for DIV access | | dcp.trustedIssuers | list | `[]` | Configures the trusted issuers for this runtime. If no supportedTypes are specified, the value defaults to "*" for that issuer | | fullnameOverride | string | `""` | | | imagePullSecrets | list | `[]` | Existing image pull secret to use to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) | @@ -280,9 +338,18 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHO | participant.bpnl | string | `"BPNLCHANGEME"` | BPNL Number | | participant.contextId | string | `"UUID CHANGEME"` | Participant Context Id - Newly introduced id for a connector instance (needed for multitenancy) | | participant.id | string | `"did:web:changeme"` | Participant Id, resp. the Decentralized IDentifier (DID) of the connector | -| postgresql.auth.database | string | `"edc"` | | -| postgresql.auth.password | string | `"password"` | | -| postgresql.auth.username | string | `"user"` | | +| postgresql.auth.database | string | postgres | Database of the root user. If an exisisting secret is used, this value is overwritten into the existing secret. | +| postgresql.auth.existingSecret | string | {{ .Release.Name }}-postgresql | Name of the existing secret containing the superuser credentials. | +| postgresql.auth.password | string | Autogenerated random alpha=numeric string with 16 characters (if empty). | Password of the root user. If an existing secret is used, this value is overwritten into the existing secret. | +| postgresql.auth.secretKeys.adminPasswordKey | string | postgres-password | Key of the admin password to use of the existing secret. | +| postgresql.auth.username | string | postgres | Username of the root user. If an existing secret is used, this value is overwritten into the existing secret. | +| postgresql.customUser.database | string | edc | Name for the custom database to be created and assigned to the custom user. If an existing secret is used, this value is overwritten into the existing secret. | +| postgresql.customUser.existingSecret | string | {{ .Release.Name }}-postgresql-custom-user-credentials | Name of the existing secret containing the custom user credentials. | +| postgresql.customUser.name | string | edc | Name of the custom user to be created. If an existing secret is used, this value is overwritten into the existing secret. | +| postgresql.customUser.password | string | Autogenerated random alpha=numeric string with 16 characters (if empty). | Password to be used for the custom user. If an existing secret is used, this value is overwritten into the existing secret. | +| postgresql.customUser.secretKeys.database | string | CUSTOM_DB | Key of the custom user database to use of the existing secret. | +| postgresql.customUser.secretKeys.name | string | CUSTOM_USER | Key of the custom user name to use of the existing secret. | +| postgresql.customUser.secretKeys.password | string | CUSTOM_PASSWORD | Key of the custom user password to use of the existing secret. | | postgresql.image.registry | string | `"docker.io"` | | | postgresql.image.repository | string | `"postgres"` | | | postgresql.jdbcUrl | string | `"jdbc:postgresql://{{ .Release.Name }}-postgresql:5432/edc"` | | diff --git a/charts/tractusx-connector/README.md.gotmpl b/charts/tractusx-connector/README.md.gotmpl index bdb59b24be..eef7c90579 100644 --- a/charts/tractusx-connector/README.md.gotmpl +++ b/charts/tractusx-connector/README.md.gotmpl @@ -36,6 +36,65 @@ In addition, in order to map BPNs to DIDs, a new service is required, called the must be configured: - `controlplane.bdrs.server.url`: base URL of the BPN-DID Resolution Service ("BDRS") +#### Database configuration + +When bringing your own database, respectively not installing postgres (`install.postgresql: false`), use the following information: + +```yaml +postgresql: + jdbcUrl: "jdbc:postgresql://{{ "{{" }} .Release.Name }}-postgresql:5432/edc" + auth: + username: "postgres" + password: "password" +``` + +When installing postgres with the chart, it is **RECOMMENDED** to use a custom user beside the admin user: + +> [!note] +> The value `postgresql.jdbUrl` is composed in the deployments using a dependent variable of the database name and the name of the postgress deployment. + +```yaml +postgresql: + auth: + database: "postgres" + username: "postgres" + password: "password" # generated if empty + customUser: # name or exisitng secret must be set + name: "edc" + database: "edc" # must ge different than postgresql.auth.database + password: "password" # generated if empty +``` + +When installing postgres with the chart, you can alteratively not create and use a custom user (**NOT RECOMMENDED**). + +```yaml +postgresql: + auth: + database: "postgres" + username: "postgres" + password: "password" # generated if empty + customUser: + existingSecret: "" # explicitly set to empty + name: "" # explicitly set to empty +``` + +Further you can also reuse existing secrets instead: + +```yaml +postgresql: + auth: + existingSecret: "my-existing-secret-name" + secretKeys: + adminPasswordKey: "postgres-password" + customUser: + existingSecret: "my-existing-secret-name" + secretKeys: + password: "CUSTOM_PASSWORD" + name: "CUSTOM_USER" + database: "CUSTOM_DB" +``` + + ### Launching the application As an easy starting point, please consider using [this example configuration](https://github.com/eclipse-tractusx/tractusx-edc/blob/main/edc-tests/deployment/src/main/resources/helm/tractusx-connector-test.yaml) diff --git a/charts/tractusx-connector/templates/_helpers.tpl b/charts/tractusx-connector/templates/_helpers.tpl index a115b22154..b63e5cb708 100644 --- a/charts/tractusx-connector/templates/_helpers.tpl +++ b/charts/tractusx-connector/templates/_helpers.tpl @@ -1,3 +1,22 @@ +{{- /* +* Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) +* Copyright (c) 2023 Contributors to the Eclipse Foundation +* +* See the NOTICE file(s) distributed with this work for additional +* information regarding copyright ownership. +* +* 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. +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations +* under the License. +* +* SPDX-License-Identifier: Apache-2.0 +*/}} {{/* Expand the name of the chart. */}} @@ -180,3 +199,20 @@ Create the name of the service account to use {{- default "default" .Values.serviceAccount.name }} {{- end }} {{- end }} + +{{/* +Create a default fully qualified app name for PostgreSQL. +*/}} +{{- define "txdc.postgresql.fullname" -}} +{{- if .Values.postgresql.fullnameOverride }} +{{- .Values.postgresql.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else if .Values.postgresql.nameOverride }} +{{- printf "%s-%s" .Release.Name .Values.postgresql.nameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-postgresql" .Release.Name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{- define "txdc.postgresql.custom-user-secret" -}} +{{- printf "%s-custom-user-credentials" (include "txdc.postgresql.fullname" .) -}} +{{- end }} \ No newline at end of file diff --git a/charts/tractusx-connector/templates/deployment-controlplane.yaml b/charts/tractusx-connector/templates/deployment-controlplane.yaml index 6b8cb6b5e8..05c7dcb9fd 100644 --- a/charts/tractusx-connector/templates/deployment-controlplane.yaml +++ b/charts/tractusx-connector/templates/deployment-controlplane.yaml @@ -3,6 +3,7 @@ # Copyright (c) 2023 Mercedes-Benz Tech Innovation GmbH # Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + # Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -212,14 +213,68 @@ spec: ################ ## POSTGRESQL ## ################ - - # default datasource + {{ if not .Values.install.postgresql }} + # default datasource, no postgresql secret available - name: "EDC_DATASOURCE_DEFAULT_USER" value: {{ .Values.postgresql.auth.username | required ".Values.postgresql.auth.username is required" | quote }} - name: "EDC_DATASOURCE_DEFAULT_PASSWORD" value: {{ .Values.postgresql.auth.password | required ".Values.postgresql.auth.password is required" | quote }} - name: "EDC_DATASOURCE_DEFAULT_URL" value: {{ tpl .Values.postgresql.jdbcUrl . | quote }} + {{- else }} + {{- $hasCustomUser := or .Values.postgresql.customUser.name .Values.postgresql.customUser.existingSecret -}} + {{- if $hasCustomUser }} + # custom user section activated (customUser.name or customUser.existingSecret exist) + {{- $customUserSecretName := .Values.postgresql.customUser.existingSecret | default (include "txdc.postgresql.custom-user-secret" .) -}} + {{- $pwKey := .Values.postgresql.customUser | dig "secretKeys" "password" "CUSTOM_PASSWORD" -}} + {{- $nameKey := .Values.postgresql.customUser | dig "secretKeys" "name" "CUSTOM_USER" -}} + {{- $dbKey := .Values.postgresql.customUser | dig "secretKeys" "database" "CUSTOM_DB" }} + - name: "EDC_DATASOURCE_DEFAULT_USER" + valueFrom: + secretKeyRef: + name: {{ $customUserSecretName | quote }} + key: {{ $nameKey | quote }} + - name: "EDC_DATASOURCE_DEFAULT_PASSWORD" + valueFrom: + secretKeyRef: + name: {{ $customUserSecretName | quote }} + key: {{ $pwKey | quote }} + # dependent variable to automatically construct the datasource url + - name: EDC_DATASOURCE_DEFAULT_DB + valueFrom: + secretKeyRef: + name: {{ $customUserSecretName | quote }} + key: {{ $dbKey | quote }} + - name: EDC_DATASOURCE_DEFAULT_URL + value: "jdbc:postgresql://{{ include "txdc.postgresql.fullname" . }}:{{ .Values.postgresql.service.port }}/$(EDC_DATASOURCE_DEFAULT_DB)" + {{- else }} + {{ $adminUserSecretName := .Values.postgresql.auth.existingSecret | default (include "txdc.postgresql.fullname" .) -}} + {{- $pwKey := .Values.postgresql.auth | dig "secretKeys" "adminPasswordKey" "postgres-password" }} + # admin user section activated (customUser.name or customUser.existingSecret don't exist) + # for auth commonly only deviating key for postgresPassword may be defined via secretKeys.adminPasswordKey + # for name and db, we assume the same keys and defaults from cloudpirates admin secret + {{- $nameKey := .Values.postgresql.auth | dig "secretKeys" "name" "username" -}} + {{- $dbKey := .Values.postgresql.auth | dig "secretKeys" "database" "database" }} + - name: "EDC_DATASOURCE_DEFAULT_USER" + valueFrom: + secretKeyRef: + name: {{ $adminUserSecretName | quote }} + key: {{ $nameKey | quote }} + - name: "EDC_DATASOURCE_DEFAULT_PASSWORD" + valueFrom: + secretKeyRef: + name: {{ $adminUserSecretName | quote }} + key: {{ $pwKey | quote }} + # dependent variable to automatically construct the datasource url + - name: EDC_DATASOURCE_DEFAULT_DB + valueFrom: + secretKeyRef: + name: {{ $adminUserSecretName | quote }} + key: {{ $dbKey | quote }} + - name: EDC_DATASOURCE_DEFAULT_URL + value: "jdbc:postgresql://{{ include "txdc.postgresql.fullname" . }}:{{ .Values.postgresql.service.port }}/$(EDC_DATASOURCE_DEFAULT_DB)" + {{- end }} + {{- end }} ############################# diff --git a/charts/tractusx-connector/templates/deployment-dataplane.yaml b/charts/tractusx-connector/templates/deployment-dataplane.yaml index c396b3ef4c..27c13c674b 100644 --- a/charts/tractusx-connector/templates/deployment-dataplane.yaml +++ b/charts/tractusx-connector/templates/deployment-dataplane.yaml @@ -3,6 +3,7 @@ # Copyright (c) 2023 Mercedes-Benz Tech Innovation GmbH # Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + # Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -238,14 +239,68 @@ spec: ################ ## POSTGRESQL ## ################ - - # default datasource + {{ if not .Values.install.postgresql }} + # default datasource, no postgresql secret available - name: "EDC_DATASOURCE_DEFAULT_USER" value: {{ .Values.postgresql.auth.username | required ".Values.postgresql.auth.username is required" | quote }} - name: "EDC_DATASOURCE_DEFAULT_PASSWORD" value: {{ .Values.postgresql.auth.password | required ".Values.postgresql.auth.password is required" | quote }} - name: "EDC_DATASOURCE_DEFAULT_URL" value: {{ tpl .Values.postgresql.jdbcUrl . | quote }} + {{- else }} + {{- $hasCustomUser := or .Values.postgresql.customUser.name .Values.postgresql.customUser.existingSecret -}} + {{- if $hasCustomUser }} + # custom user section activated (customUser.name or customUser.existingSecret exist) + {{- $customUserSecretName := .Values.postgresql.customUser.existingSecret | default (include "txdc.postgresql.custom-user-secret" .) -}} + {{- $pwKey := .Values.postgresql.customUser | dig "secretKeys" "password" "CUSTOM_PASSWORD" -}} + {{- $nameKey := .Values.postgresql.customUser | dig "secretKeys" "name" "CUSTOM_USER" -}} + {{- $dbKey := .Values.postgresql.customUser | dig "secretKeys" "database" "CUSTOM_DB" }} + - name: "EDC_DATASOURCE_DEFAULT_USER" + valueFrom: + secretKeyRef: + name: {{ $customUserSecretName | quote }} + key: {{ $nameKey | quote }} + - name: "EDC_DATASOURCE_DEFAULT_PASSWORD" + valueFrom: + secretKeyRef: + name: {{ $customUserSecretName | quote }} + key: {{ $pwKey | quote }} + # dependent variable to automatically construct the datasource url + - name: EDC_DATASOURCE_DEFAULT_DB + valueFrom: + secretKeyRef: + name: {{ $customUserSecretName | quote }} + key: {{ $dbKey | quote }} + - name: EDC_DATASOURCE_DEFAULT_URL + value: "jdbc:postgresql://{{ include "txdc.postgresql.fullname" . }}:{{ .Values.postgresql.service.port }}/$(EDC_DATASOURCE_DEFAULT_DB)" + {{- else }} + {{ $adminUserSecretName := .Values.postgresql.auth.existingSecret | default (include "txdc.postgresql.fullname" .) -}} + {{- $pwKey := .Values.postgresql.auth | dig "secretKeys" "adminPasswordKey" "postgres-password" }} + # admin user section activated (customUser.name or customUser.existingSecret don't exist) + # for auth commonly only deviating key for postgresPassword may be defined via secretKeys.adminPasswordKey + # for name and db, we assume the same keys and defaults from cloudpirates admin secret + {{- $nameKey := .Values.postgresql.auth | dig "secretKeys" "name" "username" -}} + {{- $dbKey := .Values.postgresql.auth | dig "secretKeys" "database" "database" }} + - name: "EDC_DATASOURCE_DEFAULT_USER" + valueFrom: + secretKeyRef: + name: {{ $adminUserSecretName | quote }} + key: {{ $nameKey | quote }} + - name: "EDC_DATASOURCE_DEFAULT_PASSWORD" + valueFrom: + secretKeyRef: + name: {{ $adminUserSecretName | quote }} + key: {{ $pwKey | quote }} + # dependent variable to automatically construct the datasource url + - name: EDC_DATASOURCE_DEFAULT_DB + valueFrom: + secretKeyRef: + name: {{ $adminUserSecretName | quote }} + key: {{ $dbKey | quote }} + - name: EDC_DATASOURCE_DEFAULT_URL + value: "jdbc:postgresql://{{ include "txdc.postgresql.fullname" . }}:{{ .Values.postgresql.service.port }}/$(EDC_DATASOURCE_DEFAULT_DB)" + {{- end }} + {{- end }} ######################### ## DATA PLANE PUBLIC API diff --git a/charts/tractusx-connector/values.yaml b/charts/tractusx-connector/values.yaml index 469c1b878c..daddf4e04b 100644 --- a/charts/tractusx-connector/values.yaml +++ b/charts/tractusx-connector/values.yaml @@ -3,6 +3,7 @@ # Copyright (c) 2023 Mercedes-Benz Tech Innovation GmbH # Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # Copyright (c) 2021,2024 Contributors to the Eclipse Foundation +# Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -60,12 +61,12 @@ dcp: url: oauth: # -- URL where connectors can request OAuth2 access tokens for DIV access - token_url: + token_url: "CHANGEME" client: # -- Client ID for requesting OAuth2 access token for DIV access - id: + id: "CHANGEME" # -- Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access - secret_alias: + secret_alias: "CHANGEME" didService: selfRegistration: # -- Whether Service Self Registration is enabled @@ -209,7 +210,7 @@ controlplane: cache_validity_seconds: 600 server: # -- URL of the BPN/DID Resolution Service - url: + url: "CHANGEME" # -- configuration for policy engine policy: @@ -480,10 +481,10 @@ dataplane: refresh_endpoint: signer: # -- Alias under which the private key (JWK or PEM format) is stored in the vault - privatekey_alias: + privatekey_alias: "CHANGEME" verifier: # -- Alias under which the public key (JWK or PEM format) is stored in the vault, that belongs to the private key which was referred to at `dataplane.token.signer.privatekey_alias` - publickey_alias: + publickey_alias: "CHANGEME" aws: endpointOverride: "" @@ -637,10 +638,47 @@ postgresql: requests: cpu: 250m memory: 256Mi + # -- auth: + # -- Database of the root user. If an exisisting secret is used, this value is overwritten into the existing secret. + # @default -- postgres + database: "postgres" + # -- Username of the root user. If an existing secret is used, this value is overwritten into the existing secret. + # @default -- postgres + username: "postgres" + # -- Password of the root user. If an existing secret is used, this value is overwritten into the existing secret. + # @default -- Autogenerated random alpha=numeric string with 16 characters (if empty). + password: "password" + # -- Name of the existing secret containing the superuser credentials. + # @default -- {{ .Release.Name }}-postgresql + existingSecret: "" + secretKeys: + # -- Key of the admin password to use of the existing secret. + # @default -- postgres-password + adminPasswordKey: "postgres-password" + customUser: + # -- Name for the custom database to be created and assigned to the custom user. If an existing secret is used, this value is overwritten into the existing secret. + # @default -- edc database: "edc" - username: "user" + # -- Name of the custom user to be created. If an existing secret is used, this value is overwritten into the existing secret. + # @default -- edc + name: "edc" + # -- Password to be used for the custom user. If an existing secret is used, this value is overwritten into the existing secret. + # @default -- Autogenerated random alpha=numeric string with 16 characters (if empty). password: "password" + # -- Name of the existing secret containing the custom user credentials. + # @default -- {{ .Release.Name }}-postgresql-custom-user-credentials + existingSecret: "" + secretKeys: + # -- Key of the custom user database to use of the existing secret. + # @default -- CUSTOM_DB + database: "CUSTOM_DB" + # -- Key of the custom user name to use of the existing secret. + # @default -- CUSTOM_USER + name: "CUSTOM_USER" + # -- Key of the custom user password to use of the existing secret. + # @default -- CUSTOM_PASSWORD + password: "CUSTOM_PASSWORD" vault: injector: diff --git a/docs/migration/2026_06-Version_0.12.x_0.13.x.md b/docs/migration/2026_06-Version_0.12.x_0.13.x.md index a58f9fe1f3..f86793f6a5 100644 --- a/docs/migration/2026_06-Version_0.12.x_0.13.x.md +++ b/docs/migration/2026_06-Version_0.12.x_0.13.x.md @@ -7,10 +7,10 @@ to another. This document is not a comprehensive feature list. -* [Migration Guide `0.12.x -> 0.13.x`](#migration-guide-012x---013x) - * [1. Federate Catalog removal](#1-federate-catalog-removal) - * [2. Deprecated instances](#2-deprecated-instances) - * [3. Postgres Version](#3-postgres-version) +- [Migration Guide `0.12.x -> 0.13.x`](#migration-guide-012x---013x) + - [1. Federate Catalog removal](#1-federate-catalog-removal) + - [2. Deprecated instances](#2-deprecated-instances) + - [3. Postgres Version](#3-postgres-version) ## 1. Federate Catalog removal @@ -50,3 +50,6 @@ As a consequence, for a Kubernetes setup done with the provided helm charts, the upgrade with the provided helm charts, as the two images are not supporting that. Instead, during update, an operator has to follow the general [migration guide](https://github.com/eclipse-tractusx/tutorial-resources/blob/main/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md#:~:text=GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md-,GENERIC_POSTGRESQL_MIGRATION_GUIDE,-.md) + +Further, the chart now differentiates between admin and custom user. It is recommended to use a custom user. Please +follow the [database configuration section](../../charts/tractusx-connector/README.md#database-configuration) of the helm documentation of the tractusx-connector. From 794df902cc92fca7419628ab5cce5400f0e5fd51 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Fri, 22 May 2026 10:03:43 +0200 Subject: [PATCH 146/259] Update to upstream 0.17.0 version and do necessary adaptations Signed-off-by: Lars Geyer-Blaumeiser --- .../edc-controlplane-base/build.gradle.kts | 7 ++++ .../edc/vault/memory/VaultSeedExtension.java | 2 -- .../edc-dataplane-base/build.gradle.kts | 4 +-- .../token-refresh-core/build.gradle.kts | 1 - ...DataPlaneTokenRefreshServiceExtension.java | 2 +- ...eTokenRefreshServiceImplComponentTest.java | 2 +- .../http/api/DspCatalogApiV08Extension.java | 22 +++++++------ .../DspApiConfigurationV08Extension.java | 5 ++- .../api/edr/BaseEdrCacheApiController.java | 3 +- .../edr/BaseEdrCacheApiControllerTest.java | 2 +- .../edc/monitor/logger/Log4j2Monitor.java | 32 ++++++++++++++++--- .../logger/Log4j2MonitorExtension.java | 5 +-- .../edc/monitor/logger/LoggerMonitorTest.java | 2 +- .../V1_8_0__Add_DataAddressAlias.sql | 19 ++++++++++- .../connector/V1_9_0__Add_ClaimsColumn.sql | 19 +++++++++++ .../AbstractPostgresqlMigrationExtension.java | 28 +++++++++++++--- .../EmptyAssetSelectorValidatorTest.java | 6 ++-- .../tests/transfer/TransferEndToEndTest.java | 1 + .../tractusx/edc/tests/ParticipantEdrApi.java | 2 +- .../participant/TractusxParticipantBase.java | 6 ++++ .../tests/auth/DelegatedAuthEndToEndTest.java | 1 + .../EmptyAssetSelectorValidatorTest.java | 1 + .../policy/PolicyDefinitionEndToEndTest.java | 2 +- .../dcp/ih/TxScopeToCriterionTransformer.java | 5 +-- gradle/libs.versions.toml | 12 +++---- 25 files changed, 145 insertions(+), 46 deletions(-) create mode 100644 edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_9_0__Add_ClaimsColumn.sql diff --git a/edc-controlplane/edc-controlplane-base/build.gradle.kts b/edc-controlplane/edc-controlplane-base/build.gradle.kts index 86a1b7a6d2..8e1d6e10a3 100644 --- a/edc-controlplane/edc-controlplane-base/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-base/build.gradle.kts @@ -29,6 +29,13 @@ configurations.all { // decentralized-claims-sts-remote-client excluded because we have the tx-dcp-sts-div that takes care to define the correct client in case of DIV exclude("org.eclipse.edc", "decentralized-claims-sts-remote-client") + + // We decided to not provide the federated catalog feature with this runtime + exclude("org.eclipse.edc", "federated-catalog-api") + exclude("org.eclipse.edc", "federated-catalog-spi") + exclude("org.eclipse.edc", "federated-catalog-core") + exclude("org.eclipse.edc", "federated-catalog-core-2025") + exclude("org.eclipse.edc", "federated-catalog-cache-sql") } dependencies { diff --git a/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java b/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java index 8e9b7dcc08..179421d032 100644 --- a/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java +++ b/edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java @@ -21,7 +21,6 @@ import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; -import org.eclipse.edc.runtime.metamodel.annotation.BaseExtension; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provider; @@ -33,7 +32,6 @@ import java.util.stream.Stream; @Extension(value = "Vault seed extension: adds secrets to the vault", categories = { "vault", "security" }) -@BaseExtension public class VaultSeedExtension implements ServiceExtension { static final String VAULT_MEMORY_SECRETS_PROPERTY = "tx.edc.vault.secrets"; diff --git a/edc-dataplane/edc-dataplane-base/build.gradle.kts b/edc-dataplane/edc-dataplane-base/build.gradle.kts index 8c105884cc..f5618c01af 100644 --- a/edc-dataplane/edc-dataplane-base/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-base/build.gradle.kts @@ -53,8 +53,8 @@ dependencies { runtimeOnly(libs.edc.aws.validator.data.address.s3) runtimeOnly(libs.edc.core.did) // for the DID Public Key Resolver runtimeOnly(libs.edc.core.edrstore) - runtimeOnly(libs.edc.core.participant.context.config) - runtimeOnly(libs.edc.core.participant.context.single) + runtimeOnly(libs.edc.core.participant.context.core) + runtimeOnly(libs.edc.core.participant.context.classic) runtimeOnly(libs.edc.dpf.awss3) runtimeOnly(libs.edc.aws.provision.s3) runtimeOnly(libs.edc.dpf.azblob) diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/build.gradle.kts b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/build.gradle.kts index 814b5029b5..1c1bf72304 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/build.gradle.kts +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/build.gradle.kts @@ -29,7 +29,6 @@ dependencies { implementation(libs.edc.spi.dataplane.dataplane) implementation(libs.edc.spi.identity.did) implementation(libs.edc.spi.jwt) - implementation(libs.edc.spi.jwt.signer) implementation(libs.edc.spi.keys) implementation(libs.edc.spi.participant.context.single) implementation(libs.edc.spi.token) diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java index ee2b1de5bd..016e6d4307 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java @@ -22,7 +22,7 @@ import org.eclipse.edc.connector.dataplane.spi.iam.DataPlaneAccessTokenService; import org.eclipse.edc.connector.dataplane.spi.store.AccessTokenDataStore; import org.eclipse.edc.iam.did.spi.resolution.DidPublicKeyResolver; -import org.eclipse.edc.jwt.signer.spi.JwsSignerProvider; +import org.eclipse.edc.jwt.spi.signer.JwsSignerProvider; import org.eclipse.edc.keys.spi.LocalPublicKeyService; import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; import org.eclipse.edc.runtime.metamodel.annotation.Extension; diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplComponentTest.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplComponentTest.java index a5a2e3d7a3..692f011c67 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplComponentTest.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplComponentTest.java @@ -220,7 +220,7 @@ void refresh_issuerNotVerifiable() throws JOSEException { signedAuthToken.sign(CryptoConverter.createSigner(consumerKey)); var tokenResponse = tokenRefreshService.refreshToken(edr.getAdditional().get(EDR_PROPERTY_REFRESH_TOKEN).toString(), signedAuthToken.serialize()); - assertThat(tokenResponse).isFailed().detail().isEqualTo("Authentication token validation failed: Token verification failed"); + assertThat(tokenResponse).isFailed().detail().isEqualTo("Authentication token validation failed: JWT signature not valid"); } @DisplayName("Verify that a refresh attempt fails if no \"token\" claim is present") diff --git a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08Extension.java b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08Extension.java index 8449c4fb60..d4a01451ca 100644 --- a/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08Extension.java +++ b/edc-extensions/dsp/dsp-catalog-08/dsp-catalog-http-api-08/src/main/java/org/eclipse/edc/protocol/dsp/catalog/http/api/DspCatalogApiV08Extension.java @@ -30,7 +30,7 @@ import org.eclipse.edc.protocol.dsp.catalog.validation.CatalogRequestMessageValidator; import org.eclipse.edc.protocol.dsp.http.spi.message.ContinuationTokenManager; import org.eclipse.edc.protocol.dsp.http.spi.message.DspRequestHandler; -import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; +import org.eclipse.edc.protocol.spi.ProtocolWebhookResolver; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.spi.monitor.Monitor; @@ -44,6 +44,8 @@ import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; +import java.util.Optional; + import static org.eclipse.edc.protocol.dsp.http.spi.types.HttpMessageProtocol.DATASPACE_PROTOCOL_HTTP; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_NAMESPACE_V_08; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp08Constants.DSP_SCOPE_V_08; @@ -72,7 +74,7 @@ public class DspCatalogApiV08Extension implements ServiceExtension { @Inject private CriterionOperatorRegistry criterionOperatorRegistry; @Inject - private DataspaceProfileContextRegistry dataspaceProfileContextRegistry; + private ProtocolWebhookResolver protocolWebhookResolver; @Inject private TypeTransformerRegistry transformerRegistry; @Inject @@ -104,13 +106,15 @@ public void prepare() { } private void registerDataService() { - var webhook = dataspaceProfileContextRegistry.getWebhook(DATASPACE_PROTOCOL_HTTP); - if (webhook != null) { - dataServiceRegistry.register(DATASPACE_PROTOCOL_HTTP, (ctx, protocol) -> DataService.Builder.newInstance() - .endpointDescription("dspace:connector") - .endpointUrl(webhook.url()) - .build()); - } + dataServiceRegistry.register(DATASPACE_PROTOCOL_HTTP, this::createDataService); + } + + private DataService createDataService(String participantContextId, String protocol) { + return Optional.ofNullable(protocolWebhookResolver.getWebhook(participantContextId, protocol)) + .map(webhook -> DataService.Builder.newInstance() + .endpointDescription("dspace:connector") + .endpointUrl(webhook.url()) + .build()).orElse(null); } private ContinuationTokenManager continuationTokenManager(Monitor monitor) { diff --git a/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java b/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java index b144ceb4c5..dda6b6c990 100644 --- a/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java +++ b/edc-extensions/dsp/dsp-http-api-configuration-08/src/main/java/org/eclipse/edc/protocol/dsp/http/api/configuration/DspApiConfigurationV08Extension.java @@ -32,6 +32,7 @@ import org.eclipse.edc.protocol.spi.DefaultParticipantIdExtractionFunction; import org.eclipse.edc.runtime.metamodel.annotation.Extension; import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.query.CriterionOperatorRegistry; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; @@ -80,6 +81,8 @@ public class DspApiConfigurationV08Extension implements ServiceExtension { @Inject private ParticipantIdMapper participantIdMapper; @Inject + CriterionOperatorRegistry criterionOperatorRegistry; + @Inject private DspBaseWebhookAddress dspWebhookAddress; @Inject private DataspaceProfileContextRegistry dataspaceProfileContextRegistry; @@ -125,7 +128,7 @@ private void registerTransformers() { dspApiTransformerRegistry.register(new JsonValueToGenericTypeTransformer(typeManager, JSON_LD)); dspApiTransformerRegistry.register(new JsonObjectToAssetTransformer()); dspApiTransformerRegistry.register(new JsonObjectToQuerySpecTransformer()); - dspApiTransformerRegistry.register(new JsonObjectToCriterionTransformer()); + dspApiTransformerRegistry.register(new JsonObjectToCriterionTransformer(criterionOperatorRegistry)); dspApiTransformerRegistry.register(new JsonObjectToDataAddressDspaceTransformer(DSP_NAMESPACE_V_08)); dspApiTransformerRegistry.register(new JsonObjectFromPolicyTransformer(jsonBuilderFactory, participantIdMapper)); diff --git a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/BaseEdrCacheApiController.java b/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/BaseEdrCacheApiController.java index 8548d5d280..4e1620aabf 100644 --- a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/BaseEdrCacheApiController.java +++ b/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/BaseEdrCacheApiController.java @@ -95,7 +95,8 @@ public JsonObject initiateEdrNegotiation(JsonObject requestObject) { var participantContext = participantContextSupplier.get() .orElseThrow(exceptionMapper(ContractDefinition.class)); - var contractNegotiation = contractNegotiationService.initiateNegotiation(participantContext, enrichContractRequest(contractRequest)); + var contractNegotiation = contractNegotiationService.initiateNegotiation(participantContext, enrichContractRequest(contractRequest)) + .orElseThrow(InvalidRequestException::new); var idResponse = IdResponse.Builder.newInstance() .id(contractNegotiation.getId()) diff --git a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/BaseEdrCacheApiControllerTest.java b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/BaseEdrCacheApiControllerTest.java index a4817967cd..fb5f512d3c 100644 --- a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/BaseEdrCacheApiControllerTest.java +++ b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/BaseEdrCacheApiControllerTest.java @@ -102,7 +102,7 @@ void initEdrNegotiation_shouldWork_whenValidRequest() { var responseBody = Json.createObjectBuilder().add(TYPE, ID_RESPONSE_TYPE).add(ID, contractNegotiation.getId()).build(); when(transformerRegistry.transform(any(JsonObject.class), eq(ContractRequest.class))).thenReturn(Result.success(createContractRequest())); - when(contractNegotiationService.initiateNegotiation(any(), any())).thenReturn(contractNegotiation); + when(contractNegotiationService.initiateNegotiation(any(), any())).thenReturn(ServiceResult.success(contractNegotiation)); when(transformerRegistry.transform(any(IdResponse.class), eq(JsonObject.class))).thenReturn(Result.success(responseBody)); var participantContext = ParticipantContext.Builder.newInstance().participantContextId("participantContextId").identity("identity").build(); when(participantContextSupplier.get()).thenReturn(ServiceResult.success(participantContext)); diff --git a/edc-extensions/log4j2-monitor/src/main/java/org/eclipse/edc/monitor/logger/Log4j2Monitor.java b/edc-extensions/log4j2-monitor/src/main/java/org/eclipse/edc/monitor/logger/Log4j2Monitor.java index a11ca96a3d..cc83de758c 100644 --- a/edc-extensions/log4j2-monitor/src/main/java/org/eclipse/edc/monitor/logger/Log4j2Monitor.java +++ b/edc-extensions/log4j2-monitor/src/main/java/org/eclipse/edc/monitor/logger/Log4j2Monitor.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -19,7 +20,6 @@ package org.eclipse.edc.monitor.logger; -import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.eclipse.edc.spi.monitor.Monitor; @@ -37,14 +37,24 @@ public class Log4j2Monitor implements Monitor { */ private static final Logger LOGGER = LogManager.getLogger(Log4j2Monitor.class.getName()); + private final Level minLevel; + + public Log4j2Monitor() { + this(Level.getDefaultLevel()); + } + + public Log4j2Monitor(Level level) { + this.minLevel = level; + } + @Override public void severe(final Supplier supplier, final Throwable... errors) { - log(supplier, Level.ERROR, errors); + log(supplier, Level.SEVERE, errors); } @Override public void warning(final Supplier supplier, final Throwable... errors) { - log(supplier, Level.WARN, errors); + log(supplier, Level.WARNING, errors); } @Override @@ -58,10 +68,22 @@ public void debug(final Supplier supplier, final Throwable... errors) { } private void log(final Supplier supplier, final Level level, final Throwable... errors) { + if (level.value() < minLevel.value()) { + return; + } if (errors == null || errors.length == 0) { - LOGGER.log(level, () -> sanitizeMessage(supplier)); + LOGGER.log(levelConverter(level), () -> sanitizeMessage(supplier)); } else { - Arrays.stream(errors).forEach(error -> LOGGER.log(level, sanitizeMessage(supplier), error)); + Arrays.stream(errors).forEach(error -> LOGGER.log(levelConverter(level), sanitizeMessage(supplier), error)); } } + + private org.apache.logging.log4j.Level levelConverter(Level level) { + return switch (level) { + case SEVERE -> org.apache.logging.log4j.Level.ERROR; + case WARNING -> org.apache.logging.log4j.Level.WARN; + case INFO -> org.apache.logging.log4j.Level.INFO; + case DEBUG -> org.apache.logging.log4j.Level.DEBUG; + }; + } } \ No newline at end of file diff --git a/edc-extensions/log4j2-monitor/src/main/java/org/eclipse/edc/monitor/logger/Log4j2MonitorExtension.java b/edc-extensions/log4j2-monitor/src/main/java/org/eclipse/edc/monitor/logger/Log4j2MonitorExtension.java index 3cbd28d589..10c0686524 100644 --- a/edc-extensions/log4j2-monitor/src/main/java/org/eclipse/edc/monitor/logger/Log4j2MonitorExtension.java +++ b/edc-extensions/log4j2-monitor/src/main/java/org/eclipse/edc/monitor/logger/Log4j2MonitorExtension.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -30,7 +31,7 @@ public class Log4j2MonitorExtension implements MonitorExtension { @Override - public Monitor getMonitor() { - return new Log4j2Monitor(); + public Monitor getMonitor(Monitor.Level level, String... programArgs) { + return new Log4j2Monitor(level); } } diff --git a/edc-extensions/log4j2-monitor/src/test/java/org/eclipse/edc/monitor/logger/LoggerMonitorTest.java b/edc-extensions/log4j2-monitor/src/test/java/org/eclipse/edc/monitor/logger/LoggerMonitorTest.java index 076f3d72b5..1d1a04d6a1 100644 --- a/edc-extensions/log4j2-monitor/src/test/java/org/eclipse/edc/monitor/logger/LoggerMonitorTest.java +++ b/edc-extensions/log4j2-monitor/src/test/java/org/eclipse/edc/monitor/logger/LoggerMonitorTest.java @@ -55,7 +55,7 @@ void setUp() { var context = (LoggerContext) LogManager.getContext(false); var config = context.getConfiguration(); listAppender = config.getAppender("LIST"); - sut = new Log4j2Monitor(); + sut = new Log4j2Monitor(Monitor.Level.DEBUG); } @AfterEach diff --git a/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_8_0__Add_DataAddressAlias.sql b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_8_0__Add_DataAddressAlias.sql index f81f496d16..c3694e4aeb 100644 --- a/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_8_0__Add_DataAddressAlias.sql +++ b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_8_0__Add_DataAddressAlias.sql @@ -1 +1,18 @@ -ALTER TABLE edc_transfer_process ADD COLUMN data_address_alias text; +-- +-- Copyright (c) 2026 Cofinity-X 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: +-- Cofinity-X GmbH - initial API and implementation +-- + +-- +-- table: edc_transfer_process +-- + +ALTER TABLE edc_transfer_process ADD COLUMN IF NOT EXISTS data_address_alias text; diff --git a/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_9_0__Add_ClaimsColumn.sql b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_9_0__Add_ClaimsColumn.sql new file mode 100644 index 0000000000..c0af4d4350 --- /dev/null +++ b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_9_0__Add_ClaimsColumn.sql @@ -0,0 +1,19 @@ +-- +-- Copyright (c) 2026 Cofinity-X 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: +-- Cofinity-X GmbH - initial API and implementation +-- +-- +-- table: edc_contract_agreement, edc_transfer_process +-- + +ALTER TABLE edc_contract_agreement ADD COLUMN IF NOT EXISTS claims JSON; + +ALTER TABLE edc_transfer_process ADD COLUMN IF NOT EXISTS claims JSON; \ No newline at end of file diff --git a/edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java b/edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java index feac61695a..35dc4307ea 100644 --- a/edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java +++ b/edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java @@ -20,7 +20,10 @@ package org.eclipse.tractusx.edc.postgresql.migration; +import org.eclipse.edc.runtime.metamodel.annotation.Configuration; import org.eclipse.edc.runtime.metamodel.annotation.Setting; +import org.eclipse.edc.runtime.metamodel.annotation.SettingContext; +import org.eclipse.edc.runtime.metamodel.annotation.Settings; import org.eclipse.edc.spi.persistence.EdcPersistenceException; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; @@ -29,7 +32,9 @@ import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.flywaydb.core.api.output.MigrateResult; +import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Properties; import java.util.function.Supplier; @@ -45,11 +50,13 @@ @Deprecated(since = "0.12.0") public abstract class AbstractPostgresqlMigrationExtension implements ServiceExtension { - private static final String DEFAULT_MIGRATION_ENABLED_TEMPLATE = "true"; + private static final Boolean DEFAULT_MIGRATION_ENABLED_VALUE = true; + private static final String MIGRATION_ENABLED_PREFIX = "tx.edc.postgresql.migration"; + private static final String MIGRATION_ENABLED_PROPERTY = "enabled"; - // TODO: Make this a context aware setting after 0.17.0 upstream update. - @Setting(description = "Enable/disables subsystem schema migration", defaultValue = DEFAULT_MIGRATION_ENABLED_TEMPLATE, type = "boolean") - private static final String MIGRATION_ENABLED_TEMPLATE = "tx.edc.postgresql.migration.%s.enabled"; + @SettingContext(MIGRATION_ENABLED_PREFIX) + @Configuration + private Map migrationEnablement; private static final String DEFAULT_MIGRATION_SCHEMA = "public"; private static final String MIGRATION_SCHEMA = "tx.edc.postgresql.migration.schema"; @@ -70,7 +77,10 @@ public void initialize(final ServiceExtensionContext context) { var config = context.getConfig(); var subSystemName = Objects.requireNonNull(getSubsystemName()); - enabled = config.getBoolean(MIGRATION_ENABLED_TEMPLATE.formatted(subSystemName), Boolean.valueOf(DEFAULT_MIGRATION_ENABLED_TEMPLATE)); + enabled = Optional.ofNullable(migrationEnablement) + .map(m -> m.get(subSystemName)) + .map(MigrationSetting::enabled) + .orElse(DEFAULT_MIGRATION_ENABLED_VALUE); if (!enabled) { context.getMonitor().info("Migration for subsystem %s disabled".formatted(subSystemName)); @@ -113,4 +123,12 @@ protected String getMigrationSubsystem() { return getSubsystemName(); } + @Settings + private record MigrationSetting( + @Setting( + key = MIGRATION_ENABLED_PROPERTY, + description = "Enable/disables subsystem schema migration" + ) + Boolean enabled + ) {} } diff --git a/edc-extensions/validators/empty-asset-selector/src/test/java/org/eclipse/tractusx/edc/validators/emptyassetselector/EmptyAssetSelectorValidatorTest.java b/edc-extensions/validators/empty-asset-selector/src/test/java/org/eclipse/tractusx/edc/validators/emptyassetselector/EmptyAssetSelectorValidatorTest.java index 899e626a0d..7c26bf3165 100644 --- a/edc-extensions/validators/empty-asset-selector/src/test/java/org/eclipse/tractusx/edc/validators/emptyassetselector/EmptyAssetSelectorValidatorTest.java +++ b/edc-extensions/validators/empty-asset-selector/src/test/java/org/eclipse/tractusx/edc/validators/emptyassetselector/EmptyAssetSelectorValidatorTest.java @@ -22,6 +22,7 @@ import jakarta.json.Json; import jakarta.json.JsonArrayBuilder; import org.assertj.core.api.Assertions; +import org.eclipse.edc.spi.query.CriterionOperator; import org.eclipse.edc.spi.query.CriterionOperatorRegistry; import org.eclipse.edc.validator.jsonobject.JsonObjectValidator; import org.eclipse.edc.validator.spi.ValidationFailure; @@ -46,6 +47,7 @@ class EmptyAssetSelectorValidatorTest { CriterionOperatorRegistry criterionOperatorRegistry = mock(); + CriterionOperator criterionOperator = new CriterionOperator(CriterionOperatorRegistry.IN, Iterable.class, null); private final JsonObjectValidator validator = EmptyAssetSelectorValidator.instance(criterionOperatorRegistry); @@ -54,7 +56,7 @@ void shouldPass_whenContractDefinitionIsCorrect() { var criterion = createObjectBuilder() .add(CRITERION_OPERAND_LEFT, value("operandLeft")) - .add(CRITERION_OPERATOR, value("=")) + .add(CRITERION_OPERATOR, value(CriterionOperatorRegistry.IN)) .add(CRITERION_OPERAND_RIGHT, value("operandRight")); var contractDefinition = createObjectBuilder() @@ -63,7 +65,7 @@ void shouldPass_whenContractDefinitionIsCorrect() { .add(CONTRACT_DEFINITION_ASSETS_SELECTOR, createArrayBuilder().add(criterion)) .build(); - when(criterionOperatorRegistry.isSupported("=")).thenReturn(true); + when(criterionOperatorRegistry.get(CriterionOperatorRegistry.IN)).thenReturn(criterionOperator); var result = validator.validate(contractDefinition); diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java index ae8027f5b9..c122324da9 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java @@ -268,6 +268,7 @@ public String createContractDefinitionLegacyManagementContext(TractusxDcpPartici .build(); return participant.baseManagementRequest() + .basePath("/v3") .contentType(JSON) .body(requestBody) .when() diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/ParticipantEdrApi.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/ParticipantEdrApi.java index 97b9661008..e2b0fa36af 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/ParticipantEdrApi.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/ParticipantEdrApi.java @@ -231,6 +231,6 @@ private String createQuery(String leftOp, String op, String rightOp) { } private RequestSpecification baseEdrRequest() { - return participant.baseManagementRequest().contentType(JSON); + return participant.baseManagementRequest().basePath("/v3").contentType(JSON); } } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java index 9ddb9e0d18..2355f64f49 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java @@ -179,6 +179,7 @@ public void storeBusinessPartner(String bpn, String... groups) { .add(TX_NAMESPACE + "groups", Json.createArrayBuilder(Arrays.asList(groups))) .build(); baseManagementRequest() + .basePath("/v3") .contentType(JSON) .body(body) .when() @@ -196,6 +197,7 @@ public void updateBusinessPartner(String bpn, String... groups) { .add(TX_NAMESPACE + "groups", Json.createArrayBuilder(Arrays.asList(groups))) .build(); baseManagementRequest() + .basePath("/v3") .contentType(JSON) .body(body) .when() @@ -209,6 +211,7 @@ public void updateBusinessPartner(String bpn, String... groups) { */ public void deleteBusinessPartner(String bpn) { baseManagementRequest() + .basePath("/v3") .when() .delete("/business-partner-groups/{bpn}", bpn) .then() @@ -222,6 +225,7 @@ public ValidatableResponse retireProviderAgreement(String agreementId) { .add(AR_ENTRY_REASON, "long-reason") .build(); return baseManagementRequest() + .basePath("/v3") .contentType(JSON) .body(body) .when() @@ -260,6 +264,7 @@ public ValidatableResponse getCatalog(TractusxParticipantBase provider) { return baseManagementRequest() .header("x-api-key", MANAGEMENT_API_KEY) + .basePath("/v3") .contentType(JSON) .when() .body(requestBodyBuilder.build()) @@ -270,6 +275,7 @@ public ValidatableResponse getCatalog(TractusxParticipantBase provider) { public String getTransferProcessField(String transferProcessId, String fieldName) { return baseManagementRequest() + .basePath("/v3") .contentType(JSON) .when() .get("/transferprocesses/{id}", transferProcessId) diff --git a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/auth/DelegatedAuthEndToEndTest.java b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/auth/DelegatedAuthEndToEndTest.java index 6ec5828abb..e79089532a 100644 --- a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/auth/DelegatedAuthEndToEndTest.java +++ b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/auth/DelegatedAuthEndToEndTest.java @@ -64,6 +64,7 @@ void shouldDelegateAuth() { var token = KEYCLOAK.issueToken(); CONNECTOR.baseManagementRequest() + .basePath("/v3") .header("Authorization", "Bearer " + token) .contentType(ContentType.JSON) .post("/assets/request") diff --git a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java index e8a3679e0b..a8dd179416 100644 --- a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java +++ b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java @@ -122,6 +122,7 @@ private ValidatableResponse createContractDefinitionRequest(String definitionId, } return PROVIDER.baseManagementRequest() + .basePath("/v3") .contentType(JSON) .body(requestBody.build()) .when() diff --git a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java index 470acdde80..762dba72ac 100644 --- a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java +++ b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java @@ -248,7 +248,7 @@ public Stream provideArguments(ExtensionContext extensionCo private Response createPolicyDefinition(JsonObject policy) { JsonObject requestBody = Json.createObjectBuilder().add("@context", Json.createObjectBuilder().add("@vocab", "https://w3id.org/edc/v0.0.1/ns/")).add("@type", "PolicyDefinition").add("policy", policy).build(); - return (Response) PROVIDER.baseManagementRequest().contentType(ContentType.JSON).body(requestBody).when().post("/policydefinitions", new Object[0]).then().extract(); + return (Response) PROVIDER.baseManagementRequest().basePath("/v3").contentType(ContentType.JSON).body(requestBody).when().post("/policydefinitions", new Object[0]).then().extract(); } private static JsonObject policyFromRules(String ruleType, String policyDefinition, JsonObject... rules) { diff --git a/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/TxScopeToCriterionTransformer.java b/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/TxScopeToCriterionTransformer.java index ca203347ef..7cbc28ccff 100644 --- a/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/TxScopeToCriterionTransformer.java +++ b/edc-tests/runtime/dcp/dcp-extensions/src/main/java/org/eclipse/tractusx/edc/dcp/ih/TxScopeToCriterionTransformer.java @@ -41,13 +41,14 @@ public class TxScopeToCriterionTransformer implements ScopeToCriterionTransforme private final List allowedOperations = List.of("read", "*", "all"); @Override - public Result transform(String scope) { + public Result> transformScope(String scope) { var tokens = tokenize(scope); if (tokens.failed()) { return failure("Scope string cannot be converted: %s".formatted(tokens.getFailureDetail())); } var credentialType = tokens.getContent()[1]; - return success(new Criterion(TYPE_OPERAND, CONTAINS_OPERATOR, credentialType)); + + return success(List.of(new Criterion(TYPE_OPERAND, CONTAINS_OPERATOR, credentialType))); } protected Result tokenize(String scope) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e6c83a300e..7cb540b282 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,15 +2,14 @@ format.version = "1.1" [versions] -edc = "0.16.0" -edc-next = "0.16.0" +edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.2" awaitility = "4.3.0" aws = "2.46.4" azure-storage-blob = "12.34.0" bouncyCastle-jdk18on = "1.84" -dcp-tck = "1.0.0-RC6" +dcp-tck = "1.0.0" dsp-tck = "1.0.0-RC6" flyway = "12.8.0" jackson = "2.22.0" @@ -51,7 +50,6 @@ edc-spi-http = { module = "org.eclipse.edc:http-spi", version.ref = "edc" } edc-spi-identity-did = { module = "org.eclipse.edc:identity-did-spi", version.ref = "edc" } edc-spi-jsonld = { module = "org.eclipse.edc:json-ld-spi", version.ref = "edc" } edc-spi-jwt = { module = "org.eclipse.edc:jwt-spi", version.ref = "edc" } -edc-spi-jwt-signer = { module = "org.eclipse.edc:jwt-signer-spi", version.ref = "edc" } edc-spi-keypair = { module = "org.eclipse.edc:keypair-spi", version.ref = "edc" } edc-spi-keys = { module = "org.eclipse.edc:keys-spi", version.ref = "edc" } edc-spi-participant = { module = "org.eclipse.edc:participant-spi", version.ref = "edc" } @@ -75,8 +73,8 @@ edc-core-controlplane = { module = "org.eclipse.edc:control-plane-core", version edc-transform-controlplane = { module = "org.eclipse.edc:control-plane-transform", version.ref = "edc" } edc-core-edrstore = { module = "org.eclipse.edc:edr-store-core", version.ref = "edc" } edc-core-jersey = { module = "org.eclipse.edc:jersey-core", version.ref = "edc" } -edc-core-participant-context-config = { module = "org.eclipse.edc:participant-context-config-core", version.ref = "edc" } -edc-core-participant-context-single = { module = "org.eclipse.edc:participant-context-single-core", version.ref = "edc" } +edc-core-participant-context-core = { module = "org.eclipse.edc:participant-context-connector-core", version.ref = "edc" } +edc-core-participant-context-classic = { module = "org.eclipse.edc:participant-context-connector-classic-core", version.ref = "edc" } edc-core-policy-monitor = { module = "org.eclipse.edc:policy-monitor-core", version.ref = "edc" } edc-core-runtime = { module = "org.eclipse.edc:runtime-core", version.ref = "edc" } edc-core-token = { module = "org.eclipse.edc:token-core", version.ref = "edc" } @@ -174,7 +172,7 @@ dsp-tck-catalog = { module = "org.eclipse.dataspacetck.dsp:dsp-catalog", version dsp-tck-contractnegotiation = { module = "org.eclipse.dataspacetck.dsp:dsp-contract-negotiation", version.ref = "dsp-tck" } dsp-tck-transferprocess = { module = "org.eclipse.dataspacetck.dsp:dsp-transfer-process", version.ref = "dsp-tck" } junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit" } -tck-extension = { module = "org.eclipse.edc:tck-extension", version.ref = "edc-next" } +tck-extension = { module = "org.eclipse.edc:tck-extension", version.ref = "edc" } # DSP libraries dsp-spi-http = { module = "org.eclipse.edc:dsp-http-spi", version.ref = "edc" } From df8aa7769a05e6487eeb97eeab6fd4efd342c945 Mon Sep 17 00:00:00 2001 From: ndr_brt Date: Wed, 3 Jun 2026 11:13:00 +0200 Subject: [PATCH 147/259] Fix e2e and dataplane tests as well use the correct dependency --- edc-dataplane/edc-dataplane-base/build.gradle.kts | 2 +- .../edc/tests/participant/TractusxParticipantBase.java | 1 + .../edc/dataplane/transfer/test/AzureToAzureTest.java | 10 +++++----- .../edc/dataplane/transfer/test/MultiCloudTest.java | 10 +++++----- .../edc/dataplane/transfer/test/S3ToS3Test.java | 8 ++++---- .../e2e/DataPlaneTokenRefreshEndToEndTest.java | 2 +- gradle/libs.versions.toml | 2 +- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/edc-dataplane/edc-dataplane-base/build.gradle.kts b/edc-dataplane/edc-dataplane-base/build.gradle.kts index f5618c01af..9dcdc29e80 100644 --- a/edc-dataplane/edc-dataplane-base/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-base/build.gradle.kts @@ -53,7 +53,7 @@ dependencies { runtimeOnly(libs.edc.aws.validator.data.address.s3) runtimeOnly(libs.edc.core.did) // for the DID Public Key Resolver runtimeOnly(libs.edc.core.edrstore) - runtimeOnly(libs.edc.core.participant.context.core) + runtimeOnly(libs.edc.core.participant.context) runtimeOnly(libs.edc.core.participant.context.classic) runtimeOnly(libs.edc.dpf.awss3) runtimeOnly(libs.edc.aws.provision.s3) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java index 2355f64f49..24d01bd6b0 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java @@ -142,6 +142,7 @@ public Config getConfig() { put("tractusx.edc.participant.bpn", getBpn()); put("edc.iam.did.web.use.https", "false"); put("edc.encryption.strict", "false"); + put("edc.policy.monitor.period", "PT5S"); } }; diff --git a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/AzureToAzureTest.java b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/AzureToAzureTest.java index 988bf49255..26ab23aac8 100644 --- a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/AzureToAzureTest.java +++ b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/AzureToAzureTest.java @@ -130,7 +130,7 @@ void transferMultipleFile_success(Vault vault) { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(request) - .post() + .post("/start") .then() .log().ifValidationFails() .statusCode(200); @@ -167,7 +167,7 @@ void transferFile_success(Vault vault) { blobAddress(sourceContainerName, PROVIDER_AZURITE_ACCOUNT.name(), AZBLOB_PROVIDER_KEY_ALIAS, dspaceProperty(EDC_NAMESPACE + "blobName", TESTFILE_NAME)), blobAddress(destinationContainerName, CONSUMER_AZURITE_ACCOUNT.name(), AZBLOB_CONSUMER_KEY_ALIAS, dspaceProperty(EDC_NAMESPACE + "blobName", TESTFILE_NAME)) ).build()) - .post() + .post("/start") .then() .log().ifValidationFails() .statusCode(200); @@ -220,7 +220,7 @@ void transferFile_largeFile(long sizeBytes, Vault vault) throws IOException { blobAddress(sourceContainerName, PROVIDER_AZURITE_ACCOUNT.name(), AZBLOB_PROVIDER_KEY_ALIAS, dspaceProperty(EDC_NAMESPACE + "blobName", blobName)), blobAddress(destinationContainerName, CONSUMER_AZURITE_ACCOUNT.name(), AZBLOB_CONSUMER_KEY_ALIAS, dspaceProperty(EDC_NAMESPACE + "blobName", blobName)) ).build()) - .post() + .post("/start") .then() .log().ifValidationFails() .log().ifValidationFails() @@ -264,7 +264,7 @@ void transferFolder_targetFolderNotExists_shouldCreate(Vault vault) { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(request) - .post() + .post("/start") .then() .log().ifValidationFails() .statusCode(200); @@ -299,7 +299,7 @@ void transferFile_targetContainerNotExist_shouldFail(Vault vault) { blobAddress(destinationContainerName, CONSUMER_AZURITE_ACCOUNT.name(), AZBLOB_CONSUMER_KEY_ALIAS, dspaceProperty(EDC_NAMESPACE + "blobName", TESTFILE_NAME)) ).build() ) - .post() + .post("/start") .then() .log().ifValidationFails() .statusCode(200); diff --git a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/MultiCloudTest.java b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/MultiCloudTest.java index 67f237c980..643b446617 100644 --- a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/MultiCloudTest.java +++ b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/MultiCloudTest.java @@ -133,7 +133,7 @@ void transferFile_azureToS3MultipleFiles(Vault vault) { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(request) - .post() + .post("/start") .then() .log().ifError() .statusCode(200); @@ -186,7 +186,7 @@ void transferFile_azureToS3(Vault vault) { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(request) - .post() + .post("/start") .then() .log().ifError() .statusCode(200); @@ -245,7 +245,7 @@ void transferFile_s3ToAzureMultipleFiles(Vault vault) { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(request) - .post() + .post("/start") .then() .statusCode(200); @@ -309,7 +309,7 @@ void transferFile_s3ToAzureMultipleFiles_whenConsumerDefinesBloblName_success(Va .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(request) - .post() + .post("/start") .then() .statusCode(200); @@ -364,7 +364,7 @@ void transferFile_s3ToAzure(Vault vault) { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(request) - .post() + .post("/start") .then() .statusCode(200); diff --git a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/S3ToS3Test.java b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/S3ToS3Test.java index fafd1b79f8..8056abf4a9 100644 --- a/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/S3ToS3Test.java +++ b/edc-tests/e2e/cloud-transfer-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/transfer/test/S3ToS3Test.java @@ -109,7 +109,7 @@ void transferMultipleFiles() { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(createDataFlowStartMessage(sourceBucketName, destinationBucketName, additionalSourceAddressProperties, UUID.randomUUID().toString())) - .post() + .post("/start") .then() .statusCode(200); @@ -132,7 +132,7 @@ void transferFile_success() { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(createDataFlowStartMessage(sourceBucketName, destinationBucketName, additionalSourceAddressProperties, UUID.randomUUID().toString())) - .post() + .post("/start") .then() .statusCode(200); @@ -154,7 +154,7 @@ void shouldFail_whenDestinationBucketDoesNotExist() { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(createDataFlowStartMessage(sourceBucketName, "not-existent-bucket", additionalSourceAddressProperties, processId)) - .post() + .post("/start") .then() .statusCode(200); @@ -183,7 +183,7 @@ void shouldTransferOneGbFile() { .baseUri(START_DATAFLOW_URI.get().toString()) .contentType(ContentType.JSON) .body(createDataFlowStartMessage(sourceBucketName, destinationBucketName, additionalSourceAddressProperties, processId)) - .post() + .post("/start") .then() .statusCode(200) .log().ifValidationFails(); diff --git a/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java b/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java index 556cda0463..bf6a45d508 100644 --- a/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java +++ b/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java @@ -236,7 +236,7 @@ void refresh_spoofedAuthToken() throws JOSEException { .then() .log().ifValidationFails() .statusCode(401) - .body(containsString("Token verification failed")); + .body(containsString("JWT signature not valid")); } @DisplayName("The refresh token does not match the stored one") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7cb540b282..0d3a8fafb8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -73,7 +73,7 @@ edc-core-controlplane = { module = "org.eclipse.edc:control-plane-core", version edc-transform-controlplane = { module = "org.eclipse.edc:control-plane-transform", version.ref = "edc" } edc-core-edrstore = { module = "org.eclipse.edc:edr-store-core", version.ref = "edc" } edc-core-jersey = { module = "org.eclipse.edc:jersey-core", version.ref = "edc" } -edc-core-participant-context-core = { module = "org.eclipse.edc:participant-context-connector-core", version.ref = "edc" } +edc-core-participant-context = { module = "org.eclipse.edc:participant-context-core", version.ref = "edc" } edc-core-participant-context-classic = { module = "org.eclipse.edc:participant-context-connector-classic-core", version.ref = "edc" } edc-core-policy-monitor = { module = "org.eclipse.edc:policy-monitor-core", version.ref = "edc" } edc-core-runtime = { module = "org.eclipse.edc:runtime-core", version.ref = "edc" } From cd6a8dc56645ea2d51718d0a996dbd24c9909fb4 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Fri, 12 Jun 2026 15:47:26 +0200 Subject: [PATCH 148/259] Fix issues due to proper participant context usage Signed-off-by: Lars Geyer-Blaumeiser --- edc-dataplane/edc-dataplane-base/build.gradle.kts | 1 + .../tests/fixtures/DcpHelperFunctions.java | 4 ++-- .../edc/tests/participant/DcpParticipant.java | 12 ++++-------- .../tests/participant/TractusxParticipantBase.java | 13 +++++++++++-- .../edc/tests/transfer/DivConsumerPullTest.java | 8 ++++---- gradle/libs.versions.toml | 1 + 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/edc-dataplane/edc-dataplane-base/build.gradle.kts b/edc-dataplane/edc-dataplane-base/build.gradle.kts index 9dcdc29e80..97c61a1ba8 100644 --- a/edc-dataplane/edc-dataplane-base/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-base/build.gradle.kts @@ -54,6 +54,7 @@ dependencies { runtimeOnly(libs.edc.core.did) // for the DID Public Key Resolver runtimeOnly(libs.edc.core.edrstore) runtimeOnly(libs.edc.core.participant.context) + runtimeOnly(libs.edc.core.participant.context.config) runtimeOnly(libs.edc.core.participant.context.classic) runtimeOnly(libs.edc.dpf.awss3) runtimeOnly(libs.edc.aws.provision.s3) diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java index 69361058a8..6dcfe1b781 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java @@ -94,10 +94,10 @@ public static void configureParticipantContext(TractusxDcpParticipantBase partic var service = new Service(); service.setId("#credential-service"); service.setType("CredentialService"); - service.setServiceEndpoint(identityHubParticipant.getResolutionApi() + "/v1/participants/" + toBase64(participant.getDid())); + service.setServiceEndpoint(identityHubParticipant.getResolutionApi() + "/v1/participants/" + participant.getParticipantContextId()); var participantManifest = ParticipantManifest.Builder.newInstance() - .participantContextId(participant.getDid()) + .participantContextId(participant.getParticipantContextId()) .did(participant.getDid()) .key(key) .serviceEndpoint(service) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java index fc3344f230..c6dd7c767c 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java @@ -87,7 +87,7 @@ public void configureParticipant(DataspaceIssuer issuer, RuntimeExtension runtim stsRuntimeExtension.getService(Vault.class).storeSecret(getPrivateKeyAlias(), getPrivateKeyAsString()); var participantManifest = ParticipantManifest.Builder.newInstance() - .participantContextId(getDid()) + .participantContextId(getParticipantContextId()) .did(getDid()) .build(); var participantContextService = stsRuntimeExtension.getService(IdentityHubParticipantContextService.class); @@ -96,14 +96,14 @@ public void configureParticipant(DataspaceIssuer issuer, RuntimeExtension runtim runtimeExtension.getService(Vault.class).storeSecret("client_secret_alias", createParticipantContextResponse.clientSecret()); - stsRuntimeExtension.getService(KeyPairService.class).addKeyPair(getDid(), createKeyDescriptor(), true) + stsRuntimeExtension.getService(KeyPairService.class).addKeyPair(getParticipantContextId(), createKeyDescriptor(), true) .orElseThrow(f -> new EdcException("Cannot store key pair: " + f.getFailureDetail())); KeyPool.register(getFullKeyId(), getKeyPair()); var account = StsAccount.Builder.newInstance() .id(getId()) - .participantContextId(getDid()) + .participantContextId(getParticipantContextId()) .name(getName()) .clientId(getDid()) .did(getDid()) @@ -151,7 +151,7 @@ private DidDocument generateDidDocument() { service.setId("#credential-service"); service.setType("CredentialService"); var credentialServiceBaseUri = Objects.requireNonNullElse(participant.credentialServiceUri, participant.csService); - service.setServiceEndpoint(credentialServiceBaseUri.get() + "/v1/participants/" + toBase64(participant.did)); + service.setServiceEndpoint(credentialServiceBaseUri.get() + "/v1/participants/" + participant.participantContextId); var ecKey = participant.getKeyPairAsJwk(); @@ -169,9 +169,5 @@ private DidDocument generateDidDocument() { .verificationMethod(List.of(verificationMethod)) .build(); } - - private String toBase64(String s) { - return Base64.getUrlEncoder().encodeToString(s.getBytes()); - } } } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java index 24d01bd6b0..839156c9d1 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java @@ -41,6 +41,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.UUID; import static io.restassured.http.ContentType.JSON; import static jakarta.json.Json.createObjectBuilder; @@ -82,6 +83,7 @@ public abstract class TractusxParticipantBase extends IdentityParticipant { protected ParticipantConsumerDataPlaneApi dataPlane; protected String bpn; protected String did; + protected String participantContextId; public void createAsset(String id) { createAsset(id, new HashMap<>(), Map.of("type", "test-type")); @@ -96,7 +98,12 @@ public String getBpn() { public String getDid() { return did; } - + + @NotNull + public String getParticipantContextId() { + return participantContextId; + } + /** * Allows overriding the participant id, as for DSP 0.8 tests the provider's BPN has to be used. * @@ -138,7 +145,7 @@ public Config getConfig() { put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); put("edc.dataplane.api.public.baseurl", "%s/v2/data".formatted(dataPlanePublic.get())); put("edc.policy.validation.enabled", "true"); - put("edc.participant.context.id", "general-test-id"); + put("edc.participant.context.id", participantContextId); put("tractusx.edc.participant.bpn", getBpn()); put("edc.iam.did.web.use.https", "false"); put("edc.encryption.strict", "false"); @@ -366,6 +373,8 @@ public P build() { participant.bpn = participant.name.toLowerCase() + BPN_SUFFIX; } + participant.participantContextId = UUID.randomUUID().toString(); + participant.enrichManagementRequest = requestSpecification -> requestSpecification.headers(Map.of(API_KEY_HEADER_NAME, MANAGEMENT_API_KEY)); super.timeout(ASYNC_TIMEOUT); super.build(); diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java index 7beabf3920..c015f4040c 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java @@ -161,7 +161,7 @@ private static EmbeddedSecureTokenService tokenServiceFor(TokenGenerationService var dummyId = UUID.randomUUID().toString(); var account = StsAccount.Builder.newInstance() .id(dummyId) - .participantContextId(participant.getDid()) + .participantContextId(participant.getParticipantContextId()) .clientId(participant.getDid()) .name(participant.getName()) .did(participant.getDid()) @@ -173,15 +173,15 @@ private static EmbeddedSecureTokenService tokenServiceFor(TokenGenerationService var participantContextStore = runtime.getService(ParticipantContextStore.class); participantContextStore.create(IdentityHubParticipantContext.Builder.newInstance() - .participantContextId(participant.getDid()) + .participantContextId(participant.getParticipantContextId()) .did(participant.getDid()) - .apiTokenAlias(participant.getDid()).build()); + .apiTokenAlias(participant.getParticipantContextId()).build()); var keyPairService = runtime.getService(KeyPairService.class); var keyDescriptor = participant.createKeyDescriptor(); KeyPool.register(participant.getFullKeyId(), participant.getKeyPair()); - keyPairService.addKeyPair(participant.getDid(), keyDescriptor, true) + keyPairService.addKeyPair(participant.getParticipantContextId(), keyDescriptor, true) .orElseThrow(f -> new RuntimeException("Cannot add key pair: " + f.getFailureDetail())); return new EmbeddedSecureTokenService( diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0d3a8fafb8..79595fd1d4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -73,6 +73,7 @@ edc-core-controlplane = { module = "org.eclipse.edc:control-plane-core", version edc-transform-controlplane = { module = "org.eclipse.edc:control-plane-transform", version.ref = "edc" } edc-core-edrstore = { module = "org.eclipse.edc:edr-store-core", version.ref = "edc" } edc-core-jersey = { module = "org.eclipse.edc:jersey-core", version.ref = "edc" } +edc-core-participant-context-config = { module = "org.eclipse.edc:participant-context-config-core", version.ref = "edc" } edc-core-participant-context = { module = "org.eclipse.edc:participant-context-core", version.ref = "edc" } edc-core-participant-context-classic = { module = "org.eclipse.edc:participant-context-connector-classic-core", version.ref = "edc" } edc-core-policy-monitor = { module = "org.eclipse.edc:policy-monitor-core", version.ref = "edc" } From 9fac7079d1be78fb0774638d135acbecab55dce1 Mon Sep 17 00:00:00 2001 From: AndrYurk Date: Tue, 16 Jun 2026 21:42:13 +0200 Subject: [PATCH 149/259] Fix several failing tests and disable compatibility tests --- .github/workflows/verify.yaml | 1 + .../tests/fixtures/DcpHelperFunctions.java | 2 +- .../tests/participant/DataspaceIssuer.java | 37 +++++++++++-------- .../edc/tests/participant/DcpParticipant.java | 3 +- .../tck/dcp/DcpPresentationFlowTest.java | 3 +- .../tests/transfer/CredentialSpoofTest.java | 4 +- .../tests/transfer/DivConsumerPullTest.java | 14 +++++-- .../dcp/dispatchers/DivDispatcher.java | 16 +++++--- .../tck/dsp/EdcCompatibilityPostgresTest.java | 24 ++++++++++-- 9 files changed, 72 insertions(+), 32 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index b60fddbd8d..afd7436c57 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -259,6 +259,7 @@ jobs: run: ./gradlew test -DincludeTags="PostgresqlIntegrationTest" -PverboseTest=true compatibility-tests: + if: false # Disabled while compatibility tests are being migrated to the updated EDC runtime. runs-on: ubuntu-latest permissions: contents: read diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java index 6dcfe1b781..56a0150cee 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java @@ -72,7 +72,7 @@ public static void configureParticipant(TractusxDcpParticipantBase participant, var vault = identityHubRuntime.getService(Vault.class); var credentialStore = identityHubRuntime.getService(CredentialStore.class); - var credentials = issuer.issueCredentials(participant.getDid(), participant.getId()); + var credentials = issuer.issueCredentials(participant.getDid(), participant.getId(), participant.getParticipantContextId()); credentials.forEach(credentialStore::create); diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DataspaceIssuer.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DataspaceIssuer.java index 6d94b3e7ee..faf2b8ca15 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DataspaceIssuer.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DataspaceIssuer.java @@ -82,7 +82,7 @@ public String verificationId() { } - public VerifiableCredentialResource issueMembershipCredential(String did, String bpn) { + public VerifiableCredentialResource issueMembershipCredential(String did, String bpn, String participantContextId) { return issueCredential( did, bpn, "MembershipCredential", () -> CredentialSubject.Builder.newInstance() @@ -90,11 +90,12 @@ public VerifiableCredentialResource issueMembershipCredential(String did, String .claim("holderIdentifier", bpn) .claim("bpn", bpn) .build(), - membershipRawVc(did, bpn) + membershipRawVc(did, bpn), + participantContextId ); } - public VerifiableCredentialResource issueDismantlerCredential(String did, String bpn) { + public VerifiableCredentialResource issueDismantlerCredential(String did, String bpn, String participantContextId) { return issueCredential( did, bpn, "DismantlerCredential", () -> CredentialSubject.Builder.newInstance() @@ -109,11 +110,12 @@ public VerifiableCredentialResource issueDismantlerCredential(String did, String .add("activityType", "vehicleDismantle") .add("allowedVehicleBrands", Json.createArrayBuilder().add("BMW").add("Volkswagen").build()) .add("id", did) - .build()) + .build()), + participantContextId ); } - public VerifiableCredentialResource issueFrameworkCredential(String did, String bpn, String credentialType) { + public VerifiableCredentialResource issueFrameworkCredential(String did, String bpn, String credentialType, String participantContextId) { var subject = Json.createObjectBuilder() .add("type", credentialType) .add("holderIdentifier", bpn) @@ -128,7 +130,8 @@ public VerifiableCredentialResource issueFrameworkCredential(String did, String .id(did) .claim("holderIdentifier", bpn) .build(), - createVcBuilder(credentialType, subject) + createVcBuilder(credentialType, subject), + participantContextId ); } @@ -159,15 +162,15 @@ public JsonObjectBuilder membershipRawVc(String did, String bpn) { return createVcBuilder("MembershipCredential", subject); } - public List issueCredentials(String did, String bpn) { + public List issueCredentials(String did, String bpn, String participantContextId) { return List.of( - issueMembershipCredential(did, bpn), - issueDismantlerCredential(did, bpn), - issueBpnCredential(did, bpn), - issueFrameworkCredential(did, bpn, "DataExchangeGovernanceCredential")); + issueMembershipCredential(did, bpn, participantContextId), + issueDismantlerCredential(did, bpn, participantContextId), + issueBpnCredential(did, bpn, participantContextId), + issueFrameworkCredential(did, bpn, "DataExchangeGovernanceCredential", participantContextId)); } - VerifiableCredentialResource issueBpnCredential(String did, String bpn) { + VerifiableCredentialResource issueBpnCredential(String did, String bpn, String participantContextId) { var subject = Json.createObjectBuilder() .add("type", "BpnCredential") .add("holderIdentifier", bpn) @@ -182,11 +185,15 @@ VerifiableCredentialResource issueBpnCredential(String did, String bpn) { .claim("holderIdentifier", bpn) .claim("bpn", bpn) .build(), - createVcBuilder("BpnCredential", subject) + createVcBuilder("BpnCredential", subject), + participantContextId ); } - private VerifiableCredentialResource issueCredential(String did, String bpn, String type, Supplier credentialSubjectSupplier, JsonObjectBuilder vcBuilder) { + private VerifiableCredentialResource issueCredential(String did, String bpn, String type, + Supplier credentialSubjectSupplier, + JsonObjectBuilder vcBuilder, + String participantContextId) { var credential = VerifiableCredential.Builder.newInstance() .type(type) .credentialSubject(credentialSubjectSupplier.get()) @@ -198,7 +205,7 @@ private VerifiableCredentialResource issueCredential(String did, String bpn, Str var rawVc = createJwtVc(vcJson, did); return VerifiableCredentialResource.Builder.newInstance() .issuerId(didUrl()) - .participantContextId(did) + .participantContextId(participantContextId) .holderId(bpn) .credential(new VerifiableCredentialContainer(rawVc, CredentialFormat.VC1_0_JWT, credential)) .build(); diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java index c6dd7c767c..d76245de80 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/DcpParticipant.java @@ -38,7 +38,6 @@ import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.eclipse.tractusx.edc.tests.runtimes.KeyPool; -import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Objects; @@ -113,7 +112,7 @@ public void configureParticipant(DataspaceIssuer issuer, RuntimeExtension runtim } private List issueCredentials(DataspaceIssuer issuer) { - return issuer.issueCredentials(getDid(), getBpn()); + return issuer.issueCredentials(getDid(), getBpn(), getParticipantContextId()); } public KeyDescriptor createKeyDescriptor() { diff --git a/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java b/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java index 3aacaed15e..c4257ebc5d 100644 --- a/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java +++ b/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java @@ -229,12 +229,13 @@ private static Config runtimeConfiguration() { put("web.http.port", String.valueOf(getFreePort())); put("web.http.protocol.path", PROTOCOL_API_PATH); put("web.http.protocol.port", String.valueOf(PROTOCOL_API_PORT)); - put("edc.participant.id", "id"); + put("edc.participant.id", VERIFIER_DID); put("edc.iam.issuer.id", VERIFIER_DID); put("edc.iam.sts.oauth.token.url", "https://example.com/token"); put("edc.iam.sts.oauth.client.id", "test-client-id"); put("edc.iam.sts.oauth.client.secret.alias", "test-secret-alias"); put("tx.edc.iam.dcp.bdrs.server.url", "http://sts.example.com"); + put("tx.edc.dcp.cache.enabled", "false"); //register a default scope https://github.com/eclipse-dataspacetck/dcp-tck?tab=readme-ov-file#232-required-configuration put("tx.edc.iam.dcp.default-scopes.holderIdentifier.alias", "org.eclipse.dspace.dcp.vc.type"); put("tx.edc.iam.dcp.default-scopes.holderIdentifier.type", "MembershipCredential"); diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java index 726bfe5219..0ff65e3652 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java @@ -142,7 +142,7 @@ void shouldNotImpersonateConsumer_withWrappedConsumerCredential() { var presentationService = STS_RUNTIME.getService(VerifiablePresentationService.class); - withMock((membershipCredential) -> presentationService.createPresentation(MALICIOUS_ACTOR.getDid(), List.of(membershipCredential.getVerifiableCredential()), null, PROVIDER.getDid())); + withMock((membershipCredential) -> presentationService.createPresentation(MALICIOUS_ACTOR.getParticipantContextId(), List.of(membershipCredential.getVerifiableCredential()), null, PROVIDER.getDid())); PROVIDER.createAsset(assetId, Map.of(), dataAddress); @@ -168,7 +168,7 @@ void shouldNotImpersonateConsumer_withConsumerPresentation() { var presentationService = STS_RUNTIME.getService(VerifiablePresentationService.class); - withMock((membershipCredential) -> presentationService.createPresentation(CONSUMER.getDid(), List.of(membershipCredential.getVerifiableCredential()), null, PROVIDER.getDid())); + withMock((membershipCredential) -> presentationService.createPresentation(CONSUMER.getParticipantContextId(), List.of(membershipCredential.getVerifiableCredential()), null, PROVIDER.getDid())); PROVIDER.createAsset(assetId, Map.of(), dataAddress); diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java index c015f4040c..952c5d8ece 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java @@ -133,6 +133,9 @@ static void prepare() { var generatorServices = Map.of( CONSUMER.getDid(), tokenServiceFor(consumerTokenGeneration, CONSUMER, CONSUMER_RUNTIME), PROVIDER.getDid(), tokenServiceFor(providerTokenGeneration, PROVIDER, PROVIDER_RUNTIME)); + var participantContextIds = Map.of( + CONSUMER.getDid(), CONSUMER.getParticipantContextId(), + PROVIDER.getDid(), PROVIDER.getParticipantContextId()); var stsUri = STS.stsUri().get(); @@ -141,7 +144,7 @@ static void prepare() { oauthServer.stubFor(post(urlPathEqualTo(stsUri.getPath() + "/token")).willReturn(aResponse().withStatus(200) .withBody(MAPPER.writeValueAsString(Map.of("access_token", "token"))))); - divServer = new WireMockServer(options().port(DIV_URI.get().getPort()).extensions(new DivDispatcher(generatorServices))); + divServer = new WireMockServer(options().port(DIV_URI.get().getPort()).extensions(new DivDispatcher(generatorServices, participantContextIds))); divServer.start(); divServer.stubFor(post(anyUrl()).willReturn(aResponse().withTransformers("div-dispatcher"))); @@ -172,10 +175,15 @@ private static EmbeddedSecureTokenService tokenServiceFor(TokenGenerationService }); var participantContextStore = runtime.getService(ParticipantContextStore.class); - participantContextStore.create(IdentityHubParticipantContext.Builder.newInstance() + var participantContext = IdentityHubParticipantContext.Builder.newInstance() .participantContextId(participant.getParticipantContextId()) .did(participant.getDid()) - .apiTokenAlias(participant.getParticipantContextId()).build()); + .apiTokenAlias(participant.getParticipantContextId()).build(); + var createResult = participantContextStore.create(participantContext); + if (createResult.failed()) { + participantContextStore.update(participantContext) + .orElseThrow(f -> new RuntimeException("Cannot update participant context: " + f.getFailureDetail())); + } var keyPairService = runtime.getService(KeyPairService.class); var keyDescriptor = participant.createKeyDescriptor(); diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/dispatchers/DivDispatcher.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/dispatchers/DivDispatcher.java index db4077246f..a3a346e1aa 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/dispatchers/DivDispatcher.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/dcp/dispatchers/DivDispatcher.java @@ -47,14 +47,16 @@ public class DivDispatcher implements ResponseTransformerV2 { private static final TypeManager MAPPER = new JacksonTypeManager(); private final String path; private final Map secureTokenServices; + private final Map participantContextIds; - public DivDispatcher(Map secureTokenServices) { - this("/", secureTokenServices); + public DivDispatcher(Map secureTokenServices, Map participantContextIds) { + this("/", secureTokenServices, participantContextIds); } - public DivDispatcher(String path, Map secureTokenServices) { + public DivDispatcher(String path, Map secureTokenServices, Map participantContextIds) { this.path = path; this.secureTokenServices = secureTokenServices; + this.participantContextIds = participantContextIds; } @Override @@ -97,7 +99,7 @@ private Response grantAccessHandler(Map params, Response base) { var claims = Map.of(ISSUER, issuer, SUBJECT, issuer, AUDIENCE, audience); var sts = secureTokenServices.get(issuer); - var token = sts.createToken(issuer, claims, scope) + var token = sts.createToken(participantContextId(issuer), claims, scope) .map(TokenRepresentation::getToken) .orElseThrow(f -> new RuntimeException(f.getFailureDetail())); @@ -113,7 +115,7 @@ private Response signTokenHandler(Map params, Response base) { var claims = Map.of(ISSUER, issuer, SUBJECT, subject, AUDIENCE, audience, PRESENTATION_TOKEN_CLAIM, accessToken); var sts = secureTokenServices.get(issuer); - var token = sts.createToken(issuer, claims, null) + var token = sts.createToken(participantContextId(issuer), claims, null) .map(TokenRepresentation::getToken) .orElseThrow(f -> new RuntimeException(f.getFailureDetail())); @@ -137,4 +139,8 @@ private Response notFound(Response base) { .body("") .build(); } + + private String participantContextId(String did) { + return participantContextIds.getOrDefault(did, did); + } } diff --git a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java b/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java index f2450f2114..3029fc4877 100644 --- a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java +++ b/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java @@ -19,12 +19,14 @@ package org.eclipse.tractusx.edc.tests.tck.dsp; +import org.eclipse.edc.connector.controlplane.policy.spi.store.PolicyArchive; import org.eclipse.edc.connector.controlplane.profile.DataspaceProfileContextRegistryImpl; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.EmbeddedRuntime; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.junit.extensions.RuntimePerClassExtension; import org.eclipse.edc.junit.testfixtures.TestUtils; +import org.eclipse.edc.policy.model.Policy; import org.eclipse.edc.protocol.spi.DataspaceProfileContextRegistry; import org.eclipse.edc.protocol.spi.ParticipantIdExtractionFunction; import org.eclipse.edc.spi.monitor.ConsoleMonitor; @@ -71,6 +73,7 @@ public class EdcCompatibilityPostgresTest { private static final URI DATA_PLANE_PUBLIC = URI.create("http://localhost:" + getFreePort() + "/public"); private static final String CONNECTOR_UNDER_TEST = "participantContextId"; private static final String BPN = BPN_PREFIX + CONNECTOR_UNDER_TEST; + private static final String TCK_PARTICIPANT = "TCK_PARTICIPANT"; private static final DataspaceProfileContextRegistry DATASPACE_PROFILE_CONTEXT_REGISTRY_SPY = spy(DataspaceProfileContextRegistryImpl.class); @@ -90,6 +93,21 @@ public AgreementsBpnsEntry findByAgreementId(String agreementId) { } }; + private static final PolicyArchive POLICY_ARCHIVE = new PolicyArchive() { + @Override + public Policy findPolicyForContract(String contractId) { + return Policy.Builder.newInstance() + .assigner(TCK_PARTICIPANT) + .assignee(TCK_PARTICIPANT) + .build(); + } + + @Override + public String getAgreementIdForContract(String contractId) { + return contractId; + } + }; + @RegisterExtension @Order(0) private static final PostgresExtension POSTGRES = new PostgresExtension(CONNECTOR_UNDER_TEST); @@ -99,10 +117,11 @@ public AgreementsBpnsEntry findByAgreementId(String agreementId) { ":edc-tests:runtime:runtime-dsp", ":edc-extensions:single-participant-vault") .registerServiceMock(BdrsClient.class, new MockBdrsClient(s -> s, s -> s)) .registerServiceMock(AgreementsBpnsStore.class, AGREEMENTS_BPNS_STORE) + .registerServiceMock(PolicyArchive.class, POLICY_ARCHIVE) .registerServiceMock(DataspaceProfileContextRegistry.class, DATASPACE_PROFILE_CONTEXT_REGISTRY_SPY) .configurationProvider(() -> EdcCompatibilityPostgresTest.runtimeConfiguration().merge(POSTGRES.getConfig(CONNECTOR_UNDER_TEST)))); - private static final GenericContainer TCK_CONTAINER = new TckContainer<>("eclipsedataspacetck/dsp-tck-runtime:1.0.0-RC4"); + private static final GenericContainer TCK_CONTAINER = new TckContainer<>("eclipsedataspacetck/dsp-tck-runtime:1.0.0-RC6"); @BeforeEach void setUp() { @@ -114,7 +133,7 @@ private static Config runtimeConfiguration() { return ConfigFactory.fromMap(new HashMap<>() { { put("edc.participant.id", BPN); - put("edc.participant.context.id", CONNECTOR_UNDER_TEST + "_context"); + put("edc.participant.context.id", CONNECTOR_UNDER_TEST); put("web.http.port", "8080"); put("web.http.path", "/api"); put("web.http.control.port", String.valueOf(CONTROL_URL.getPort())); @@ -183,4 +202,3 @@ private String resourceConfig(String resource) { return Path.of(TestUtils.getResource(resource)).toString(); } } - From 13f33785aa49d278c8e2ab081b0b67fb05a6a633 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:36:43 +0200 Subject: [PATCH 150/259] chore(deps): bump com.squareup.okhttp3:okhttp from 5.3.2 to 5.4.0 (#2888) Bumps [com.squareup.okhttp3:okhttp](https://github.com/square/okhttp) from 5.3.2 to 5.4.0. - [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/okhttp/compare/parent-5.3.2...parent-5.4.0) --- updated-dependencies: - dependency-name: com.squareup.okhttp3:okhttp dependency-version: 5.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 79595fd1d4..df7e93a21c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ jackson = "2.22.0" jakarta-json = "2.1.3" junit = "6.1.0" nimbus = "10.9.1" -okhttp = "5.3.2" +okhttp = "5.4.0" opentelemetry = "2.28.1" opentelemetry-instrumentation = "2.28.1" opentelemetry-log4j-appender = "2.28.1-alpha" From e42fd503a34dd42449e5665518b0967cb3338d18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:37:01 +0200 Subject: [PATCH 151/259] chore(deps): bump gradle/actions in /.github/actions/setup-java (#2893) Bumps [gradle/actions](https://github.com/gradle/actions) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/gradle/actions/releases) - [Commits](https://github.com/gradle/actions/compare/50e97c2cd7a37755bbfafc9c5b7cafaece252f6e...3f131e8634966bd73d06cc69884922b02e6faf92) --- updated-dependencies: - dependency-name: gradle/actions dependency-version: 6.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-java/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index 637050c67e..86c9321bc8 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -31,4 +31,4 @@ runs: java-version: '21' distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0 + uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0 From 4302b06a0da07b361b08963c3bef86652675bff2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:37:24 +0200 Subject: [PATCH 152/259] chore(deps): bump aws from 2.46.4 to 2.46.9 (#2889) Bumps `aws` from 2.46.4 to 2.46.9. Updates `software.amazon.awssdk:s3` from 2.46.4 to 2.46.9 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.46.4 to 2.46.9 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.46.9 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.46.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index df7e93a21c..f66da440e3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.2" awaitility = "4.3.0" -aws = "2.46.4" +aws = "2.46.9" azure-storage-blob = "12.34.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0" From 62980e006770356317c6ceed76f69689d8f382a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:38:33 +0200 Subject: [PATCH 153/259] chore(deps): bump com.networknt:json-schema-validator (#2892) Bumps [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) from 3.0.3 to 3.0.4. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/3.0.3...3.0.4) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-version: 3.0.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts index 962f2d397d..5c95eb6276 100644 --- a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts @@ -43,7 +43,7 @@ dependencies { } constraints { - implementation("com.networknt:json-schema-validator:3.0.3") { + implementation("com.networknt:json-schema-validator:3.0.4") { because("older versions cause runtime issues") } } From 905d6abd23f3035ed9e3727bab1bba8747af6e2e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:38:52 +0200 Subject: [PATCH 154/259] chore(deps): bump flyway from 12.8.0 to 12.8.1 (#2890) Bumps `flyway` from 12.8.0 to 12.8.1. Updates `org.flywaydb:flyway-core` from 12.8.0 to 12.8.1 Updates `org.flywaydb:flyway-database-postgresql` from 12.8.0 to 12.8.1 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.8.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.8.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f66da440e3..bae83747d6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ azure-storage-blob = "12.34.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0" dsp-tck = "1.0.0-RC6" -flyway = "12.8.0" +flyway = "12.8.1" jackson = "2.22.0" jakarta-json = "2.1.3" junit = "6.1.0" From 6ffe918acc94174d55650ef5244449ec6eb157d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:39:14 +0200 Subject: [PATCH 155/259] chore(deps): bump mikefarah/yq (#2894) Bumps [mikefarah/yq](https://github.com/mikefarah/yq) from 4.53.2 to 4.53.3. - [Release notes](https://github.com/mikefarah/yq/releases) - [Changelog](https://github.com/mikefarah/yq/blob/master/release_notes.txt) - [Commits](https://github.com/mikefarah/yq/compare/751d8ad57b84f1794661bc70c0afb92a22ad7b3c...1b9b4ac5187171d2e5e3129be0cfa827c7f9d53d) --- updated-dependencies: - dependency-name: mikefarah/yq dependency-version: 4.53.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/update-version-and-charts/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/update-version-and-charts/action.yml b/.github/actions/update-version-and-charts/action.yml index b17e580357..bc1536a34f 100644 --- a/.github/actions/update-version-and-charts/action.yml +++ b/.github/actions/update-version-and-charts/action.yml @@ -45,7 +45,7 @@ runs: fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" - name: Bump version in /charts - uses: mikefarah/yq@751d8ad57b84f1794661bc70c0afb92a22ad7b3c # v4.53.2 + uses: mikefarah/yq@1b9b4ac5187171d2e5e3129be0cfa827c7f9d53d # v4.53.3 env: RESOLVED_VERSION: ${{ steps.resolver.outputs.version }} with: From 0e38027d86d8361bb6316f0aa655364ec2d1a96a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:39:48 +0200 Subject: [PATCH 156/259] chore(deps): bump com.azure:azure-storage-blob from 12.34.0 to 12.35.0 (#2891) Bumps [com.azure:azure-storage-blob](https://github.com/Azure/azure-sdk-for-java) from 12.34.0 to 12.35.0. - [Release notes](https://github.com/Azure/azure-sdk-for-java/releases) - [Commits](https://github.com/Azure/azure-sdk-for-java/compare/com.azure+azure-storage-blob_12.34.0...com.azure+azure-storage-blob_12.35.0) --- updated-dependencies: - dependency-name: com.azure:azure-storage-blob dependency-version: 12.35.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bae83747d6..6680a330bf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ edc-build = "1.5.2" allure = "2.35.2" awaitility = "4.3.0" aws = "2.46.9" -azure-storage-blob = "12.34.0" +azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.0" dsp-tck = "1.0.0-RC6" From c0654460e99330533ef409fb9084d60db27b8d74 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Fri, 19 Jun 2026 12:26:54 +0200 Subject: [PATCH 157/259] feat: dsp dcp tck update (#2887) * feat: bump dsc/dcp tcks to 1.0.0 * feat: bump dsc/dcp tcks to 1.0.0 * feat: bump dsc/dcp tcks to 1.0.0 --- edc-tests/e2e/dcp-tck-tests/build.gradle.kts | 4 ++-- .../edc/tests/tck/dcp/DcpPresentationFlowTest.java | 4 +++- .../build.gradle.kts | 4 ++-- .../tests/tck/dsp/EdcCompatibilityPostgresTest.java | 8 +++++--- .../tractusx/edc/tests/tck/dsp/TckContainer.java | 0 .../tractusx/edc/tests/tck/dsp/TckTestReporter.java | 0 .../src/test/resources/docker.tck.properties | 0 edc-tests/runtime/runtime-dcp-tck/build.gradle.kts | 1 - gradle/libs.versions.toml | 10 ++++++++-- settings.gradle.kts | 2 +- 10 files changed, 21 insertions(+), 12 deletions(-) rename edc-tests/e2e/{dsp-compatibility-tests => dsp-tck-tests}/build.gradle.kts (94%) rename edc-tests/e2e/{dsp-compatibility-tests => dsp-tck-tests}/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java (97%) rename edc-tests/e2e/{dsp-compatibility-tests => dsp-tck-tests}/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckContainer.java (100%) rename edc-tests/e2e/{dsp-compatibility-tests => dsp-tck-tests}/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckTestReporter.java (100%) rename edc-tests/e2e/{dsp-compatibility-tests => dsp-tck-tests}/src/test/resources/docker.tck.properties (100%) diff --git a/edc-tests/e2e/dcp-tck-tests/build.gradle.kts b/edc-tests/e2e/dcp-tck-tests/build.gradle.kts index bbd70097bc..842ae348d0 100644 --- a/edc-tests/e2e/dcp-tck-tests/build.gradle.kts +++ b/edc-tests/e2e/dcp-tck-tests/build.gradle.kts @@ -31,9 +31,9 @@ dependencies { testImplementation(libs.nimbus.jwt) testImplementation(libs.restAssured) - testImplementation(libs.dsp.tck.runtime) + testImplementation(libs.tck.runtime) testImplementation(libs.dcp.system) - testImplementation(libs.dsp.tck.core) + testImplementation(libs.tck.core) testImplementation(libs.wiremock) testImplementation(libs.junit.platform.launcher) testImplementation(libs.testcontainers.junit) diff --git a/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java b/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java index c4257ebc5d..2c8d99e3ae 100644 --- a/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java +++ b/edc-tests/e2e/dcp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dcp/DcpPresentationFlowTest.java @@ -94,7 +94,9 @@ public class DcpPresentationFlowTest { @RegisterExtension static final RuntimePerClassExtension RUNTIME = new RuntimePerClassExtension( - new EmbeddedRuntime("Connector-under-test", ":edc-tests:runtime:runtime-dcp-tck") + new EmbeddedRuntime("Connector-under-test", + ":edc-tests:runtime:runtime-dcp-tck", + ":edc-extensions:single-participant-vault") .registerServiceMock(SecureTokenService.class, STS_MOCK) .registerServiceMock(DataspaceProfileContextRegistry.class, DATASPACE_PROFILE_CONTEXT_REGISTRY_SPY) .registerServiceMock(BdrsClient.class, new MockBdrsClient((s) -> s, (s) -> s)) diff --git a/edc-tests/e2e/dsp-compatibility-tests/build.gradle.kts b/edc-tests/e2e/dsp-tck-tests/build.gradle.kts similarity index 94% rename from edc-tests/e2e/dsp-compatibility-tests/build.gradle.kts rename to edc-tests/e2e/dsp-tck-tests/build.gradle.kts index 1a75639378..d81f490f4b 100644 --- a/edc-tests/e2e/dsp-compatibility-tests/build.gradle.kts +++ b/edc-tests/e2e/dsp-tck-tests/build.gradle.kts @@ -27,8 +27,8 @@ dependencies { testImplementation(libs.edc.core.controlplane) testImplementation(libs.awaitility) testImplementation(libs.testcontainers.junit) - testImplementation(libs.dsp.tck.core) - testImplementation(libs.dsp.tck.runtime) + testImplementation(libs.tck.core) + testImplementation(libs.tck.runtime) testImplementation(libs.dsp.tck.api) testImplementation(libs.dsp.tck.system) testRuntimeOnly(libs.dsp.tck.metadata) diff --git a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java b/edc-tests/e2e/dsp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java similarity index 97% rename from edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java rename to edc-tests/e2e/dsp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java index 3029fc4877..9b66ddb281 100644 --- a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java +++ b/edc-tests/e2e/dsp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/EdcCompatibilityPostgresTest.java @@ -114,14 +114,15 @@ public String getAgreementIdForContract(String contractId) { @RegisterExtension private static final RuntimeExtension RUNTIME = new RuntimePerClassExtension(new EmbeddedRuntime(CONNECTOR_UNDER_TEST, - ":edc-tests:runtime:runtime-dsp", ":edc-extensions:single-participant-vault") + ":edc-tests:runtime:runtime-dsp", + ":edc-extensions:single-participant-vault") .registerServiceMock(BdrsClient.class, new MockBdrsClient(s -> s, s -> s)) .registerServiceMock(AgreementsBpnsStore.class, AGREEMENTS_BPNS_STORE) .registerServiceMock(PolicyArchive.class, POLICY_ARCHIVE) .registerServiceMock(DataspaceProfileContextRegistry.class, DATASPACE_PROFILE_CONTEXT_REGISTRY_SPY) .configurationProvider(() -> EdcCompatibilityPostgresTest.runtimeConfiguration().merge(POSTGRES.getConfig(CONNECTOR_UNDER_TEST)))); - private static final GenericContainer TCK_CONTAINER = new TckContainer<>("eclipsedataspacetck/dsp-tck-runtime:1.0.0-RC6"); + private static final GenericContainer TCK_CONTAINER = new TckContainer<>("eclipsedataspacetck/dsp-tck-runtime:1.0.0"); @BeforeEach void setUp() { @@ -148,7 +149,7 @@ private static Config runtimeConfiguration() { put("edc.dsp.callback.address", PROTOCOL_URL.toString()); // host.docker.internal is required by the container to communicate with the host put("edc.management.context.enabled", "true"); put("edc.hostname", "host.docker.internal"); - put("edc.component.id", "DSP-compatibility-test"); + put("edc.component.id", "DSP-tck-test"); put("edc.transfer.proxy.token.signer.privatekey.alias", "private-key"); put("edc.transfer.proxy.token.verifier.publickey.alias", "public-key"); put("edc.policy.validation.enabled", "true"); @@ -202,3 +203,4 @@ private String resourceConfig(String resource) { return Path.of(TestUtils.getResource(resource)).toString(); } } + diff --git a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckContainer.java b/edc-tests/e2e/dsp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckContainer.java similarity index 100% rename from edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckContainer.java rename to edc-tests/e2e/dsp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckContainer.java diff --git a/edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckTestReporter.java b/edc-tests/e2e/dsp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckTestReporter.java similarity index 100% rename from edc-tests/e2e/dsp-compatibility-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckTestReporter.java rename to edc-tests/e2e/dsp-tck-tests/src/test/java/org/eclipse/tractusx/edc/tests/tck/dsp/TckTestReporter.java diff --git a/edc-tests/e2e/dsp-compatibility-tests/src/test/resources/docker.tck.properties b/edc-tests/e2e/dsp-tck-tests/src/test/resources/docker.tck.properties similarity index 100% rename from edc-tests/e2e/dsp-compatibility-tests/src/test/resources/docker.tck.properties rename to edc-tests/e2e/dsp-tck-tests/src/test/resources/docker.tck.properties diff --git a/edc-tests/runtime/runtime-dcp-tck/build.gradle.kts b/edc-tests/runtime/runtime-dcp-tck/build.gradle.kts index d9709c62dd..0d0f8ba203 100644 --- a/edc-tests/runtime/runtime-dcp-tck/build.gradle.kts +++ b/edc-tests/runtime/runtime-dcp-tck/build.gradle.kts @@ -27,7 +27,6 @@ dependencies { implementation(project(":edc-controlplane:edc-controlplane-base")) { exclude(module = "cx-dcp") } - implementation(project(":edc-extensions:single-participant-vault")) } application { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6680a330bf..20c5c2b5e1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,8 +9,9 @@ awaitility = "4.3.0" aws = "2.46.9" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" -dcp-tck = "1.0.0" -dsp-tck = "1.0.0-RC6" +dcp-tck = "1.0.1" +dsp-tck = "1.0.0" +common-tck = "1.0.0" flyway = "12.8.1" jackson = "2.22.0" jakarta-json = "2.1.3" @@ -163,6 +164,11 @@ edc-verifiablecredentials-jwt = { module = "org.eclipse.edc:jwt-verifiable-crede dcp-testcases = { module = "org.eclipse.dataspacetck.dcp:dcp-testcases", version.ref = "dcp-tck" } dcp-system = { module = "org.eclipse.dataspacetck.dcp:dcp-system", version.ref = "dcp-tck" } +# Common-TCK libraries +tck-runtime = { module = "org.eclipse.dataspacetck.common:tck-runtime", version.ref = "common-tck" } +tck-core = { module = "org.eclipse.dataspacetck.common:core", version.ref = "common-tck" } + + # DSP-TCK libraries dsp-tck-runtime = { module = "org.eclipse.dataspacetck.dsp:tck-runtime", version.ref = "dsp-tck" } dsp-tck-core = { module = "org.eclipse.dataspacetck.dsp:core", version.ref = "dsp-tck" } diff --git a/settings.gradle.kts b/settings.gradle.kts index e105e220d8..226c371f52 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -141,7 +141,7 @@ include(":edc-tests:e2e:policy-tests") include(":edc-tests:e2e:transfer-tests") include("edc-tests:e2e:discovery-tests") include(":edc-tests:e2e:dcp-tck-tests") -include(":edc-tests:e2e:dsp-compatibility-tests") +include(":edc-tests:e2e:dsp-tck-tests") include(":edc-tests:compatibility-tests") include(":edc-tests:runtime:dataplane-cloud") include(":edc-tests:runtime:runtime-dsp") From b9bc6c9734c7807c9a878608422612faa51b4834 Mon Sep 17 00:00:00 2001 From: HKit-HTW Date: Fri, 19 Jun 2026 12:28:01 +0200 Subject: [PATCH 158/259] =?UTF-8?q?docs:=20update=20policy=20API=20walkthr?= =?UTF-8?q?ough,=20fix=20errors=20and=20add=20usage=20policy=20=E2=80=A6?= =?UTF-8?q?=20(#2875)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: update policy API walkthrough, fix errors and add usage policy constraints * 02_policies.md: removed wrong identifier Co-authored-by: Lars Geyer-Blaumeiser * 02_policies.md: removed obsolete scenario and fixed "isAnyOf" rightOperator to a valid array * 02_policies.md: added missing constraints * 02_policies.md: removed outdated constraint --------- Co-authored-by: Hans Kittelmann Co-authored-by: Lars Geyer-Blaumeiser --- .../management-api-walkthrough/02_policies.md | 165 ++++++------------ 1 file changed, 57 insertions(+), 108 deletions(-) diff --git a/docs/usage/management-api-walkthrough/02_policies.md b/docs/usage/management-api-walkthrough/02_policies.md index 4e948f5be7..f3ebd6bb47 100644 --- a/docs/usage/management-api-walkthrough/02_policies.md +++ b/docs/usage/management-api-walkthrough/02_policies.md @@ -39,34 +39,33 @@ please refer to the CX-0152 standard [appendix](https://catenax-ev.github.io/doc | Name | Action | usable in | side-effects | |-----------------------------------|-----------------|-----------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------| -| `BusinessPartnerGroup` | `access` | `permission` | validated against the identity extracted from the `MembershipCredential` | -| `BusinessPartnerNumber` | `access` | `permission` | validated against the identity extracted from the `MembershipCredential` | -| `FrameworkAgreement` | `access`, `use` | `permission` | | -| `Membership` | `access`, `use` | `permission` | validated against the `MembershipCredential` | -| `inForceDate` | `access`, `use` | `permission` | validated continuously - all Transfer Processes relying on an Agreement with this Constraint will be stopped when `inForceDate` is exceeded. | -| `AffiliatesRegion` | `use` | `permission`, `prohibition` | | | `AffiliatesBpnl` | `use` | `permission`, `prohibition` | | -| `DataFrequency` | `use` | `permission` | | -| `VersionChanges` | `use` | `permission` | | -| `ContractTermination` | `use` | `permission` | | +| `AffiliatesRegion` | `use` | `permission`, `prohibition` | | +| `BusinessPartnerGroup` | `access` | `permission` | validated against the identity extracted from the `MembershipCredential` | +| `BusinessPartnerNumber` | `access` | `permission` | validated against the identity extracted from the `MembershipCredential` -> `BpnCredential` | | `ConfidentialInformationMeasures` | `use` | `permission` | | | `ConfidentialInformationSharing` | `use` | `permission` | | -| `ExclusiveUsage` | `use` | `permission` | | -| `Warranty` | `use` | `permission` | | -| `WarrantyDefinition` | `use` | `permission` | | -| `WarrantyDurationMonths` | `use` | `permission` | | -| `Liability` | `use` | `permission` | | -| `JurisdictionLocationReference` | `use` | `permission` | | -| `JurisdictionLocation` | `use` | `permission` | | -| `Precedence` | `use` | `permission` | | -| `DataUsageEndDurationDays` | `use` | `permission` | | +| `ContractReference` | `use` | `permission` | | +| `ContractTermination` | `use` | `permission` | | +| `DataFrequency` | `use` | `permission` | | | `DataUsageEndDate` | `use` | `permission` | | | `DataUsageEndDefinition` | `use` | `permission` | | -| `DataUsageEndDate` | `use` | `permission` | | -| `DataUsageEndDate` | `use` | `permission` | | +| `DataUsageEndDurationDays` | `use` | `permission` | | | `DataProvisioningEndDurationDays` | `use` | `obligation` | | | `DataProvisioningEndDate` | `use` | `obligation` | | +| `ExclusiveUsage` | `use` | `permission` | | +| `FrameworkAgreement` | `access`, `use` | `permission` | | +| `JurisdictionLocation` | `use` | `permission` | | +| `JurisdictionLocationReference` | `use` | `permission` | | +| `Liability` | `use` | `permission` | | +| `Membership` | `access`, `use` | `permission` | validated against the `MembershipCredential` | +| `Precedence` | `use` | `permission` | | +| `UsagePurpose` | `use` | `permission` | | | `UsageRestriction` | `use` | `prohibition` | | +| `VersionChanges` | `use` | `permission` | | +| `Warranty` | `use` | `permission` | | +| `WarrantyDefinition` | `use` | `permission` | | +| `WarrantyDurationMonths` | `use` | `permission` | | ### Policies & Verifiable Credentials (VC) @@ -93,6 +92,19 @@ In EDC, a distinction is made between **Access** and **Usage** Policies. Whether a policy is used as access or usage policy is determined during [contract definition](03_contractdefinitions.md). +#### Mandatory Constraints for Usage Policies + +In the Catena-X dataspace, a usage policy must always contain at least the following two constraints: + +- **`FrameworkAgreement`:** Specifies the data exchange governance framework the consumer must have agreed to (e.g. `DataExchangeGovernance:1.0`). +- **`UsagePurpose`:** Defines the permitted purposes for which the data may be used (e.g. `cx.core.qualityNotifications:1`). + +Both constraints must be combined using an `and` conjunction. + +> **Note:** Policies that do not include both `FrameworkAgreement` and `UsagePurpose` constraints will not be +> accepted in the Catena-X dataspace. Additional constraints may be added depending on the use case. + + ### Creating a Policy Definition Policies can be created in the Connector as follows: @@ -148,7 +160,7 @@ or the [json-ld playground](https://json-ld.org/playground/) helps to be consist If the creation of the `policydefinition` was successful, the Management-API will return HTTP 201. -## Exemplary scenarios +## Exemplary scenario For the following Scenarios, we assume there is a **Partner 1 (provider)** who wants to provide Data for **Partner 2 (consumer)** @@ -156,7 +168,7 @@ For the following Scenarios, we assume there is a **Partner 1 (provider)** who w - Partner 1 (provider) has the Business-Partner-Number BPN12345. - Partner 2 (consumer) has the Business-Partner-Number BPN6789. -Partner 2 (consumer) signed the **Traceability Framework Agreement** and followed all the necessary steps that the +Partner 2 (consumer) signed the **Framework Agreement** and followed all the necessary steps that the Credential appears within Partner 2s identity. When doing a catalog request with @@ -187,18 +199,11 @@ For example: } ``` -For other subsequent requests like Contract negotiation requests and transfer process requests, the presented -credentials are based on the usage/contract policy. This means VC based policies can be used only -in the usage/contract policy. - -#### Scenario 1 +#### Scenario -Partner 1 wants to create an Access Policy, that Partner 2 can receive the Contract Offer if its BPN matches. But a -Contract Agreement should only be created if Partner 2 also signed the Traceability Framework Agreement. So in this -case, Partner 2 should receive the Contract Offer in the first place, regardless if it signed the Traceability Framework -Agreement. The signing of the Agreement should be checked at the time of contract negotiation. +Partner 1 wants to create an Access Policy, that Partner 2 can receive the Contract Offer if its BPN matches. But a Contract Agreement should only be created if Partner 2 also signed the Framework Agreement. So in this case, Partner 2 should receive the Contract Offer in the first place, regardless if it signed the Framework Agreement. The signing of the Agreement should be checked at the time of contract negotiation. -##### Partner 1 - Access Policy Example (Scenario 1) +##### Partner 1 - Access Policy Example ```json { @@ -218,8 +223,8 @@ Agreement. The signing of the Agreement should be checked at the time of contrac "action": "access", "constraint": { "leftOperand": "BusinessPartnerNumber", - "operator": "eq", - "rightOperand": "BPN6789" + "operator": "isAnyOf", + "rightOperand": ["BPN6789", "..."] } } ] @@ -227,7 +232,7 @@ Agreement. The signing of the Agreement should be checked at the time of contrac } ``` -##### Partner 1 - Usage/Contract Policy Example (Scenario 1) +##### Partner 1 - Usage/Contract Policy Example ```json { @@ -246,9 +251,18 @@ Agreement. The signing of the Agreement should be checked at the time of contrac { "action": "use", "constraint": { - "leftOperand": "FrameworkAgreement", - "operator": "eq", - "rightOperand": "DataExchangeGovernance:1.0" + "and": [ + { + "leftOperand": "FrameworkAgreement", + "operator": "eq", + "rightOperand": "DataExchangeGovernance:1.0" + }, + { + "leftOperand": "UsagePurpose", + "operator": "isAnyOf", + "rightOperand": [""] + } + ] } } ] @@ -256,81 +270,16 @@ Agreement. The signing of the Agreement should be checked at the time of contrac } ``` -##### Desired Outcome (Scenario 1) +> **Note:** The Access Policy only checks the BPN at catalog request time. The `FrameworkAgreement` and +> `UsagePurpose` constraints in the Usage Policy are evaluated during contract negotiation. If either +> constraint is not satisfied, the negotiation will be rejected. + +##### Desired Outcome Partner 2 receives the Contract Offer and is able to negotiate the contract because he presents a valid `DataExchangeGovernanceCredential`. -#### Scenario 2 - -Partner 1 wants to create an Access Policy that Partner 2 can receive the Contract Offer if the BPN is matching -but a Contract Agreement should only be created if Partner 2 is identified as a Dismantler (owns the " -DismantlerCredential"). - -##### Partner 1 - Access Policy Example (Scenario 2) - -```json -{ - "@context": [ - "https://w3id.org/dspace/2025/1/odrl-profile.jsonld", - "https://w3id.org/catenax/2025/9/policy/context.jsonld", - { - "@vocab": "https://w3id.org/edc/v0.0.1/ns/" - } - ], - "@type": "PolicyDefinition", - "@id": "{{POLICY_ID}}", - "policy": { - "@type": "Set", - "permission": [ - { - "action": "use", - "constraint": { - "leftOperand": "BusinessPartnerNumber", - "operator": "eq", - "rightOperand": "BPN6789" - } - } - ] - } -} -``` - -##### Partner 1 - Usage/Contract Policy Example (Scenario 2) - -```json -{ - "@context": [ - "https://w3id.org/dspace/2025/1/odrl-profile.jsonld", - "https://w3id.org/catenax/2025/9/policy/context.jsonld", - { - "@vocab": "https://w3id.org/edc/v0.0.1/ns/" - } - ], - "@type": "PolicyDefinition", - "@id": "{{POLICY_ID}}", - "policy": { - "@type": "Set", - "permission": [ - { - "action": "use", - "constraint": { - "leftOperand": "Dismantler", - "operator": "eq", - "rightOperand": "active" - } - } - ] - } -} -``` - -##### Desired Outcome (Scenario 2) - -Partner 2 receives the Contract Offer in the first place. -The contract negotiation, started by Partner 2 fails because he has not been identified as Dismantler and therefore does -not own the Dismantler Credential. #### Writing Policies for the Connector From 573151bfc97f44ebf68f6f064ffa3612d8b38cc9 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Wed, 24 Jun 2026 19:18:59 +0200 Subject: [PATCH 159/259] Fix: Make refresh use body as specified in rfc6749 (#2897) * Make refresh use body as specified in rfc Signed-off-by: Lars Geyer-Blaumeiser * Update todo comment for later removal of legacy Signed-off-by: Lars Geyer-Blaumeiser * Checkstyle issues Signed-off-by: Lars Geyer-Blaumeiser --------- Signed-off-by: Lars Geyer-Blaumeiser --- .../tokenrefresh/api/v1/TokenRefreshApi.java | 7 ++- .../api/v1/TokenRefreshApiController.java | 51 ++++++++++++++++--- .../api/v1/TokenRefreshApiControllerTest.java | 34 ++++++++----- .../tokenrefresh/TokenRefreshHandlerImpl.java | 14 ++++- .../TokenRefreshHandlerImplTest.java | 15 +++++- .../DataPlaneTokenRefreshEndToEndTest.java | 50 +++++++++--------- .../tests/edrv2/EdrCacheApiEndToEndTest.java | 43 ++++++++-------- 7 files changed, 140 insertions(+), 74 deletions(-) diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApi.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApi.java index 6d506b7193..9822c0dd89 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApi.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApi.java @@ -21,12 +21,12 @@ import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityScheme; import io.swagger.v3.oas.annotations.tags.Tag; @@ -43,8 +43,7 @@ public interface TokenRefreshApi { @Operation(description = "Resolves all groups for a particular BPN", - parameters = { @Parameter(name = "grant_type", description = "The grant type. Must be \"refresh_token\""), - @Parameter(name = "refresh_token", description = "The refresh token") }, + requestBody = @RequestBody(description = "Form parameters: grant_type=refresh_token&refresh_token="), responses = { @ApiResponse(responseCode = "200", description = "The access token and refresh token were updated. Expiry should be " + "interpreted as starting from the time of message reception, allowing for some leeway.", @@ -54,5 +53,5 @@ public interface TokenRefreshApi { @ApiResponse(responseCode = "400", description = "Request body was malformed, query parameters were missing, etc.", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) }) - TokenResponse refreshToken(String grantType, String refreshToken, String bearerToken); + TokenResponse refreshToken(String grantType, String refreshToken, String bearerToken, String formParameters); } diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiController.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiController.java index ce0c468d23..8c2635e828 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiController.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiController.java @@ -19,6 +19,7 @@ package org.eclipse.tractusx.edc.dataplane.tokenrefresh.api.v1; +import io.swagger.v3.oas.annotations.parameters.RequestBody; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.HeaderParam; import jakarta.ws.rs.POST; @@ -32,12 +33,16 @@ import org.eclipse.tractusx.edc.spi.tokenrefresh.dataplane.DataPlaneTokenRefreshService; import org.eclipse.tractusx.edc.spi.tokenrefresh.dataplane.model.TokenResponse; +import java.util.HashMap; +import java.util.Map; + import static jakarta.ws.rs.core.HttpHeaders.AUTHORIZATION; @Produces({ MediaType.APPLICATION_JSON }) @Path("/token") public class TokenRefreshApiController implements TokenRefreshApi { - private static final String REFRESH_TOKEN_GRANT = "refresh_token"; + private static final String GRANT_TYPE = "grant_type"; + private static final String REFRESH_TOKEN = "refresh_token"; private final DataPlaneTokenRefreshService tokenRefreshService; public TokenRefreshApiController(DataPlaneTokenRefreshService tokenRefreshService) { @@ -47,20 +52,50 @@ public TokenRefreshApiController(DataPlaneTokenRefreshService tokenRefreshServic @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Override - public TokenResponse refreshToken(@QueryParam("grant_type") String grantType, - @QueryParam("refresh_token") String refreshToken, - @HeaderParam(AUTHORIZATION) String bearerToken) { - if (!REFRESH_TOKEN_GRANT.equals(grantType)) { - throw new InvalidRequestException("Grant type MUST be '%s' but was '%s'".formatted(REFRESH_TOKEN_GRANT, grantType)); + public TokenResponse refreshToken(@QueryParam(GRANT_TYPE) String grantType, + @QueryParam(REFRESH_TOKEN) String refreshToken, + @HeaderParam(AUTHORIZATION) String bearerToken, + @RequestBody() String formParams) { + // TODO: This version still supports the deprecated usage of query parameter to provide the + // grant_type and refresh_token. This is due to backward compatibility to ensure interoperability + // with previous versions. This should be removed in the future, if old connectors are not used + // anymore. + + var paramMap = parseFormParameter(formParams); + if (!paramMap.containsKey(GRANT_TYPE)) { + paramMap.put(GRANT_TYPE, grantType); + } + if (!paramMap.containsKey(REFRESH_TOKEN)) { + paramMap.put(REFRESH_TOKEN, refreshToken); + } + + if (!REFRESH_TOKEN.equals(paramMap.get(GRANT_TYPE))) { + throw new InvalidRequestException("Grant type MUST be '%s' but was '%s'".formatted(REFRESH_TOKEN, paramMap.get(GRANT_TYPE))); } - if (StringUtils.isNullOrBlank(refreshToken)) { + if (StringUtils.isNullOrBlank(paramMap.get(REFRESH_TOKEN))) { throw new InvalidRequestException("Parameter 'refresh_token' cannot be null"); } if (StringUtils.isNullOrBlank(bearerToken)) { throw new AuthenticationFailedException("Authorization header missing"); } - return tokenRefreshService.refreshToken(refreshToken, bearerToken) + return tokenRefreshService.refreshToken(paramMap.get(REFRESH_TOKEN), bearerToken) .orElseThrow(f -> new AuthenticationFailedException(f.getFailureDetail())); } + + private Map parseFormParameter(String formParams) { + var result = new HashMap(); + if (!StringUtils.isNullOrBlank(formParams)) { + var params = formParams.split("&"); + for (String param : params) { + if (!StringUtils.isNullOrBlank(param)) { + var keyValuePair = param.split("="); + if (keyValuePair.length == 2) { + result.put(keyValuePair[0], keyValuePair[1]); + } + } + } + } + return result; + } } diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiControllerTest.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiControllerTest.java index d8fc82d13c..cc76aa7b93 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiControllerTest.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiControllerTest.java @@ -35,6 +35,7 @@ import static io.restassured.RestAssured.given; import static jakarta.ws.rs.core.HttpHeaders.AUTHORIZATION; +import static java.lang.String.format; import static org.hamcrest.Matchers.containsString; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -48,17 +49,16 @@ class TokenRefreshApiControllerTest extends RestControllerTestBase { @Test void refresh_noAuthHeader_expect401() { baseRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", "foo-token") /* missing: .header(AUTHORIZATION, "auth-token") */ .contentType(ContentType.URLENC) + .body("grant_type=refresh_token&refresh_token=foo-token") .then() .statusCode(401); } - @DisplayName("Expect HTTP 200 when the token was successfully refreshed") + @DisplayName("Expect HTTP 200 when the token was successfully refreshed and query params used") @Test - void refresh_expect200() { + void refresh_expect200query() { when(refreshService.refreshToken(any(), any())).thenReturn(Result.success(new TokenResponse("new-accesstoken", "new-refreshtoken", 3000L, "bearer"))); baseRequest() .queryParam("grant_type", "refresh_token") @@ -70,16 +70,28 @@ void refresh_expect200() { .body(Matchers.isA(TokenResponse.class)); } + @DisplayName("Expect HTTP 200 when the token was successfully refreshed and correct body used") + @Test + void refresh_expect200body() { + when(refreshService.refreshToken(any(), any())).thenReturn(Result.success(new TokenResponse("new-accesstoken", "new-refreshtoken", 3000L, "bearer"))); + baseRequest() + .header(AUTHORIZATION, "auth-token") + .contentType(ContentType.URLENC) + .body("grant_type=refresh_token&refresh_token=foo-token") + .then() + .statusCode(200) + .body(Matchers.isA(TokenResponse.class)); + } + @DisplayName("Expect HTTP 400 when an invalid grant type was provided") @ParameterizedTest(name = "Invalid grant_type: {0}") @ValueSource(strings = { "REFRESH_TOKEN", "refreshToken", "invalid_grant", "client_credentials", "" }) @NullSource void refresh_invalidGrantType_expect400(String grant) { baseRequest() - .queryParam("grant_type", grant) - .queryParam("refresh_token", "foo-token") .header(AUTHORIZATION, "auth-token") .contentType(ContentType.URLENC) + .body(format("grant_type=%s&refresh_token=foo-token", grant)) .then() .statusCode(400); } @@ -90,10 +102,9 @@ void refresh_invalidGrantType_expect400(String grant) { @EmptySource void refresh_invalidRefreshToken_expect400(String refreshToken) { baseRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) .header(AUTHORIZATION, "auth-token") .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .then() .statusCode(400); } @@ -102,16 +113,16 @@ void refresh_invalidRefreshToken_expect400(String refreshToken) { @Test void refresh_queryParamsMissing() { baseRequest() - .queryParam("grant_type", "refresh_token") .header(AUTHORIZATION, "auth-token") .contentType(ContentType.URLENC) + .body("grant_type=refresh_token") .then() .statusCode(400); baseRequest() - .queryParam("refresh_token", "foo-token") .header(AUTHORIZATION, "auth-token") .contentType(ContentType.URLENC) + .body("refresh_token=foo-token") .then() .statusCode(400); } @@ -122,10 +133,9 @@ void refresh_tokenInvalid_expect401() { when(refreshService.refreshToken(any(), any())).thenReturn(Result.failure("Invalid auth token")); baseRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", "foo-token") .header(AUTHORIZATION, "auth-token") .contentType(ContentType.URLENC) + .body("grant_type=refresh_token&refresh_token=foo-token") .then() .statusCode(401) .body(containsString("Invalid auth token")); diff --git a/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImpl.java b/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImpl.java index c203286dd5..89cb1d627e 100644 --- a/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImpl.java +++ b/edc-extensions/tokenrefresh-handler/src/main/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImpl.java @@ -20,9 +20,9 @@ package org.eclipse.tractusx.edc.common.tokenrefresh; import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.FormBody; import okhttp3.HttpUrl; import okhttp3.Request; -import okhttp3.RequestBody; import org.eclipse.edc.edr.spi.store.EndpointDataReferenceCache; import org.eclipse.edc.http.spi.EdcHttpClient; import org.eclipse.edc.iam.decentralizedclaims.spi.SecureTokenService; @@ -192,17 +192,27 @@ private Result createTokenRefreshRequest(String refreshEndpoint, String if (!refreshEndpoint.endsWith("/token")) { refreshEndpoint += "/token"; } + + // TODO: This version still supports the deprecated usage of query parameter to provide the + // grant_type and refresh_token. This is due to backward compatibility to ensure interoperability + // with previous versions. This should be removed in the future, if old connectors are not used + // anymore. var url = HttpUrl.parse(refreshEndpoint) .newBuilder() .addQueryParameter("grant_type", "refresh_token") .addQueryParameter("refresh_token", refreshToken) .build(); + var body = new FormBody.Builder() + .add("grant_type", "refresh_token") + .add("refresh_token", refreshToken) + .build(); + return success(new Request.Builder() .addHeader("Authorization", bearerToken) .addHeader("Content-Type", "application/x-www-form-urlencoded") .url(url) - .post(RequestBody.create(new byte[0])) + .post(body) .build()); } diff --git a/edc-extensions/tokenrefresh-handler/src/test/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImplTest.java b/edc-extensions/tokenrefresh-handler/src/test/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImplTest.java index 610494beb3..49d242121c 100644 --- a/edc-extensions/tokenrefresh-handler/src/test/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImplTest.java +++ b/edc-extensions/tokenrefresh-handler/src/test/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImplTest.java @@ -34,6 +34,7 @@ import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; +import okio.Buffer; import org.assertj.core.api.Assertions; import org.eclipse.edc.edr.spi.store.EndpointDataReferenceCache; import org.eclipse.edc.http.spi.EdcHttpClient; @@ -128,7 +129,19 @@ void refresh_validateCorrectRequest() throws IOException { }); verify(mockedHttpClient).execute(argThat(r -> { var hdr = r.header("Content-Type"); - return hdr != null && hdr.equalsIgnoreCase("application/x-www-form-urlencoded"); + var body = r.body(); + Buffer sink = new Buffer(); + try { + if (body != null) { + body.writeTo(sink); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return hdr != null && + hdr.equalsIgnoreCase("application/x-www-form-urlencoded") && + body != null && + sink.readUtf8().contains("grant_type=refresh_token&refresh_token=foo-refresh-token"); })); } diff --git a/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java b/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java index bf6a45d508..e7c9c7dee2 100644 --- a/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java +++ b/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java @@ -29,6 +29,7 @@ import com.nimbusds.jose.jwk.gen.ECKeyGenerator; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import io.restassured.http.ContentType; import org.eclipse.edc.connector.dataplane.spi.DataFlow; import org.eclipse.edc.connector.dataplane.spi.edr.EndpointDataReferenceServiceRegistry; import org.eclipse.edc.iam.did.spi.resolution.DidPublicKeyResolver; @@ -49,14 +50,12 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EmptySource; -import org.junit.jupiter.params.provider.NullSource; import java.net.URI; import java.text.ParseException; import java.util.Map; +import static java.lang.String.format; import static org.apache.http.HttpHeaders.AUTHORIZATION; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; @@ -64,7 +63,6 @@ import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_AUTH_NS; import static org.hamcrest.Matchers.containsString; - @EndToEndTest public class DataPlaneTokenRefreshEndToEndTest { @@ -125,9 +123,9 @@ void refresh_success() { var authToken = createAuthToken(accessToken, consumerKey); var tokenResponse = RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) .header(AUTHORIZATION, "Bearer " + authToken) + .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .post("/token") .then() .log().ifError() @@ -137,11 +135,9 @@ void refresh_success() { assertThat(tokenResponse).isNotNull(); } - @DisplayName("Refresh token is null or empty (missing)") - @ParameterizedTest - @NullSource - @EmptySource - void refresh_invalidRefreshToken(String invalidRefreshToken) { + @DisplayName("Refresh token is empty (missing)") + @Test + void refresh_invalidRefreshToken() { // register generator and secrets prepareDataplaneRuntime(); @@ -155,9 +151,9 @@ void refresh_invalidRefreshToken(String invalidRefreshToken) { var authToken = createAuthToken(accessToken, consumerKey); RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", invalidRefreshToken) .header(AUTHORIZATION, "Bearer " + authToken) + .contentType(ContentType.URLENC) + .body("grant_type=refresh_token&refresh_token=") .post("/token") .then() .log().ifError() @@ -180,9 +176,9 @@ void refresh_emptyAuthHeader() { // auth header is empty RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) .header(AUTHORIZATION, "") + .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .post("/token") .then() .log().ifError() @@ -205,8 +201,8 @@ void refresh_missingAuthHeader() { // auth header is empty RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) + .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .post("/token") .then() .log().ifError() @@ -229,9 +225,9 @@ void refresh_spoofedAuthToken() throws JOSEException { var authTokenWithSpoofedKey = createAuthToken(accessToken, spoofedKey); RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) .header(AUTHORIZATION, "Bearer " + authTokenWithSpoofedKey) + .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .post("/token") .then() .log().ifValidationFails() @@ -253,9 +249,9 @@ void refresh_withWrongRefreshToken() { var accessToken = edr.getStringProperty(EDC_NAMESPACE + "authorization"); RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) .header(AUTHORIZATION, "Bearer " + createAuthToken(accessToken, consumerKey)) + .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .post("/token") .then() .log().ifValidationFails() @@ -286,9 +282,9 @@ void refresh_invalidAuthenticationToken_missingAccessToken() { var authToken = createJwt(consumerKey, claims); RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) .header(AUTHORIZATION, "Bearer " + authToken) + .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .post("/token") .then() .log().ifValidationFails() @@ -319,9 +315,9 @@ void refresh_invalidAuthenticationToken_missingAudience() { var authToken = createJwt(consumerKey, claims); RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) .header(AUTHORIZATION, "Bearer " + authToken) + .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .post("/token") .then() .log().ifValidationFails() @@ -356,9 +352,9 @@ void refresh_invalidTokenId() { var authToken = createJwt(consumerKey, claims); RUNTIME_CONFIG.basePublicApiRequest() - .queryParam("grant_type", "refresh_token") - .queryParam("refresh_token", refreshToken) .header(AUTHORIZATION, "Bearer " + authToken) + .contentType(ContentType.URLENC) + .body(format("grant_type=refresh_token&refresh_token=%s", refreshToken)) .post("/token") .then() .log().ifValidationFails() diff --git a/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java b/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java index 057d296810..d0f0e03586 100644 --- a/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java +++ b/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java @@ -56,7 +56,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.IntStream; -import static com.github.tomakehurst.wiremock.client.WireMock.absent; +import static com.github.tomakehurst.wiremock.client.WireMock.matching; import static com.github.tomakehurst.wiremock.client.WireMock.ok; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; @@ -117,7 +117,9 @@ void setup() throws JOSEException { @DisplayName("Verify HTTP 200 response and body when refreshing succeeds") @Test void getEdrWithRefresh_success() { - mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")).withRequestBody(absent()) + mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")) + .withFormParam("grant_type", WireMock.equalTo("refresh_token")) + .withFormParam("refresh_token", matching(".+")) .willReturn(ok(tokenResponseBody()))); storeEdr("test-id", true); @@ -126,8 +128,7 @@ void getEdrWithRefresh_success() { .extract().body().as(JsonObject.class); assertThat(edr).isNotNull(); - mockedRefreshApi.verify(1, postRequestedFor(urlPathEqualTo("/refresh/token")) - .withQueryParam("grant_type", WireMock.equalTo("refresh_token"))); + mockedRefreshApi.verify(1, postRequestedFor(urlPathEqualTo("/refresh/token"))); } @DisplayName("When multiple requests to refresh, to different edrs, verify all return non expired token") @@ -137,7 +138,9 @@ void getEdrWithRefresh_subsequentRequestReturn() throws InterruptedException { var accessToken = createJwt(providerSigningKey, claims); var refreshToken = createJwt(providerSigningKey, new JWTClaimsSet.Builder().build()); var tokenResponseBodyString = tokenResponseBody(accessToken, refreshToken); - mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")).withRequestBody(absent()) + mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")) + .withFormParam("grant_type", WireMock.equalTo("refresh_token")) + .withFormParam("refresh_token", matching(".+")) .willReturn(WireMock.aResponse() .withStatus(200) .withFixedDelay(5000) @@ -184,8 +187,7 @@ void getEdrWithRefresh_subsequentRequestReturn() throws InterruptedException { latch.await(); assertThat(failed.get()).isFalse(); - mockedRefreshApi.verify(2, postRequestedFor(urlPathEqualTo("/refresh/token")) - .withQueryParam("grant_type", WireMock.equalTo("refresh_token"))); + mockedRefreshApi.verify(2, postRequestedFor(urlPathEqualTo("/refresh/token"))); } @DisplayName("Verify the refresh endpoint is not called when token not yet expired") @@ -197,8 +199,7 @@ void getEdrWithRefresh_notExpired_shouldNotCallEndpoint() { .extract().body().as(JsonObject.class); assertThat(edr).isNotNull(); - mockedRefreshApi.verify(0, postRequestedFor(urlPathEqualTo("/refresh/token")) - .withQueryParam("grant_type", WireMock.equalTo("refresh_token"))); + mockedRefreshApi.verify(0, postRequestedFor(urlPathEqualTo("/refresh/token"))); } @DisplayName("Verify the refresh endpoint is not called when auto_refresh=false") @@ -211,14 +212,15 @@ void getEdrWithRefresh_whenNotAutorefresh_shouldNotCallEndpoint() { .extract().body().as(JsonObject.class); assertThat(edr).isNotNull(); - mockedRefreshApi.verify(0, postRequestedFor(urlPathEqualTo("/refresh/token")) - .withQueryParam("grant_type", WireMock.equalTo("refresh_token"))); + mockedRefreshApi.verify(0, postRequestedFor(urlPathEqualTo("/refresh/token"))); } @DisplayName("Verify HTTP 403 response when refreshing the token is not allowed") @Test void getEdrWithRefresh_unauthorized() { - mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")).withRequestBody(absent()) + mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")) + .withFormParam("grant_type", WireMock.equalTo("refresh_token")) + .withFormParam("refresh_token", matching(".+")) .willReturn(WireMock.aResponse() .withStatus(401) .withBody("unauthorized") @@ -228,13 +230,14 @@ void getEdrWithRefresh_unauthorized() { CONSUMER.edrs().getEdrWithRefresh("test-id", true) .statusCode(403); - mockedRefreshApi.verify(1, postRequestedFor(urlPathEqualTo("/refresh/token")) - .withQueryParam("grant_type", WireMock.equalTo("refresh_token"))); + mockedRefreshApi.verify(1, postRequestedFor(urlPathEqualTo("/refresh/token"))); } @Test void refreshEdr() { - mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")).withRequestBody(absent()) + mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")) + .withFormParam("grant_type", WireMock.equalTo("refresh_token")) + .withFormParam("refresh_token", matching(".+")) .willReturn(ok(tokenResponseBody()))); storeEdr("test-id", true); @@ -243,8 +246,7 @@ void refreshEdr() { .extract().body().as(JsonObject.class); assertThat(edr).isNotNull(); - mockedRefreshApi.verify(1, postRequestedFor(urlPathEqualTo("/refresh/token")) - .withQueryParam("grant_type", WireMock.equalTo("refresh_token"))); + mockedRefreshApi.verify(1, postRequestedFor(urlPathEqualTo("/refresh/token"))); } @Test @@ -255,7 +257,9 @@ void refreshEdr_whenNotFound() { @Test void refreshEdr_whenNotAuthorized() { - mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")).withRequestBody(absent()) + mockedRefreshApi.stubFor(post(urlPathEqualTo("/refresh/token")) + .withFormParam("grant_type", WireMock.equalTo("refresh_token")) + .withFormParam("refresh_token", matching(".+")) .willReturn(WireMock.aResponse() .withStatus(401) .withBody("unauthorized") @@ -265,8 +269,7 @@ void refreshEdr_whenNotAuthorized() { CONSUMER.edrs().refreshEdr("test-id") .statusCode(403); - mockedRefreshApi.verify(1, postRequestedFor(urlPathEqualTo("/refresh/token")) - .withQueryParam("grant_type", WireMock.equalTo("refresh_token"))); + mockedRefreshApi.verify(1, postRequestedFor(urlPathEqualTo("/refresh/token"))); } private String tokenResponseBody() { From 3c63420b2c0a91efb8991f01cf081e04e31a781d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:37:51 +0200 Subject: [PATCH 160/259] chore(deps): bump aws from 2.46.9 to 2.46.13 (#2905) Bumps `aws` from 2.46.9 to 2.46.13. Updates `software.amazon.awssdk:s3` from 2.46.9 to 2.46.13 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.46.9 to 2.46.13 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.46.13 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.46.13 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 20c5c2b5e1..6f59e7a5b9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.2" awaitility = "4.3.0" -aws = "2.46.9" +aws = "2.46.13" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" From 7c2e9eccdace543d9ebd2e2b532e8b79b0c0910c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:38:13 +0200 Subject: [PATCH 161/259] chore(deps): bump io.swagger.core.v3.swagger-gradle-plugin (#2904) Bumps io.swagger.core.v3.swagger-gradle-plugin from 2.2.50 to 2.2.51. --- updated-dependencies: - dependency-name: io.swagger.core.v3.swagger-gradle-plugin dependency-version: 2.2.51 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6f59e7a5b9..50908eb086 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -255,5 +255,5 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } shadow = { id = "com.gradleup.shadow", version = "9.4.2" } -swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.50" } +swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.51" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From f659a861f16e42337fe383baddacac7a5c827b6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:38:35 +0200 Subject: [PATCH 162/259] chore(deps): bump flyway from 12.8.1 to 12.9.0 (#2903) Bumps `flyway` from 12.8.1 to 12.9.0. Updates `org.flywaydb:flyway-core` from 12.8.1 to 12.9.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.8.1 to 12.9.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.9.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 50908eb086..314bfa175e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" -flyway = "12.8.1" +flyway = "12.9.0" jackson = "2.22.0" jakarta-json = "2.1.3" junit = "6.1.0" From 339092ef5036ac90cd873d64029924a5bba30fc2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:58:07 +0200 Subject: [PATCH 163/259] chore(deps): bump eclipse-temurin in /resources (#2902) Bumps eclipse-temurin from `c707c0d` to `28db6fd`. --- updated-dependencies: - dependency-name: eclipse-temurin dependency-version: 25-jre-alpine dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- resources/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/Dockerfile b/resources/Dockerfile index 9da1b2052f..af6d77812c 100644 --- a/resources/Dockerfile +++ b/resources/Dockerfile @@ -19,7 +19,7 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -FROM eclipse-temurin:25-jre-alpine@sha256:c707c0d18cb9e8556380719f80d96a7529d0746fbb42143893949b98ed2f8943 +FROM eclipse-temurin:25-jre-alpine@sha256:28db6fdf60e38945e43d840c0333aeaec66c15943070104f7586fd3c9d1665b0 RUN apk update && apk upgrade --no-cache ARG JAR From 64ebf141fef978ef27c8ac1173d0399c74f46d43 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 10:49:45 +0200 Subject: [PATCH 164/259] chore(deps): bump actions/setup-java in /.github/actions/setup-java (#2913) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.2.0 to 5.3.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/be666c2fcd27ec809703dec50e508c2fdc7f6654...ad2b38190b15e4d6bdf0c97fb4fca8412226d287) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: 5.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-java/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index 86c9321bc8..2696e49939 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -26,7 +26,7 @@ runs: using: "composite" steps: - name: Setup JDK 21 - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 + uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 with: java-version: '21' distribution: 'temurin' From 0efe819deea5fe88173e9b5ccb68316b5a81464d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 10:50:29 +0200 Subject: [PATCH 165/259] chore(deps): bump actions/checkout (#2911) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index cddf0d8794..07f2ce51b7 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -46,7 +46,7 @@ inputs: runs: using: "composite" steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false From dbf2f330a707d872d8c0afe376d8e5172761e3c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 10:51:14 +0200 Subject: [PATCH 166/259] chore(deps): bump actions/checkout from 6.0.3 to 7.0.0 (#2909) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 2 +- .github/workflows/deployment-test.yaml | 4 ++-- .github/workflows/draft-release.yaml | 4 ++-- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 2 +- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 4 ++-- .github/workflows/publish-openapi-ui.yml | 4 ++-- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 2 +- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 4 ++-- 16 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 64e9bf7ec2..58550557ca 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -59,7 +59,7 @@ jobs: with: egress-policy: audit - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 97b7edb750..1fac9499bc 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -53,7 +53,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/run-deployment-test @@ -88,7 +88,7 @@ jobs: with: egress-policy: audit - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/run-deployment-test diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index f5852db39d..e30a2adfda 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -47,7 +47,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false @@ -120,7 +120,7 @@ jobs: packages: write pages: write steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.2 # zizmor: ignore[artipacked] + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6.0.2 # zizmor: ignore[artipacked] with: persist-credentials: true - name: Create Release branch diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index b16343142c..4f9808434b 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -38,7 +38,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: true - uses: ./.github/actions/setup-java diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 647122388d..24a06e02b2 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -52,7 +52,7 @@ jobs: ############## ### Set-Up ### ############## - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 37c2781472..2fcd50ead6 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -48,7 +48,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index 0ce1a3efe0..90a0934892 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -41,7 +41,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: copy contexts into public folder diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index f5f4c07acd..610007f26c 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -98,7 +98,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: "Get version" @@ -168,7 +168,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/publish-latest-versioned-snapshot diff --git a/.github/workflows/publish-openapi-ui.yml b/.github/workflows/publish-openapi-ui.yml index 137aebe16e..31316b8f7a 100644 --- a/.github/workflows/publish-openapi-ui.yml +++ b/.github/workflows/publish-openapi-ui.yml @@ -53,7 +53,7 @@ jobs: generate-openapi-spec: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -75,7 +75,7 @@ jobs: { name: "data-plane", folder: "edc-dataplane/edc-dataplane-base" } ] steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup-java diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8b927f1c3..0f2306f2e3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,7 +63,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: false @@ -155,7 +155,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 persist-credentials: true @@ -195,7 +195,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: true - name: Prepare Git Config @@ -259,7 +259,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -302,7 +302,7 @@ jobs: with: egress-policy: audit - name: Checkout main - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 ref: main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index dca9109df8..9f855b56d7 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -46,7 +46,7 @@ jobs: with: egress-policy: audit - name: Checkout Repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 # Ensure full clone for pull request workflows persist-credentials: false diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index db94d2d9f6..bdd27b3500 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -73,7 +73,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: Log inputs diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index f1f1b0136f..95bfb2eb07 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -62,7 +62,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup-java diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index b43ac1cb05..a2d7067137 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -54,7 +54,7 @@ jobs: with: egress-policy: audit - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index afd7436c57..15327ba0cb 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -39,7 +39,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - run: | @@ -62,7 +62,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -80,7 +80,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -97,7 +97,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -155,7 +155,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -174,7 +174,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -194,7 +194,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - name: get api groups and create matrix for next job @@ -216,7 +216,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -250,7 +250,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -268,7 +268,7 @@ jobs: uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 with: egress-policy: audit - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -291,7 +291,7 @@ jobs: with: egress-policy: audit - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index bc51f80e51..87058c6d48 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -51,7 +51,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false @@ -76,7 +76,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false From 35c1adb2a1d47f8dfbb6af0a9a77d67830c288e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 10:53:06 +0200 Subject: [PATCH 167/259] chore(deps): bump aws from 2.46.13 to 2.46.14 (#2908) Bumps `aws` from 2.46.13 to 2.46.14. Updates `software.amazon.awssdk:s3` from 2.46.13 to 2.46.14 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.46.13 to 2.46.14 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.46.14 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.46.14 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 314bfa175e..cb0a7113e0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.2" awaitility = "4.3.0" -aws = "2.46.13" +aws = "2.46.14" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" From 5bafbe7de9d1a85f1fa24ba7c0530b43c4d991a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 10:54:23 +0200 Subject: [PATCH 168/259] chore(deps): bump gradle-wrapper from 9.5.1 to 9.6.0 (#2907) Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.5.1 to 9.6.0. - [Release notes](https://github.com/gradle/gradle/releases) - [Commits](https://github.com/gradle/gradle/compare/v9.5.1...v9.6.0) --- updated-dependencies: - dependency-name: gradle-wrapper dependency-version: 9.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 4 ++-- gradlew.bat | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df6a6ad763..eb84db68da 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-bin.zip networkTimeout=10000 retries=0 retryBackOffMs=500 diff --git a/gradlew b/gradlew index b9bb139f79..249efbb032 100755 --- a/gradlew +++ b/gradlew @@ -20,7 +20,7 @@ ############################################################################## # -# Gradle start up script for POSIX generated by Gradle. +# gradlew start up script for POSIX generated by Gradle. # # Important for running: # @@ -29,7 +29,7 @@ # bash, then to run this script, type that shell name before the whole # command line, like: # -# ksh Gradle +# ksh gradlew # # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: diff --git a/gradlew.bat b/gradlew.bat index aa5f10b069..8508ef684d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -19,7 +19,7 @@ @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem -@rem Gradle startup script for Windows +@rem gradlew startup script for Windows @rem @rem ########################################################################## @@ -72,7 +72,7 @@ echo location of your Java installation. 1>&2 -@rem Execute Gradle +@rem Execute gradlew @rem endlocal doesn't take effect until after the line is parsed and variables are expanded @rem which allows us to clear the local environment before executing the java command endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel From 35a87c5a4107821eae37a3cc00df147a95c2611d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:01:35 +0200 Subject: [PATCH 169/259] chore(deps): bump actions/checkout (#2912) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/run-deployment-test/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/run-deployment-test/action.yml b/.github/actions/run-deployment-test/action.yml index e0b4636405..b9b4324f20 100644 --- a/.github/actions/run-deployment-test/action.yml +++ b/.github/actions/run-deployment-test/action.yml @@ -49,7 +49,7 @@ inputs: runs: using: "composite" steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - uses: ./.github/actions/setup-java From 9ce09723c4b6340ddce7e4651e7ca0f63f103435 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:01:58 +0200 Subject: [PATCH 170/259] chore(deps): bump trufflesecurity/trufflehog from 3.95.5 to 3.95.6 (#2910) Bumps [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) from 3.95.5 to 3.95.6. - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/d411fff7b8879a62509f3fa98c07f247ac089a51...30d5bb91af1a771378349dbbb0c82129392acf70) --- updated-dependencies: - dependency-name: trufflesecurity/trufflehog dependency-version: 3.95.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/secrets-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 9f855b56d7..066c78a08c 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -53,7 +53,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@d411fff7b8879a62509f3fa98c07f247ac089a51 + uses: trufflesecurity/trufflehog@30d5bb91af1a771378349dbbb0c82129392acf70 continue-on-error: true with: path: ./ # Scan the entire repository From 674c25f43c43e31b1a04b2b38c0dd2ca20b2c8ea Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Wed, 1 Jul 2026 16:15:14 +0200 Subject: [PATCH 171/259] chore: Enable dependabot for bugfixes (#2906) * Enable dependabot for bugfix release branch Signed-off-by: Lars Geyer-Blaumeiser * Revert previous approach and use an on demand workflow Signed-off-by: Lars Geyer-Blaumeiser * Apply suggestions from code review Co-authored-by: Andrii Yurkevych --------- Signed-off-by: Lars Geyer-Blaumeiser Co-authored-by: Andrii Yurkevych --- .github/workflows/dependabot-on-demand.yaml | 58 +++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/dependabot-on-demand.yaml diff --git a/.github/workflows/dependabot-on-demand.yaml b/.github/workflows/dependabot-on-demand.yaml new file mode 100644 index 0000000000..b79f636cbe --- /dev/null +++ b/.github/workflows/dependabot-on-demand.yaml @@ -0,0 +1,58 @@ +################################################################################# +# Copyright (c) 2026 Cofinity-X GmbH +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +--- +name: "Dependabot (on-demand)" +run-name: "Dependabot ${{ matrix.ecosystem }} (${{ matrix.directory }})" + +on: + workflow_dispatch: + inputs: + branch: + description: "Branch to check (e.g. release/0.10.0)." + required: true + +permissions: + contents: read + +jobs: + run: + runs-on: ubuntu-latest + name: "Dependabot ${{ matrix.ecosystem }} (${{ matrix.directory }})" + strategy: + fail-fast: false + matrix: + include: + - ecosystem: gradle + directory: / + - ecosystem: docker + directory: resources + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + LOCAL_GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ECOSYSTEM: ${{ matrix.ecosystem }} + DIRECTORY: ${{ matrix.directory }} + BRANCH: ${{ inputs.branch }} + REPO: ${{ github.repository }} + steps: + - name: Run Dependabot + run: | + VERSION="$(gh release view --repo dependabot/cli --json tagName -q .tagName)" + curl -sSfL "https://github.com/dependabot/cli/releases/download/${VERSION}/dependabot-${VERSION}-linux-amd64.tar.gz" | tar -xz dependabot + ./dependabot update "$ECOSYSTEM" "$REPO" --branch "$BRANCH" --directory "$DIRECTORY" From 1bb7402882dcd515217ff88c65d343725afdd35a Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Wed, 1 Jul 2026 16:22:35 +0200 Subject: [PATCH 172/259] fix: fix Dependabot (on-demand) (#2916) --- .github/workflows/dependabot-on-demand.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-on-demand.yaml b/.github/workflows/dependabot-on-demand.yaml index b79f636cbe..1d5acaa339 100644 --- a/.github/workflows/dependabot-on-demand.yaml +++ b/.github/workflows/dependabot-on-demand.yaml @@ -19,7 +19,7 @@ --- name: "Dependabot (on-demand)" -run-name: "Dependabot ${{ matrix.ecosystem }} (${{ matrix.directory }})" +run-name: "Dependabot (gradle/docker ecosystem) on ${{ inputs.branch }}" on: workflow_dispatch: From db7ddc1930c2b440c46ddd7310b1b3877cd7d265 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:27:52 +0200 Subject: [PATCH 173/259] chore(deps): bump actions/setup-java in /.github/actions/setup-java (#2931) Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.3.0 to 5.4.0. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/ad2b38190b15e4d6bdf0c97fb4fca8412226d287...1bcf9fb12cf4aa7d266a90ae39939e61372fe520) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: 5.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-java/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index 2696e49939..e7e4603cb3 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -26,7 +26,7 @@ runs: using: "composite" steps: - name: Setup JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 + uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 with: java-version: '21' distribution: 'temurin' From 617eb44393c2c546ef2d8db95226045bd15171a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:29:37 +0200 Subject: [PATCH 174/259] chore(deps): bump actions/cache from 5.0.5 to 6.1.0 (#2919) Bumps [actions/cache](https://github.com/actions/cache) from 5.0.5 to 6.1.0. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...55cc8345863c7cc4c66a329aec7e433d2d1c52a9) --- updated-dependencies: - dependency-name: actions/cache dependency-version: 6.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deployment-test.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 1fac9499bc..408b1a0b62 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -40,7 +40,7 @@ jobs: with: egress-policy: audit - name: Cache ContainerD Image Layers - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs key: ${{ runner.os }}-io.containerd.snapshotter.v1.overlayfs diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index a2d7067137..8ae111edb2 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -40,7 +40,7 @@ jobs: with: egress-policy: audit - name: Cache ContainerD Image Layers - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs key: ${{ runner.os }}-io.containerd.snapshotter.v1.overlayfs From 75b77e746ccac0beee0bdd0cd95a4018c04f5fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arno=20Wei=C3=9F?= <86715435+arnoweiss@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:32:57 +0200 Subject: [PATCH 175/259] fix(agreements-bpns): null-check BdrsClient.resolveBpn result (#2915) (#2917) --- .../EventContractNegotiationSubscriber.java | 22 ++++++++--- ...ventContractNegotiationSubscriberTest.java | 39 +++++++++++++++++++ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-core/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/EventContractNegotiationSubscriber.java b/edc-extensions/agreements-bpns/bpns-evaluation-core/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/EventContractNegotiationSubscriber.java index c580be3232..df320866cf 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-core/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/EventContractNegotiationSubscriber.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-core/src/main/java/org/eclipse/tractusx/edc/agreements/bpns/EventContractNegotiationSubscriber.java @@ -47,8 +47,12 @@ public void on(EventEnvelope envelope) { var agreement = payload.getContractAgreement(); var agreementId = agreement.getId(); - var providerBpn = extractBpn(agreement.getProviderId()); - var consumerBpn = extractBpn(agreement.getConsumerId()); + var providerBpn = extractBpn(agreementId, agreement.getProviderId()); + var consumerBpn = extractBpn(agreementId, agreement.getConsumerId()); + + if (providerBpn == null || consumerBpn == null) { + return; + } var entry = AgreementsBpnsEntry.Builder.newInstance() .withAgreementId(agreementId) @@ -59,9 +63,15 @@ public void on(EventEnvelope envelope) { store.save(entry).onFailure(failure -> monitor.severe(failure.getFailureDetail())); } - private String extractBpn(String id) { - return id.startsWith(DID_PREFIX) - ? bdrsClient.resolveBpn(id) - : id; + private String extractBpn(String agreementId, String id) { + if (!id.startsWith(DID_PREFIX)) { + return id; + } + var bpn = bdrsClient.resolveBpn(id); + if (bpn == null) { + monitor.severe("Could not resolve BPN for DID '%s' on agreement '%s'. The agreement will not be stored." + .formatted(id, agreementId)); + } + return bpn; } } diff --git a/edc-extensions/agreements-bpns/bpns-evaluation-core/src/test/java/org/eclipse/tractusx/edc/agreements/bpns/EventContractNegotiationSubscriberTest.java b/edc-extensions/agreements-bpns/bpns-evaluation-core/src/test/java/org/eclipse/tractusx/edc/agreements/bpns/EventContractNegotiationSubscriberTest.java index 98caf2f427..3a43f434ce 100644 --- a/edc-extensions/agreements-bpns/bpns-evaluation-core/src/test/java/org/eclipse/tractusx/edc/agreements/bpns/EventContractNegotiationSubscriberTest.java +++ b/edc-extensions/agreements-bpns/bpns-evaluation-core/src/test/java/org/eclipse/tractusx/edc/agreements/bpns/EventContractNegotiationSubscriberTest.java @@ -41,6 +41,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -173,4 +175,41 @@ void on_shouldLogSevere_whenStoreSaveFails() { verify(monitor).severe(failureDetail); } + + @Test + void on_shouldLogSevereAndSkipSave_whenBpnResolutionReturnsNull() { + var agreementId = UUID.randomUUID().toString(); + var providerId = "did:provider"; + var consumerId = "did:consumer"; + + var subscriberWithNullResolver = new EventContractNegotiationSubscriber( + store, monitor, new MockBdrsClient((s) -> s, (s) -> null)); + + var agreement = ContractAgreement.Builder.newInstance() + .id(agreementId) + .providerId(providerId) + .consumerId(consumerId) + .assetId("asset") + .policy(Policy.Builder.newInstance().assignee(consumerId).build()) + .build(); + + var event = ContractNegotiationFinalized.Builder.newInstance() + .contractNegotiationId(UUID.randomUUID().toString()) + .contractAgreement(agreement) + .counterPartyAddress("counterPartyAddress") + .counterPartyId("counterPartyId") + .protocol("protocol") + .build(); + + var envelope = EventEnvelope.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .at(System.currentTimeMillis()) + .payload(event) + .build(); + + subscriberWithNullResolver.on(envelope); + + verify(monitor, times(2)).severe(anyString()); + verify(store, never()).save(any()); + } } From 7f24dffa2fa7fbf8f6ac5797ed33a80b4dbd0a52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:36:44 +0200 Subject: [PATCH 176/259] chore(deps): bump zizmorcore/zizmor-action from 0.5.6 to 0.5.7 (#2927) Bumps [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) from 0.5.6 to 0.5.7. - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/5f14fd08f7cf1cb1609c1e344975f152c7ee938d...192e21d79ab29983730a13d1382995c2307fbcaa) --- updated-dependencies: - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/workflow-security-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 87058c6d48..d12dd35e67 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -56,7 +56,7 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 + uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7 with: version: "1.23.1" advanced-security: "true" From efb2380020860d947d4ff4c05ec16857e0676906 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:37:10 +0200 Subject: [PATCH 177/259] chore(deps): bump actions/setup-python from 6.2.0 to 6.3.0 (#2918) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6.2.0 to 6.3.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...ece7cb06caefa5fff74198d8649806c4678c61a1) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/helm-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 24a06e02b2..1e55b62213 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -58,7 +58,7 @@ jobs: persist-credentials: false - uses: ./.github/actions/setup-helm - name: python (setup) - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: 3.13 - name: chart-testing (setup) From 10e27465a702f3f694ecee4b54f92e824312157b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:30:24 +0200 Subject: [PATCH 178/259] chore(deps): bump azure/setup-helm in /.github/actions/setup-helm (#2930) Bumps [azure/setup-helm](https://github.com/azure/setup-helm) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/azure/setup-helm/releases) - [Changelog](https://github.com/Azure/setup-helm/blob/main/CHANGELOG.md) - [Commits](https://github.com/azure/setup-helm/compare/dda3372f752e03dde6b3237bc9431cdc2f7a02a2...9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310) --- updated-dependencies: - dependency-name: azure/setup-helm dependency-version: 5.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-helm/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/setup-helm/action.yml b/.github/actions/setup-helm/action.yml index 33ef49ded8..a7fafe4b98 100644 --- a/.github/actions/setup-helm/action.yml +++ b/.github/actions/setup-helm/action.yml @@ -24,6 +24,6 @@ description: "Setup Helm" runs: using: "composite" steps: - - uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5.0.0 + - uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # v5.0.1 with: version: v3.16.1 From 250a56540b874bdc8873deabafb07b6c20d8acf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:32:06 +0200 Subject: [PATCH 179/259] chore(deps): bump com.networknt:json-schema-validator (#2928) Bumps [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) from 3.0.4 to 3.0.5. - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/3.0.4...3.0.5) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-version: 3.0.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts index 5c95eb6276..138c57ef5f 100644 --- a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts @@ -43,7 +43,7 @@ dependencies { } constraints { - implementation("com.networknt:json-schema-validator:3.0.4") { + implementation("com.networknt:json-schema-validator:3.0.5") { because("older versions cause runtime issues") } } From d75dfddd735f6fe3ce05d9f7c15ce74927bb3102 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:32:52 +0200 Subject: [PATCH 180/259] chore(deps): bump io.qameta.allure:allure-junit5 from 2.35.2 to 2.35.3 (#2926) Bumps [io.qameta.allure:allure-junit5](https://github.com/allure-framework/allure-java) from 2.35.2 to 2.35.3. - [Release notes](https://github.com/allure-framework/allure-java/releases) - [Commits](https://github.com/allure-framework/allure-java/compare/2.35.2...2.35.3) --- updated-dependencies: - dependency-name: io.qameta.allure:allure-junit5 dependency-version: 2.35.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cb0a7113e0..21b75efca9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ format.version = "1.1" [versions] edc = "0.17.0" edc-build = "1.5.2" -allure = "2.35.2" +allure = "2.35.3" awaitility = "4.3.0" aws = "2.46.14" azure-storage-blob = "12.35.0" From 28f83a463479ec79c4b4266c52fb392b66e12060 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:37:53 +0200 Subject: [PATCH 181/259] chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations (#2925) Bumps [io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.28.1 to 2.29.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.28.1...v2.29.0) --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations dependency-version: 2.29.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 21b75efca9..ae7a136533 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ junit = "6.1.0" nimbus = "10.9.1" okhttp = "5.4.0" opentelemetry = "2.28.1" -opentelemetry-instrumentation = "2.28.1" +opentelemetry-instrumentation = "2.29.0" opentelemetry-log4j-appender = "2.28.1-alpha" postgres = "42.7.11" restAssured = "6.0.0" From de4bbc51037033823cc7ea4767ef5cb71f553788 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:39:17 +0200 Subject: [PATCH 182/259] chore(deps): bump aws from 2.46.14 to 2.46.17 (#2922) Bumps `aws` from 2.46.14 to 2.46.17. Updates `software.amazon.awssdk:s3` from 2.46.14 to 2.46.17 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.46.14 to 2.46.17 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.46.17 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.46.17 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ae7a136533..47aaff68e5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.3" awaitility = "4.3.0" -aws = "2.46.14" +aws = "2.46.17" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" From ddb613a256c7c0a3b6168eca1b3354b6e9af8893 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:40:20 +0200 Subject: [PATCH 183/259] chore(deps): bump io.swagger.core.v3.swagger-gradle-plugin (#2924) Bumps io.swagger.core.v3.swagger-gradle-plugin from 2.2.51 to 2.2.52. --- updated-dependencies: - dependency-name: io.swagger.core.v3.swagger-gradle-plugin dependency-version: 2.2.52 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 47aaff68e5..e91fe7eb4f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -255,5 +255,5 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } shadow = { id = "com.gradleup.shadow", version = "9.4.2" } -swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.51" } +swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.52" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From 7525b14360a68f0e0fe906e73e785b150cc0c2e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:55:22 +0200 Subject: [PATCH 184/259] chore(deps): bump io.opentelemetry.javaagent:opentelemetry-javaagent (#2921) Bumps [io.opentelemetry.javaagent:opentelemetry-javaagent](https://github.com/open-telemetry/opentelemetry-java-instrumentation) from 2.28.1 to 2.29.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.28.1...v2.29.0) --- updated-dependencies: - dependency-name: io.opentelemetry.javaagent:opentelemetry-javaagent dependency-version: 2.29.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e91fe7eb4f..7cbed602cd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,7 +18,7 @@ jakarta-json = "2.1.3" junit = "6.1.0" nimbus = "10.9.1" okhttp = "5.4.0" -opentelemetry = "2.28.1" +opentelemetry = "2.29.0" opentelemetry-instrumentation = "2.29.0" opentelemetry-log4j-appender = "2.28.1-alpha" postgres = "42.7.11" From 72755ae7c3a38f38a483ff9b67b4caeafb86aa69 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Tue, 7 Jul 2026 07:57:17 +0200 Subject: [PATCH 185/259] refactoring: Provide endpoints currently available under api version v4alpha to management api v3 (#2932) * feat: move v4alpha to v3 * feat: move v4alpha to v3 --- .../2026_06-Version_0.12.x_0.13.x.md | 11 +- .../management-api-walkthrough/04_catalog.md | 6 +- .../10_nonfiniteproviderpush.md | 2 +- .../connector-discovery-api/build.gradle.kts | 1 + .../ConnectorDiscoveryExtension.java | 39 ++- .../ConnectorDiscoveryController.java} | 44 ++- .../api/v3/ConnectorDiscoveryV3Api.java | 165 ++++++++++++ .../v3/ConnectorDiscoveryV3Controller.java | 59 ++++ .../ConnectorDiscoveryV4AlphaApi.java | 7 +- .../ConnectorDiscoveryV4AlphaController.java | 66 +++++ .../UnexpectedResultApiException.java | 2 +- .../BaseConnectorDiscoveryServiceImpl.java | 12 +- .../DefaultConnectorDiscoveryServiceImpl.java | 4 +- .../{v4alpha => }/spi/CacheConfig.java | 2 +- .../spi/ConnectorDiscoveryRequest.java | 2 +- .../spi/ConnectorDiscoveryService.java | 2 +- .../spi/ConnectorParamsDiscoveryRequest.java | 2 +- ...JsonObjectToConnectorDiscoveryRequest.java | 8 +- ...jectToConnectorParamsDiscoveryRequest.java | 10 +- .../ConnectorDiscoveryRequestValidator.java | 6 +- ...nectorParamsDiscoveryRequestValidator.java | 8 +- ...rg.eclipse.edc.spi.system.ServiceExtension | 2 +- .../ConnectorDiscoveryControllerTest.java | 175 ++++++++++++ ...onnectorDiscoveryRequestValidatorTest.java | 8 +- ...orParamsDiscoveryRequestValidatorTest.java | 10 +- ...aultConnectorDiscoveryServiceImplTest.java | 14 +- ...ObjectToConnectorDiscoveryRequestTest.java | 8 +- ...ToConnectorParamsDiscoveryRequestTest.java | 10 +- ...nnectorDiscoveryV4AlphaControllerTest.java | 252 ------------------ ...DiscoveryBpnlAndDsp08ServiceExtension.java | 8 +- ...AndDsp08ConnectorDiscoveryServiceImpl.java | 6 +- ...sp08ConnectorDiscoveryServiceImplTest.java | 6 +- .../{v4alpha => }/DataFlowApiController.java | 24 +- .../dataflow/api/DataFlowApiExtension.java | 8 +- .../edc/dataflow/api/v3/DataFlowV3Api.java | 49 ++++ .../api/v3/DataFlowV3ApiController.java | 50 ++++ ...taFlowApi.java => DataFlowV4AlphaApi.java} | 3 +- .../v4alpha/DataFlowV4AlphaApiController.java | 56 ++++ .../api/DataFlowApiControllerTest.java | 84 ++++++ .../v4alpha/DataFlowApiControllerTest.java | 109 -------- .../participant/TractusxParticipantBase.java | 6 +- .../transfer/DataFlowApiEndToEndTest.java | 2 +- 42 files changed, 848 insertions(+), 500 deletions(-) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/ConnectorDiscoveryExtension.java (71%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha/api/ConnectorDiscoveryV4AlphaController.java => api/ConnectorDiscoveryController.java} (69%) create mode 100644 edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v3/ConnectorDiscoveryV3Api.java create mode 100644 edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v3/ConnectorDiscoveryV3Controller.java rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha/api => api/v4alpha}/ConnectorDiscoveryV4AlphaApi.java (97%) create mode 100644 edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v4alpha/ConnectorDiscoveryV4AlphaController.java rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/exceptions/UnexpectedResultApiException.java (95%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/service/BaseConnectorDiscoveryServiceImpl.java (97%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/service/DefaultConnectorDiscoveryServiceImpl.java (94%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/spi/CacheConfig.java (93%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/spi/ConnectorDiscoveryRequest.java (96%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/spi/ConnectorDiscoveryService.java (98%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/spi/ConnectorParamsDiscoveryRequest.java (97%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/transformers/JsonObjectToConnectorDiscoveryRequest.java (87%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/transformers/JsonObjectToConnectorParamsDiscoveryRequest.java (81%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/validators/ConnectorDiscoveryRequestValidator.java (90%) rename edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/validators/ConnectorParamsDiscoveryRequestValidator.java (88%) create mode 100644 edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryControllerTest.java rename edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/ConnectorDiscoveryRequestValidatorTest.java (93%) rename edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/ConnectorParamsDiscoveryRequestValidatorTest.java (88%) rename edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/DefaultConnectorDiscoveryServiceImplTest.java (97%) rename edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/JsonObjectToConnectorDiscoveryRequestTest.java (89%) rename edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/{v4alpha => }/JsonObjectToConnectorParamsDiscoveryRequestTest.java (88%) delete mode 100644 edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryV4AlphaControllerTest.java rename edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/{v4alpha => }/DataFlowApiController.java (75%) create mode 100644 edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v3/DataFlowV3Api.java create mode 100644 edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v3/DataFlowV3ApiController.java rename edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/{DataFlowApi.java => DataFlowV4AlphaApi.java} (97%) create mode 100644 edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowV4AlphaApiController.java create mode 100644 edc-extensions/dataplane/dataflow/dataflow-api/src/test/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiControllerTest.java delete mode 100644 edc-extensions/dataplane/dataflow/dataflow-api/src/test/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApiControllerTest.java diff --git a/docs/migration/2026_06-Version_0.12.x_0.13.x.md b/docs/migration/2026_06-Version_0.12.x_0.13.x.md index f86793f6a5..4ed3860ea1 100644 --- a/docs/migration/2026_06-Version_0.12.x_0.13.x.md +++ b/docs/migration/2026_06-Version_0.12.x_0.13.x.md @@ -20,8 +20,15 @@ The Federate Catalog feature has not been proven to be usable, that's why it wil that `tx.edc.postgresql.migration.federatedcatalog.enabled` is set to `false` before the migration. ## 2. Deprecated instances -The API `/business-partner-groups` has been removed, please use `/v3/business-partner-groups` instead. -Also the API `/v2/edrs` has been removed, please use `/v3/edrs` instead. +API changes: + +| Old API | New API | +|-------------------------------|-------------------------------| +| `/business-partner-groups` | `/v3/business-partner-groups` | +| `/v2/edrs` | `/v3/edrs` | +| `/v4alpha/connectordiscovery` | `/v3/connectordiscovery` | +| `/v4alpha/dataflows` | `/v3/dataflows` | + Additionally, several configuration parameters deprecated since version 0.8.x have also been removed. Please use the updated configuration parameters instead. diff --git a/docs/usage/management-api-walkthrough/04_catalog.md b/docs/usage/management-api-walkthrough/04_catalog.md index 69926339d5..dae01d1f59 100644 --- a/docs/usage/management-api-walkthrough/04_catalog.md +++ b/docs/usage/management-api-walkthrough/04_catalog.md @@ -26,7 +26,7 @@ DSP discovery is supported with the following requests For the full flow including the DID document download: ```http request -POST /v4alpha/connectordiscovery/connectors HTTP/1.1 +POST /v3/connectordiscovery/connectors HTTP/1.1 Host: https://consumer-control.plane/api/management X-Api-Key: password Content-Type: application/json @@ -45,7 +45,7 @@ Content-Type: application/json or, if a connector base address is already known: ```http request -POST /v4alpha/connectordiscovery/dspversionparams HTTP/1.1 +POST /v3/connectordiscovery/dspversionparams HTTP/1.1 Host: https://consumer-control.plane/api/management X-Api-Key: password Content-Type: application/json @@ -257,7 +257,7 @@ policies included. ## Reference -- [Connector Discovery API](https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/#/Connector%20Discovery/discoverDspVersionParamsV4Alpha) +- [Connector Discovery API](https://eclipse-tractusx.github.io/tractusx-edc/openapi/control-plane-api/#/Connector%20Discovery/discoverDspVersionParamsV3) ## Notice diff --git a/docs/usage/management-api-walkthrough/10_nonfiniteproviderpush/10_nonfiniteproviderpush.md b/docs/usage/management-api-walkthrough/10_nonfiniteproviderpush/10_nonfiniteproviderpush.md index 1831f3b3ac..6aea48f9d4 100644 --- a/docs/usage/management-api-walkthrough/10_nonfiniteproviderpush/10_nonfiniteproviderpush.md +++ b/docs/usage/management-api-walkthrough/10_nonfiniteproviderpush/10_nonfiniteproviderpush.md @@ -56,7 +56,7 @@ available within the management API context and is exposed through the data plan the following request: ```http request -POST /v4alpha/dataflows/{{TRANSFER_PROCESS_ID}}/trigger HTTP/1.1 +POST /v3/dataflows/{{TRANSFER_PROCESS_ID}}/trigger HTTP/1.1 Host: https://provider-data.plane/api/management X-Api-Key: password Content-Type: application/json diff --git a/edc-extensions/connector-discovery/connector-discovery-api/build.gradle.kts b/edc-extensions/connector-discovery/connector-discovery-api/build.gradle.kts index 9ac82c8e11..bbdfae4123 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/build.gradle.kts +++ b/edc-extensions/connector-discovery/connector-discovery-api/build.gradle.kts @@ -40,6 +40,7 @@ dependencies { implementation(libs.edc.lib.validator) implementation(libs.edc.lib.util) implementation(libs.edc.boot) + implementation(libs.edc.api.core) implementation(libs.edc.api.management.config) implementation(libs.jakarta.rsApi) diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryExtension.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryExtension.java similarity index 71% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryExtension.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryExtension.java index c0e27fef53..7d4e1a8658 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryExtension.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryExtension.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha; +package org.eclipse.tractusx.edc.discovery; import org.eclipse.edc.http.spi.EdcHttpClient; import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; @@ -36,21 +36,23 @@ import org.eclipse.edc.web.jersey.providers.jsonld.JerseyJsonLdInterceptor; import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; -import org.eclipse.tractusx.edc.discovery.v4alpha.api.ConnectorDiscoveryV4AlphaController; -import org.eclipse.tractusx.edc.discovery.v4alpha.service.DefaultConnectorDiscoveryServiceImpl; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryService; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.transformers.JsonObjectToConnectorDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.transformers.JsonObjectToConnectorParamsDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.validators.ConnectorDiscoveryRequestValidator; -import org.eclipse.tractusx.edc.discovery.v4alpha.validators.ConnectorParamsDiscoveryRequestValidator; +import org.eclipse.tractusx.edc.discovery.api.ConnectorDiscoveryController; +import org.eclipse.tractusx.edc.discovery.api.v3.ConnectorDiscoveryV3Controller; +import org.eclipse.tractusx.edc.discovery.api.v4alpha.ConnectorDiscoveryV4AlphaController; +import org.eclipse.tractusx.edc.discovery.service.DefaultConnectorDiscoveryServiceImpl; +import org.eclipse.tractusx.edc.discovery.spi.CacheConfig; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryService; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.transformers.JsonObjectToConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.transformers.JsonObjectToConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.validators.ConnectorDiscoveryRequestValidator; +import org.eclipse.tractusx.edc.discovery.validators.ConnectorParamsDiscoveryRequestValidator; import java.time.Clock; import static org.eclipse.edc.spi.constants.CoreConstants.JSON_LD; -import static org.eclipse.tractusx.edc.discovery.v4alpha.ConnectorDiscoveryExtension.NAME; +import static org.eclipse.tractusx.edc.discovery.ConnectorDiscoveryExtension.NAME; @Extension(value = NAME) public class ConnectorDiscoveryExtension implements ServiceExtension { @@ -101,12 +103,21 @@ public void initialize(ServiceExtensionContext context) { managementTypeTransformerRegistry.register(new JsonObjectToConnectorDiscoveryRequest()); validatorRegistry.register(ConnectorDiscoveryRequest.TYPE, ConnectorDiscoveryRequestValidator.instance()); - webService.registerResource(ApiContext.MANAGEMENT, new ConnectorDiscoveryV4AlphaController( - connectorDiscoveryService, managementTypeTransformerRegistry, validatorRegistry, monitor)); + var connectorDiscoveryController = new ConnectorDiscoveryController( + connectorDiscoveryService, managementTypeTransformerRegistry, validatorRegistry, monitor); + + webService.registerResource(ApiContext.MANAGEMENT, + new ConnectorDiscoveryV4AlphaController(connectorDiscoveryController, monitor)); webService.registerDynamicResource( ApiContext.MANAGEMENT, ConnectorDiscoveryV4AlphaController.class, new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, "MANAGEMENT_API")); + webService.registerResource(ApiContext.MANAGEMENT, + new ConnectorDiscoveryV3Controller(connectorDiscoveryController)); + webService.registerDynamicResource( + ApiContext.MANAGEMENT, ConnectorDiscoveryV3Controller.class, + new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, "MANAGEMENT_API")); + } @Provider(isDefault = true) diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/api/ConnectorDiscoveryV4AlphaController.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/ConnectorDiscoveryController.java similarity index 69% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/api/ConnectorDiscoveryV4AlphaController.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/ConnectorDiscoveryController.java index 3ac37951f7..46dd25910c 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/api/ConnectorDiscoveryV4AlphaController.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/ConnectorDiscoveryController.java @@ -18,52 +18,43 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.api; +package org.eclipse.tractusx.edc.discovery.api; import jakarta.json.JsonObject; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.container.Suspended; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.transform.spi.TypeTransformerRegistry; import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; import org.eclipse.edc.web.spi.exception.ValidationFailureException; -import org.eclipse.tractusx.edc.discovery.v4alpha.exceptions.UnexpectedResultApiException; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryService; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.exceptions.UnexpectedResultApiException; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryService; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; import java.util.concurrent.CompletionException; -import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; - -@Consumes(APPLICATION_JSON) -@Produces(APPLICATION_JSON) -@Path("/v4alpha/connectordiscovery") -public class ConnectorDiscoveryV4AlphaController implements ConnectorDiscoveryV4AlphaApi { +/** + * Holds the versioned-independent connector discovery logic. Version specific controllers (e.g. v3, v4alpha) + * delegate the actual work to this controller. + */ +public class ConnectorDiscoveryController { private final ConnectorDiscoveryService connectorDiscoveryService; private final TypeTransformerRegistry transformerRegistry; private final JsonObjectValidatorRegistry validator; private final Monitor monitor; - public ConnectorDiscoveryV4AlphaController(ConnectorDiscoveryService connectorDiscoveryService, - TypeTransformerRegistry transformerRegistry, - JsonObjectValidatorRegistry validator, - Monitor monitor) { + public ConnectorDiscoveryController(ConnectorDiscoveryService connectorDiscoveryService, + TypeTransformerRegistry transformerRegistry, + JsonObjectValidatorRegistry validator, + Monitor monitor) { this.connectorDiscoveryService = connectorDiscoveryService; this.transformerRegistry = transformerRegistry; this.validator = validator; this.monitor = monitor; } - @Path("/dspversionparams") - @POST - @Override - public void discoverDspVersionParamsV4Alpha(JsonObject inputJson, @Suspended AsyncResponse response) { + public void discoverDspVersionParams(JsonObject inputJson, AsyncResponse response) { validator.validate(ConnectorParamsDiscoveryRequest.TYPE, inputJson) .orElseThrow(ValidationFailureException::new); @@ -78,10 +69,7 @@ public void discoverDspVersionParamsV4Alpha(JsonObject inputJson, @Suspended Asy }); } - @Path("/connectors") - @POST - @Override - public void discoverConnectorServicesV4Alpha(JsonObject inputJson, @Suspended AsyncResponse response) { + public void discoverConnectorServices(JsonObject inputJson, AsyncResponse response) { validator.validate(ConnectorDiscoveryRequest.TYPE, inputJson) .orElseThrow((ValidationFailureException::new)); diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v3/ConnectorDiscoveryV3Api.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v3/ConnectorDiscoveryV3Api.java new file mode 100644 index 0000000000..8c6337f59e --- /dev/null +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v3/ConnectorDiscoveryV3Api.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.discovery.api.v3; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.json.JsonObject; +import jakarta.ws.rs.container.AsyncResponse; +import jakarta.ws.rs.container.Suspended; +import org.eclipse.edc.jsonld.spi.JsonLdKeywords; +import org.eclipse.edc.web.spi.ApiErrorDetail; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; + +@OpenAPIDefinition(info = @Info( + description = "With this API clients discover connectors based on published services in a DID document and " + + "discover the right version parameters according to different DSP versions.", + title = "Connector Discovery API")) +@Tag(name = "Connector Discovery") +public interface ConnectorDiscoveryV3Api { + + @Operation(description = "Discover supported connector parameters for a given connector endpoint.", + requestBody = @RequestBody(content = @Content(schema = @Schema(name = "Connector Params Discovery Request", + implementation = ConnectorParamsDiscoveryRequestSchema.class))), + responses = { + @ApiResponse(responseCode = "200", + description = "A list of connector parameters for the DSP version to use with the given connector.", + content = @Content(schema = @Schema(name = "Connector Discovery Response", + implementation = ConnectorParamsDiscoveryResponse.class))), + @ApiResponse(responseCode = "500", description = "Discovery failed due to an internal error", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))), + @ApiResponse(responseCode = "502", description = "Discovery failed due to connection issues to counter party", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))), + @ApiResponse(responseCode = "400", description = "Request body was malformed", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) + }) + void discoverDspVersionParamsV3(JsonObject querySpecJson, @Suspended AsyncResponse response); + + @Operation(description = "Searches for 'DataService' entries in the DID document of a participant and provides " + + "the connection parameters for all found connectors by applying the connector param discovery request for each.", + requestBody = @RequestBody(content = @Content(schema = @Schema(name = "Connector Discovery Request", + implementation = ConnectorDiscoveryRequestSchema.class))), + responses = { + @ApiResponse(responseCode = "200", + description = "A list of connector endpoint parameters for the version to use for each found connector", + content = @Content( + mediaType = "application/json", + array = @ArraySchema(schema = @Schema( + name = "Service Discovery Response", + implementation = ConnectorParamsDiscoveryResponse.class)) + )), + @ApiResponse(responseCode = "400", description = "Request body was malformed", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))), + @ApiResponse(responseCode = "404", description = "Given Id could not be resolved to a DID document", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))), + @ApiResponse(responseCode = "500", description = "Discovery failed due to an internal error", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))), + @ApiResponse(responseCode = "502", description = "Discovery failed due to connection to counter party", + content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) + }) + void discoverConnectorServicesV3(JsonObject querySpecJson, @Suspended AsyncResponse response); + + @Schema(name = "ConnectorParamsDiscoveryRequest", + description = "Note: In former versions, the property 'counterPartyId' was named 'bpnl', " + + "for convenience this value is still allowed", + example = ConnectorParamsDiscoveryRequestSchema.EXAMPLE) + record ConnectorParamsDiscoveryRequestSchema( + @Schema(name = CONTEXT, requiredMode = REQUIRED) + Object context, + @Schema(name = JsonLdKeywords.TYPE, example = ConnectorParamsDiscoveryRequest.TYPE) + String type, + @Schema(requiredMode = REQUIRED) + String counterPartyId, + @Schema(requiredMode = REQUIRED) + String counterPartyAddress + ) { + public static final String EXAMPLE = """ + { + "@context": { + "edc": "https://w3id.org/edc/v0.0.1/ns/", + "tx": "https://w3id.org/tractusx/v0.0.1/ns/" + }, + "@type": "tx:ConnectorParamsDiscoveryRequest", + "edc:counterPartyId": "BPNL1234567890", + "edc:counterPartyAddress": "https://provider.domain.com/api/dsp" + } + """; + } + + @Schema(name = "ConnectorParamsDiscoveryResponse", example = ConnectorParamsDiscoveryResponse.EXAMPLE) + record ConnectorParamsDiscoveryResponse( + Object context, + String counterPartyId, + String counterPartyAddress, + String protocol + ) { + + public static final String EXAMPLE = """ + { + "@context": { + "edc": "https://w3id.org/edc/v0.0.1/ns/" + }, + "edc:counterPartyId": "did:web:one-example.com", + "edc:counterPartyAddress": "https://provider.domain.com/api/dsp/2025-1", + "edc:protocol": "dataspace-protocol-http:2025-1" + } + """; + } + + @Schema(name = "ConnectorDiscoveryRequestSchema", example = ConnectorDiscoveryRequestSchema.EXAMPLE) + record ConnectorDiscoveryRequestSchema( + @Schema(name = CONTEXT, requiredMode = REQUIRED) + Object context, + @Schema(name = JsonLdKeywords.TYPE, example = ConnectorDiscoveryRequest.TYPE) + String type, + @Schema(requiredMode = REQUIRED) + String counterPartyId, + @Schema(requiredMode = NOT_REQUIRED) + String[] knownConnectors + ) { + public static final String EXAMPLE = """ + { + "@context": { + "edc": "https://w3id.org/edc/v0.0.1/ns/", + "tx": "https://w3id.org/tractusx/v0.0.1/ns/" + }, + "@type": "tx:ConnectorServiceDiscoveryRequest", + "edc:counterPartyId": "did:web:one-example.com", + "tx:knownConnectors": [ + "https://provider.domain.com/conn1/api/dsp", + "https://provider.domain.com/conn2/api/v1/dsp" + ] + } + """; + } +} diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v3/ConnectorDiscoveryV3Controller.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v3/ConnectorDiscoveryV3Controller.java new file mode 100644 index 0000000000..46e390146e --- /dev/null +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v3/ConnectorDiscoveryV3Controller.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.discovery.api.v3; + +import jakarta.json.JsonObject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.container.AsyncResponse; +import jakarta.ws.rs.container.Suspended; +import org.eclipse.tractusx.edc.discovery.api.ConnectorDiscoveryController; + +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; + +@Consumes(APPLICATION_JSON) +@Produces(APPLICATION_JSON) +@Path("/v3/connectordiscovery") +public class ConnectorDiscoveryV3Controller implements ConnectorDiscoveryV3Api { + + private final ConnectorDiscoveryController delegate; + + public ConnectorDiscoveryV3Controller(ConnectorDiscoveryController delegate) { + this.delegate = delegate; + } + + @Path("/dspversionparams") + @POST + @Override + public void discoverDspVersionParamsV3(JsonObject inputJson, @Suspended AsyncResponse response) { + delegate.discoverDspVersionParams(inputJson, response); + } + + @Path("/connectors") + @POST + @Override + public void discoverConnectorServicesV3(JsonObject inputJson, @Suspended AsyncResponse response) { + delegate.discoverConnectorServices(inputJson, response); + } +} + diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/api/ConnectorDiscoveryV4AlphaApi.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v4alpha/ConnectorDiscoveryV4AlphaApi.java similarity index 97% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/api/ConnectorDiscoveryV4AlphaApi.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v4alpha/ConnectorDiscoveryV4AlphaApi.java index 11483203c1..ee53a56fff 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/api/ConnectorDiscoveryV4AlphaApi.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v4alpha/ConnectorDiscoveryV4AlphaApi.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.api; +package org.eclipse.tractusx.edc.discovery.api.v4alpha; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.Operation; @@ -34,13 +34,14 @@ import jakarta.ws.rs.container.Suspended; import org.eclipse.edc.jsonld.spi.JsonLdKeywords; import org.eclipse.edc.web.spi.ApiErrorDetail; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.NOT_REQUIRED; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +@Deprecated(since = "0.13.0") @OpenAPIDefinition(info = @Info( description = "With this API clients discover connectors based on published services in a DID document and " + "discover the right version parameters according to different DSP versions.", diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v4alpha/ConnectorDiscoveryV4AlphaController.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v4alpha/ConnectorDiscoveryV4AlphaController.java new file mode 100644 index 0000000000..e607abead7 --- /dev/null +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/api/v4alpha/ConnectorDiscoveryV4AlphaController.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.discovery.api.v4alpha; + +import jakarta.json.JsonObject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.container.AsyncResponse; +import jakarta.ws.rs.container.Suspended; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.discovery.api.ConnectorDiscoveryController; + +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; +import static org.eclipse.edc.api.ApiWarnings.deprecationWarning; + +@Consumes(APPLICATION_JSON) +@Produces(APPLICATION_JSON) +@Path("/v4alpha/connectordiscovery") +@Deprecated(since = "0.13.0") +public class ConnectorDiscoveryV4AlphaController implements ConnectorDiscoveryV4AlphaApi { + + private final ConnectorDiscoveryController delegate; + private final Monitor monitor; + + public ConnectorDiscoveryV4AlphaController(ConnectorDiscoveryController delegate, Monitor monitor) { + this.delegate = delegate; + this.monitor = monitor; + } + + @Path("/dspversionparams") + @POST + @Override + public void discoverDspVersionParamsV4Alpha(JsonObject inputJson, @Suspended AsyncResponse response) { + monitor.warning(deprecationWarning("/v4alpha", "/v3")); + delegate.discoverDspVersionParams(inputJson, response); + } + + @Path("/connectors") + @POST + @Override + public void discoverConnectorServicesV4Alpha(JsonObject inputJson, @Suspended AsyncResponse response) { + monitor.warning(deprecationWarning("/v4alpha", "/v3")); + delegate.discoverConnectorServices(inputJson, response); + } +} + diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/exceptions/UnexpectedResultApiException.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/exceptions/UnexpectedResultApiException.java similarity index 95% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/exceptions/UnexpectedResultApiException.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/exceptions/UnexpectedResultApiException.java index e6612406fd..bab7cb0ba0 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/exceptions/UnexpectedResultApiException.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/exceptions/UnexpectedResultApiException.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.exceptions; +package org.eclipse.tractusx.edc.discovery.exceptions; import org.eclipse.edc.web.spi.exception.EdcApiException; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/BaseConnectorDiscoveryServiceImpl.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/service/BaseConnectorDiscoveryServiceImpl.java similarity index 97% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/BaseConnectorDiscoveryServiceImpl.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/service/BaseConnectorDiscoveryServiceImpl.java index 16b9050d95..9700af9d6f 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/BaseConnectorDiscoveryServiceImpl.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/service/BaseConnectorDiscoveryServiceImpl.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.service; +package org.eclipse.tractusx.edc.discovery.service; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.json.Json; @@ -41,11 +41,11 @@ import org.eclipse.edc.util.collection.TimestampedValue; import org.eclipse.edc.web.spi.exception.BadGatewayException; import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.discovery.v4alpha.exceptions.UnexpectedResultApiException; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryService; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.exceptions.UnexpectedResultApiException; +import org.eclipse.tractusx.edc.discovery.spi.CacheConfig; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryService; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; import java.io.IOException; import java.net.MalformedURLException; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/DefaultConnectorDiscoveryServiceImpl.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/service/DefaultConnectorDiscoveryServiceImpl.java similarity index 94% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/DefaultConnectorDiscoveryServiceImpl.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/service/DefaultConnectorDiscoveryServiceImpl.java index 710e343020..db0e77d824 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/service/DefaultConnectorDiscoveryServiceImpl.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/service/DefaultConnectorDiscoveryServiceImpl.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.service; +package org.eclipse.tractusx.edc.discovery.service; import com.fasterxml.jackson.databind.ObjectMapper; import okhttp3.Response; @@ -28,7 +28,7 @@ import org.eclipse.edc.protocol.spi.ProtocolVersion; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; +import org.eclipse.tractusx.edc.discovery.spi.CacheConfig; import java.util.List; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/CacheConfig.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/CacheConfig.java similarity index 93% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/CacheConfig.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/CacheConfig.java index b3125d82f2..82fa92dd32 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/CacheConfig.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/CacheConfig.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.spi; +package org.eclipse.tractusx.edc.discovery.spi; import java.time.Clock; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorDiscoveryRequest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorDiscoveryRequest.java similarity index 96% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorDiscoveryRequest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorDiscoveryRequest.java index 60dc626771..da2b0d94ce 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorDiscoveryRequest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorDiscoveryRequest.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.spi; +package org.eclipse.tractusx.edc.discovery.spi; import java.util.Collection; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorDiscoveryService.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorDiscoveryService.java similarity index 98% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorDiscoveryService.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorDiscoveryService.java index 2bd8e2c1cd..b05cd1975f 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorDiscoveryService.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorDiscoveryService.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.spi; +package org.eclipse.tractusx.edc.discovery.spi; import jakarta.json.JsonArray; import jakarta.json.JsonObject; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorParamsDiscoveryRequest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorParamsDiscoveryRequest.java similarity index 97% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorParamsDiscoveryRequest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorParamsDiscoveryRequest.java index cdcba2efa8..6501bfbb00 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/spi/ConnectorParamsDiscoveryRequest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/spi/ConnectorParamsDiscoveryRequest.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.spi; +package org.eclipse.tractusx.edc.discovery.spi; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.TX_NAMESPACE; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/transformers/JsonObjectToConnectorDiscoveryRequest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/transformers/JsonObjectToConnectorDiscoveryRequest.java similarity index 87% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/transformers/JsonObjectToConnectorDiscoveryRequest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/transformers/JsonObjectToConnectorDiscoveryRequest.java index a908915007..0e70289dc0 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/transformers/JsonObjectToConnectorDiscoveryRequest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/transformers/JsonObjectToConnectorDiscoveryRequest.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.transformers; +package org.eclipse.tractusx.edc.discovery.transformers; import jakarta.json.JsonObject; import jakarta.json.JsonString; @@ -25,7 +25,7 @@ import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.transform.spi.TransformerContext; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,8 +34,8 @@ import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_COUNTERPARTYID_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_KNOWNCONNECTORS_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_COUNTERPARTYID_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_KNOWNCONNECTORS_ATTRIBUTE; public class JsonObjectToConnectorDiscoveryRequest extends AbstractJsonLdTransformer { diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/transformers/JsonObjectToConnectorParamsDiscoveryRequest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/transformers/JsonObjectToConnectorParamsDiscoveryRequest.java similarity index 81% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/transformers/JsonObjectToConnectorParamsDiscoveryRequest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/transformers/JsonObjectToConnectorParamsDiscoveryRequest.java index c1d7fab441..0b360e51b3 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/transformers/JsonObjectToConnectorParamsDiscoveryRequest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/transformers/JsonObjectToConnectorParamsDiscoveryRequest.java @@ -18,18 +18,18 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.transformers; +package org.eclipse.tractusx.edc.discovery.transformers; import jakarta.json.JsonObject; import org.eclipse.edc.jsonld.spi.transformer.AbstractJsonLdTransformer; import org.eclipse.edc.transform.spi.TransformerContext; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_COUNTER_PARTY_ADDRESS_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE_LEGACY; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_COUNTER_PARTY_ADDRESS_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE_LEGACY; public class JsonObjectToConnectorParamsDiscoveryRequest extends AbstractJsonLdTransformer { diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/validators/ConnectorDiscoveryRequestValidator.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/validators/ConnectorDiscoveryRequestValidator.java similarity index 90% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/validators/ConnectorDiscoveryRequestValidator.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/validators/ConnectorDiscoveryRequestValidator.java index f32e57b29f..f7c2a0d4ac 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/validators/ConnectorDiscoveryRequestValidator.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/validators/ConnectorDiscoveryRequestValidator.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.validators; +package org.eclipse.tractusx.edc.discovery.validators; import jakarta.json.JsonObject; import jakarta.json.JsonString; @@ -34,8 +34,8 @@ import java.util.ArrayList; import static org.eclipse.edc.validator.spi.Violation.violation; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_COUNTERPARTYID_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_KNOWNCONNECTORS_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_COUNTERPARTYID_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_KNOWNCONNECTORS_ATTRIBUTE; /** * Validator for the 'ConnectorDiscoveryRequest' as defined in the connector discovery api. diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/validators/ConnectorParamsDiscoveryRequestValidator.java b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/validators/ConnectorParamsDiscoveryRequestValidator.java similarity index 88% rename from edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/validators/ConnectorParamsDiscoveryRequestValidator.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/validators/ConnectorParamsDiscoveryRequestValidator.java index 524b3cedcb..4668aaa3c9 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/v4alpha/validators/ConnectorParamsDiscoveryRequestValidator.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/java/org/eclipse/tractusx/edc/discovery/validators/ConnectorParamsDiscoveryRequestValidator.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha.validators; +package org.eclipse.tractusx.edc.discovery.validators; import jakarta.json.JsonObject; import org.eclipse.edc.validator.jsonobject.JsonLdPath; @@ -28,9 +28,9 @@ import org.eclipse.edc.validator.spi.Validator; import static org.eclipse.edc.validator.spi.Violation.violation; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_COUNTER_PARTY_ADDRESS_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE_LEGACY; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_COUNTER_PARTY_ADDRESS_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE_LEGACY; /** * Validator for the 'ConnectorParamsDiscoveryRequest' as defined in the connector discovery api. diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/connector-discovery/connector-discovery-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index 87c14429e8..43fd17e006 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -17,4 +17,4 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -org.eclipse.tractusx.edc.discovery.v4alpha.ConnectorDiscoveryExtension +org.eclipse.tractusx.edc.discovery.ConnectorDiscoveryExtension diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryControllerTest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryControllerTest.java new file mode 100644 index 0000000000..f8f2744735 --- /dev/null +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryControllerTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.discovery; + +import jakarta.json.Json; +import jakarta.ws.rs.container.AsyncResponse; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.transform.spi.TypeTransformerRegistry; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; +import org.eclipse.edc.validator.spi.ValidationResult; +import org.eclipse.edc.validator.spi.Violation; +import org.eclipse.edc.web.spi.exception.ValidationFailureException; +import org.eclipse.tractusx.edc.discovery.api.ConnectorDiscoveryController; +import org.eclipse.tractusx.edc.discovery.exceptions.UnexpectedResultApiException; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryService; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class ConnectorDiscoveryControllerTest { + + private final ConnectorDiscoveryService connectorService = mock(); + private final TypeTransformerRegistry transformerRegistry = mock(); + private final JsonObjectValidatorRegistry validator = mock(); + private final Monitor monitor = mock(); + private final AsyncResponse response = mock(); + + private final ConnectorDiscoveryController controller = + new ConnectorDiscoveryController(connectorService, transformerRegistry, validator, monitor); + + @Test + void discoverDspVersionParams_shouldResumeWithResult_whenServiceSucceeds() { + var input = Json.createObjectBuilder().build(); + var expectedJson = Json.createObjectBuilder() + .add("counterPartyId", "did:web:provider") + .add("protocol", "dataspace-protocol-http:2025-1") + .build(); + var discoveryRequest = new ConnectorParamsDiscoveryRequest("test", "test"); + + when(validator.validate(ConnectorParamsDiscoveryRequest.TYPE, input)).thenReturn(ValidationResult.success()); + when(transformerRegistry.transform(input, ConnectorParamsDiscoveryRequest.class)).thenReturn(Result.success(discoveryRequest)); + when(connectorService.discoverVersionParams(discoveryRequest)).thenReturn(CompletableFuture.completedFuture(expectedJson)); + + controller.discoverDspVersionParams(input, response); + + verify(response).resume(expectedJson); + } + + @Test + void discoverDspVersionParams_shouldResumeWithCauseAndWarn_whenServiceFails() { + var input = Json.createObjectBuilder().build(); + var discoveryRequest = new ConnectorParamsDiscoveryRequest("test", "test"); + var error = new UnexpectedResultApiException("test error"); + + when(validator.validate(ConnectorParamsDiscoveryRequest.TYPE, input)).thenReturn(ValidationResult.success()); + when(transformerRegistry.transform(input, ConnectorParamsDiscoveryRequest.class)).thenReturn(Result.success(discoveryRequest)); + when(connectorService.discoverVersionParams(discoveryRequest)).thenReturn(CompletableFuture.failedFuture(error)); + + controller.discoverDspVersionParams(input, response); + + verify(response).resume(error); + verify(monitor).warning(eq("Exception thrown during connector discovery"), any(Throwable.class)); + } + + @Test + void discoverDspVersionParams_shouldThrowValidationFailure_whenValidationFails() { + var input = Json.createObjectBuilder().build(); + + when(validator.validate(eq(ConnectorParamsDiscoveryRequest.TYPE), any())) + .thenThrow(new ValidationFailureException(List.of(new Violation("invalidField", "invalidField", "Invalid field")))); + + assertThatThrownBy(() -> controller.discoverDspVersionParams(input, response)) + .isInstanceOf(ValidationFailureException.class); + } + + @Test + void discoverDspVersionParams_shouldThrowUnexpectedResult_whenTransformFails() { + var input = Json.createObjectBuilder().build(); + + when(validator.validate(ConnectorParamsDiscoveryRequest.TYPE, input)).thenReturn(ValidationResult.success()); + when(transformerRegistry.transform(input, ConnectorParamsDiscoveryRequest.class)).thenReturn(Result.failure("cannot transform")); + + assertThatThrownBy(() -> controller.discoverDspVersionParams(input, response)) + .isInstanceOf(UnexpectedResultApiException.class); + } + + @Test + void discoverConnectorServices_shouldResumeWithResult_whenServiceSucceeds() { + var input = Json.createObjectBuilder().build(); + var expectedJson = Json.createArrayBuilder().add(Json.createObjectBuilder() + .add("counterPartyAddress", "https://example.com/api/v1/dsp/2025-1") + .add("counterPartyId", "did:web:provider") + .add("protocol", "dataspace-protocol-http:2025-1")) + .build(); + var discoveryRequest = new ConnectorDiscoveryRequest("test", List.of("https://example.com/api/v1/dsp")); + + when(validator.validate(ConnectorDiscoveryRequest.TYPE, input)).thenReturn(ValidationResult.success()); + when(transformerRegistry.transform(input, ConnectorDiscoveryRequest.class)).thenReturn(Result.success(discoveryRequest)); + when(connectorService.discoverConnectors(discoveryRequest)).thenReturn(CompletableFuture.completedFuture(expectedJson)); + + controller.discoverConnectorServices(input, response); + + verify(response).resume(expectedJson); + } + + @Test + void discoverConnectorServices_shouldResumeWithCauseAndWarn_whenServiceFails() { + var input = Json.createObjectBuilder().build(); + var discoveryRequest = new ConnectorDiscoveryRequest("test", List.of("https://example.com/api/v1/dsp")); + var error = new UnexpectedResultApiException("test error"); + + when(validator.validate(ConnectorDiscoveryRequest.TYPE, input)).thenReturn(ValidationResult.success()); + when(transformerRegistry.transform(input, ConnectorDiscoveryRequest.class)).thenReturn(Result.success(discoveryRequest)); + when(connectorService.discoverConnectors(discoveryRequest)).thenReturn(CompletableFuture.failedFuture(error)); + + controller.discoverConnectorServices(input, response); + + verify(response).resume(error); + verify(monitor).warning(eq("Exception thrown during connector discovery"), any(Throwable.class)); + } + + @Test + void discoverConnectorServices_shouldThrowValidationFailure_whenValidationFails() { + var input = Json.createObjectBuilder().build(); + + when(validator.validate(eq(ConnectorDiscoveryRequest.TYPE), any())) + .thenThrow(new ValidationFailureException(List.of(new Violation("invalidField", "invalidField", "Invalid field")))); + + assertThatThrownBy(() -> controller.discoverConnectorServices(input, response)) + .isInstanceOf(ValidationFailureException.class); + } + + @Test + void discoverConnectorServices_shouldThrowUnexpectedResult_whenTransformFails() { + var input = Json.createObjectBuilder().build(); + + when(validator.validate(ConnectorDiscoveryRequest.TYPE, input)).thenReturn(ValidationResult.success()); + when(transformerRegistry.transform(input, ConnectorDiscoveryRequest.class)).thenReturn(Result.failure("cannot transform")); + + assertThatThrownBy(() -> controller.discoverConnectorServices(input, response)) + .isInstanceOf(UnexpectedResultApiException.class); + } +} + + + diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryRequestValidatorTest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryRequestValidatorTest.java similarity index 93% rename from edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryRequestValidatorTest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryRequestValidatorTest.java index d634c1b4f4..6e63b10fd4 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryRequestValidatorTest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorDiscoveryRequestValidatorTest.java @@ -17,13 +17,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha; +package org.eclipse.tractusx.edc.discovery; import jakarta.json.Json; import jakarta.json.JsonArrayBuilder; import jakarta.json.JsonObject; import org.eclipse.edc.validator.spi.Validator; -import org.eclipse.tractusx.edc.discovery.v4alpha.validators.ConnectorDiscoveryRequestValidator; +import org.eclipse.tractusx.edc.discovery.validators.ConnectorDiscoveryRequestValidator; import org.junit.jupiter.api.Test; import java.util.Collection; @@ -35,8 +35,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VALUE; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_COUNTERPARTYID_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_KNOWNCONNECTORS_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_COUNTERPARTYID_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_KNOWNCONNECTORS_ATTRIBUTE; public class ConnectorDiscoveryRequestValidatorTest { diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorParamsDiscoveryRequestValidatorTest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorParamsDiscoveryRequestValidatorTest.java similarity index 88% rename from edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorParamsDiscoveryRequestValidatorTest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorParamsDiscoveryRequestValidatorTest.java index e3824ae985..126cd3f075 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorParamsDiscoveryRequestValidatorTest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/ConnectorParamsDiscoveryRequestValidatorTest.java @@ -18,13 +18,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha; +package org.eclipse.tractusx.edc.discovery; import jakarta.json.Json; import jakarta.json.JsonArrayBuilder; import jakarta.json.JsonObject; import org.eclipse.edc.validator.spi.Validator; -import org.eclipse.tractusx.edc.discovery.v4alpha.validators.ConnectorParamsDiscoveryRequestValidator; +import org.eclipse.tractusx.edc.discovery.validators.ConnectorParamsDiscoveryRequestValidator; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; @@ -38,9 +38,9 @@ import static jakarta.json.Json.createObjectBuilder; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VALUE; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_COUNTER_PARTY_ADDRESS_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE_LEGACY; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_COUNTER_PARTY_ADDRESS_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE_LEGACY; import static org.junit.jupiter.params.provider.Arguments.of; class ConnectorParamsDiscoveryRequestValidatorTest { diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/DefaultConnectorDiscoveryServiceImplTest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/DefaultConnectorDiscoveryServiceImplTest.java similarity index 97% rename from edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/DefaultConnectorDiscoveryServiceImplTest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/DefaultConnectorDiscoveryServiceImplTest.java index 416496e924..9e2482ccaa 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/DefaultConnectorDiscoveryServiceImplTest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/DefaultConnectorDiscoveryServiceImplTest.java @@ -18,7 +18,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha; +package org.eclipse.tractusx.edc.discovery; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.json.Json; @@ -36,12 +36,12 @@ import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.web.spi.exception.BadGatewayException; import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.discovery.v4alpha.exceptions.UnexpectedResultApiException; -import org.eclipse.tractusx.edc.discovery.v4alpha.service.DefaultConnectorDiscoveryServiceImpl; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryService; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.exceptions.UnexpectedResultApiException; +import org.eclipse.tractusx.edc.discovery.service.DefaultConnectorDiscoveryServiceImpl; +import org.eclipse.tractusx.edc.discovery.spi.CacheConfig; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryService; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/JsonObjectToConnectorDiscoveryRequestTest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/JsonObjectToConnectorDiscoveryRequestTest.java similarity index 89% rename from edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/JsonObjectToConnectorDiscoveryRequestTest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/JsonObjectToConnectorDiscoveryRequestTest.java index 1255b1137b..6265176a3a 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/JsonObjectToConnectorDiscoveryRequestTest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/JsonObjectToConnectorDiscoveryRequestTest.java @@ -17,16 +17,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha; +package org.eclipse.tractusx.edc.discovery; import jakarta.json.Json; import org.eclipse.edc.transform.spi.TransformerContext; -import org.eclipse.tractusx.edc.discovery.v4alpha.transformers.JsonObjectToConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.transformers.JsonObjectToConnectorDiscoveryRequest; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_COUNTERPARTYID_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_KNOWNCONNECTORS_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_COUNTERPARTYID_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest.CONNECTOR_DISCOVERY_REQUEST_KNOWNCONNECTORS_ATTRIBUTE; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/JsonObjectToConnectorParamsDiscoveryRequestTest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/JsonObjectToConnectorParamsDiscoveryRequestTest.java similarity index 88% rename from edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/JsonObjectToConnectorParamsDiscoveryRequestTest.java rename to edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/JsonObjectToConnectorParamsDiscoveryRequestTest.java index babb44303b..200ccf0f06 100644 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/JsonObjectToConnectorParamsDiscoveryRequestTest.java +++ b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/JsonObjectToConnectorParamsDiscoveryRequestTest.java @@ -18,11 +18,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.discovery.v4alpha; +package org.eclipse.tractusx.edc.discovery; import jakarta.json.Json; import org.eclipse.edc.transform.spi.TransformerContext; -import org.eclipse.tractusx.edc.discovery.v4alpha.transformers.JsonObjectToConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.transformers.JsonObjectToConnectorParamsDiscoveryRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; @@ -33,9 +33,9 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_COUNTER_PARTY_ADDRESS_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE; -import static org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE_LEGACY; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_COUNTER_PARTY_ADDRESS_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE; +import static org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest.DISCOVERY_PARAMS_REQUEST_IDENTIFIER_ATTRIBUTE_LEGACY; import static org.junit.jupiter.params.provider.Arguments.of; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryV4AlphaControllerTest.java b/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryV4AlphaControllerTest.java deleted file mode 100644 index 3a5b0001b0..0000000000 --- a/edc-extensions/connector-discovery/connector-discovery-api/src/test/java/org/eclipse/tractusx/edc/discovery/v4alpha/ConnectorDiscoveryV4AlphaControllerTest.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2026 Cofinity-X GmbH - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.eclipse.tractusx.edc.discovery.v4alpha; - -import io.restassured.http.ContentType; -import io.restassured.specification.RequestSpecification; -import jakarta.json.Json; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.edc.transform.spi.TypeTransformerRegistry; -import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; -import org.eclipse.edc.validator.spi.ValidationResult; -import org.eclipse.edc.validator.spi.Violation; -import org.eclipse.edc.web.jersey.testfixtures.RestControllerTestBase; -import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.edc.web.spi.exception.ValidationFailureException; -import org.eclipse.tractusx.edc.discovery.v4alpha.api.ConnectorDiscoveryV4AlphaController; -import org.eclipse.tractusx.edc.discovery.v4alpha.exceptions.UnexpectedResultApiException; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryService; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest; -import org.junit.jupiter.api.Test; - -import java.io.StringReader; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import static io.restassured.RestAssured.given; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -class ConnectorDiscoveryV4AlphaControllerTest extends RestControllerTestBase { - - private final ConnectorDiscoveryService connectorService = mock(); - private final TypeTransformerRegistry transformerRegistry = mock(); - private final JsonObjectValidatorRegistry validator = mock(); - private final Monitor monitor = mock(); - - @Override - protected Object controller() { - return new ConnectorDiscoveryV4AlphaController(connectorService, transformerRegistry, validator, monitor); - } - - @Test - void connectorParamsDiscovery_shouldReturnSuccess() { - var input = Json.createObjectBuilder().build(); - var expectedJson = Json.createObjectBuilder() - .add("counterPartyId", "did:web:provider") - .add("protocol", "dataspace-protocol-http:2025-1") - .build(); - - var discoveryRequest = new ConnectorParamsDiscoveryRequest("test", "test"); - - when(validator.validate(ConnectorParamsDiscoveryRequest.TYPE, input)) - .thenReturn(ValidationResult.success()); - when(transformerRegistry.transform(input, ConnectorParamsDiscoveryRequest.class)) - .thenReturn(Result.success(discoveryRequest)); - when(connectorService.discoverVersionParams(discoveryRequest)) - .thenReturn(CompletableFuture.completedFuture(expectedJson)); - - var resultString = baseRequest("/dspversionparams") - .contentType(ContentType.JSON) - .body(input) - .post() - .then() - .log().ifError() - .statusCode(200) - .extract().body().asString(); - - var resultJson = Json.createReader(new StringReader(resultString)).readObject(); - - assertThat(resultJson).isEqualTo(expectedJson); - } - - @Test - void connectorParamsDiscovery_shouldReturnFailure_whenServiceFails() { - - var input = Json.createObjectBuilder().build(); - var discoveryRequest = new ConnectorParamsDiscoveryRequest("test", "test"); - - when(validator.validate(ConnectorParamsDiscoveryRequest.TYPE, input)) - .thenReturn(ValidationResult.success()); - when(transformerRegistry.transform(input, ConnectorParamsDiscoveryRequest.class)) - .thenReturn(Result.success(discoveryRequest)); - when(connectorService.discoverVersionParams(discoveryRequest)) - .thenReturn(CompletableFuture.failedFuture(new UnexpectedResultApiException("test error"))); - - baseRequest("/dspversionparams") - .contentType(ContentType.JSON) - .body(input) - .post() - .then() - .log().ifError() - .statusCode(500); - } - - @Test - void connectorParamsDiscovery_shouldReturnFailureBadRequest_whenServiceFails() { - - var input = Json.createObjectBuilder().build(); - var discoveryRequest = new ConnectorParamsDiscoveryRequest("test", "test"); - - when(validator.validate(ConnectorParamsDiscoveryRequest.TYPE, input)) - .thenReturn(ValidationResult.success()); - when(transformerRegistry.transform(input, ConnectorParamsDiscoveryRequest.class)) - .thenReturn(Result.success(discoveryRequest)); - when(connectorService.discoverVersionParams(discoveryRequest)) - .thenReturn(CompletableFuture.failedFuture(new InvalidRequestException("test error"))); - - baseRequest("/dspversionparams") - .contentType(ContentType.JSON) - .body(input) - .post() - .then() - .log().ifError() - .statusCode(400); - } - - @Test - void connectorParamsDiscovery_shouldReturnValidationFailure_whenValidationFails() { - - when(validator.validate(eq(ConnectorParamsDiscoveryRequest.TYPE), any())) - .thenThrow(new ValidationFailureException(List.of(new Violation("invalidField", "invalidField", "Invalid field")))); - - baseRequest("/dspversionparams") - .contentType(ContentType.JSON) - .body("") - .post() - .then() - .log().ifError() - .statusCode(400); - } - - @Test - void connectorServiceDiscovery_shouldReturnSuccess() { - var input = Json.createObjectBuilder().build(); - var expectedJson = Json.createArrayBuilder().add(Json.createObjectBuilder() - .add("counterPartyAddress", "https://example.com/api/v1/dsp/2025-1") - .add("counterPartyId", "did:web:provider") - .add("protocol", "dataspace-protocol-http:2025-1")) - .build(); - - var discoveryRequest = new ConnectorDiscoveryRequest("test", List.of("https://example.com/api/v1/dsp")); - - when(validator.validate(ConnectorDiscoveryRequest.TYPE, input)) - .thenReturn(ValidationResult.success()); - when(transformerRegistry.transform(input, ConnectorDiscoveryRequest.class)) - .thenReturn(Result.success(discoveryRequest)); - when(connectorService.discoverConnectors(discoveryRequest)) - .thenReturn(CompletableFuture.completedFuture(expectedJson)); - - var resultString = baseRequest("/connectors") - .contentType(ContentType.JSON) - .body(input) - .post() - .then() - .log().ifError() - .statusCode(200) - .extract().body().asString(); - - var resultJson = Json.createReader(new StringReader(resultString)).readArray(); - - assertThat(resultJson).isEqualTo(expectedJson); - } - - @Test - void connectorServiceDiscovery_shouldReturnFailure_whenServiceFails() { - - var input = Json.createObjectBuilder().build(); - var discoveryRequest = new ConnectorDiscoveryRequest("test", List.of("https://example.com/api/v1/dsp")); - - when(validator.validate(ConnectorDiscoveryRequest.TYPE, input)) - .thenReturn(ValidationResult.success()); - when(transformerRegistry.transform(input, ConnectorDiscoveryRequest.class)) - .thenReturn(Result.success(discoveryRequest)); - when(connectorService.discoverConnectors(discoveryRequest)) - .thenReturn(CompletableFuture.failedFuture(new UnexpectedResultApiException("test error"))); - - baseRequest("/connectors") - .contentType(ContentType.JSON) - .body(input) - .post() - .then() - .log().ifError() - .statusCode(500); - } - - @Test - void connectorServiceDiscovery_shouldReturnFailureBadRequest_whenServiceFails() { - - var input = Json.createObjectBuilder().build(); - var discoveryRequest = new ConnectorDiscoveryRequest("test", List.of("https://example.com/api/v1/dsp")); - - when(validator.validate(ConnectorDiscoveryRequest.TYPE, input)) - .thenReturn(ValidationResult.success()); - when(transformerRegistry.transform(input, ConnectorDiscoveryRequest.class)) - .thenReturn(Result.success(discoveryRequest)); - when(connectorService.discoverConnectors(discoveryRequest)) - .thenReturn(CompletableFuture.failedFuture(new InvalidRequestException("test error"))); - - baseRequest("/connectors") - .contentType(ContentType.JSON) - .body(input) - .post() - .then() - .log().ifError() - .statusCode(400); - } - - @Test - void connectorServiceDiscovery_shouldReturnValidationFailure_whenValidationFails() { - - when(validator.validate(eq(ConnectorDiscoveryRequest.TYPE), any())) - .thenThrow(new ValidationFailureException(List.of(new Violation("invalidField", "invalidField", "Invalid field")))); - - baseRequest("/connectors") - .contentType(ContentType.JSON) - .body("") - .post() - .then() - .log().ifError() - .statusCode(400); - } - - private RequestSpecification baseRequest(String path) { - return given() - .baseUri("http://localhost:" + port) - .basePath("/v4alpha/connectordiscovery" + path) - .when(); - } -} diff --git a/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/ConnectorDiscoveryBpnlAndDsp08ServiceExtension.java b/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/ConnectorDiscoveryBpnlAndDsp08ServiceExtension.java index fdda0ecca1..8096cb9c08 100644 --- a/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/ConnectorDiscoveryBpnlAndDsp08ServiceExtension.java +++ b/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/ConnectorDiscoveryBpnlAndDsp08ServiceExtension.java @@ -30,14 +30,14 @@ import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.tractusx.edc.discovery.cx.service.BpnlAndDsp08ConnectorDiscoveryServiceImpl; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryService; +import org.eclipse.tractusx.edc.discovery.spi.CacheConfig; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryService; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import java.time.Clock; -import static org.eclipse.tractusx.edc.discovery.v4alpha.ConnectorDiscoveryExtension.DEFAULT_CACHE_EXPIRY_MS; -import static org.eclipse.tractusx.edc.discovery.v4alpha.ConnectorDiscoveryExtension.TX_EDC_CONNECTOR_DISCOVERY_CACHE_EXPIRY; +import static org.eclipse.tractusx.edc.discovery.ConnectorDiscoveryExtension.DEFAULT_CACHE_EXPIRY_MS; +import static org.eclipse.tractusx.edc.discovery.ConnectorDiscoveryExtension.TX_EDC_CONNECTOR_DISCOVERY_CACHE_EXPIRY; @Extension(value = ConnectorDiscoveryBpnlAndDsp08ServiceExtension.NAME) public class ConnectorDiscoveryBpnlAndDsp08ServiceExtension implements ServiceExtension { diff --git a/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/service/BpnlAndDsp08ConnectorDiscoveryServiceImpl.java b/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/service/BpnlAndDsp08ConnectorDiscoveryServiceImpl.java index 61595132b4..6f2695cf05 100644 --- a/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/service/BpnlAndDsp08ConnectorDiscoveryServiceImpl.java +++ b/edc-extensions/connector-discovery/cx-connector-discovery/src/main/java/org/eclipse/tractusx/edc/discovery/cx/service/BpnlAndDsp08ConnectorDiscoveryServiceImpl.java @@ -30,9 +30,9 @@ import org.eclipse.edc.protocol.spi.ProtocolVersion; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.web.spi.exception.InvalidRequestException; -import org.eclipse.tractusx.edc.discovery.v4alpha.service.BaseConnectorDiscoveryServiceImpl; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.service.BaseConnectorDiscoveryServiceImpl; +import org.eclipse.tractusx.edc.discovery.spi.CacheConfig; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import java.util.List; diff --git a/edc-extensions/connector-discovery/cx-connector-discovery/src/test/java/org/eclipse/tractusx/edc/discovery/cx/BpnlAndDsp08ConnectorDiscoveryServiceImplTest.java b/edc-extensions/connector-discovery/cx-connector-discovery/src/test/java/org/eclipse/tractusx/edc/discovery/cx/BpnlAndDsp08ConnectorDiscoveryServiceImplTest.java index 57ab2937d7..6e1c2b8511 100644 --- a/edc-extensions/connector-discovery/cx-connector-discovery/src/test/java/org/eclipse/tractusx/edc/discovery/cx/BpnlAndDsp08ConnectorDiscoveryServiceImplTest.java +++ b/edc-extensions/connector-discovery/cx-connector-discovery/src/test/java/org/eclipse/tractusx/edc/discovery/cx/BpnlAndDsp08ConnectorDiscoveryServiceImplTest.java @@ -36,9 +36,9 @@ import org.eclipse.edc.web.spi.exception.BadGatewayException; import org.eclipse.edc.web.spi.exception.InvalidRequestException; import org.eclipse.tractusx.edc.discovery.cx.service.BpnlAndDsp08ConnectorDiscoveryServiceImpl; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.CacheConfig; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorDiscoveryRequest; -import org.eclipse.tractusx.edc.discovery.v4alpha.spi.ConnectorParamsDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.CacheConfig; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorDiscoveryRequest; +import org.eclipse.tractusx.edc.discovery.spi.ConnectorParamsDiscoveryRequest; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; diff --git a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApiController.java b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiController.java similarity index 75% rename from edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApiController.java rename to edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiController.java index 4d82dbc279..2da4d4aba1 100644 --- a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApiController.java +++ b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiController.java @@ -17,25 +17,20 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.dataflow.api.v4alpha; +package org.eclipse.tractusx.edc.dataflow.api; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; import org.eclipse.edc.connector.dataplane.spi.DataFlow; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.tractusx.edc.spi.dataflow.DataFlowService; -import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; import static java.lang.String.format; import static org.eclipse.edc.web.spi.exception.ServiceResultHandler.exceptionMapper; -@Consumes(APPLICATION_JSON) -@Produces(APPLICATION_JSON) -@Path("/v4alpha/dataflows") -public class DataFlowApiController implements DataFlowApi { +/** + * Holds the version-independent data flow API logic. Version specific controllers (e.g. v3, v4alpha) + * delegate the actual work to this controller. + */ +public class DataFlowApiController { private final Monitor monitor; private final DataFlowService service; @@ -45,13 +40,10 @@ public DataFlowApiController(Monitor monitor, DataFlowService service) { this.service = service; } - @POST - @Path("/{id}/trigger") - @Override - public void triggerDataTransferV4Alpha(@PathParam("id") String id) { + public void trigger(String id) { service.trigger(id) .onSuccess(v -> monitor.debug(format("Trigger requested for dataflow with ID %s", id))) .orElseThrow(exceptionMapper(DataFlow.class, id)); } - } + diff --git a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiExtension.java b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiExtension.java index bb85a56bd5..19fc2b98e1 100644 --- a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiExtension.java +++ b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiExtension.java @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -26,7 +27,8 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; -import org.eclipse.tractusx.edc.dataflow.api.v4alpha.DataFlowApiController; +import org.eclipse.tractusx.edc.dataflow.api.v3.DataFlowV3ApiController; +import org.eclipse.tractusx.edc.dataflow.api.v4alpha.DataFlowV4AlphaApiController; import org.eclipse.tractusx.edc.spi.dataflow.DataFlowService; @Extension(DataFlowApiExtension.NAME) @@ -48,7 +50,9 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - webService.registerResource(ApiContext.MANAGEMENT, new DataFlowApiController(monitor, dataFlowService)); + var dataFlowApiController = new DataFlowApiController(monitor, dataFlowService); + webService.registerResource(ApiContext.MANAGEMENT, new DataFlowV4AlphaApiController(dataFlowApiController, monitor)); + webService.registerResource(ApiContext.MANAGEMENT, new DataFlowV3ApiController(dataFlowApiController)); } } diff --git a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v3/DataFlowV3Api.java b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v3/DataFlowV3Api.java new file mode 100644 index 0000000000..bdcefc398f --- /dev/null +++ b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v3/DataFlowV3Api.java @@ -0,0 +1,49 @@ +/******************************************************************************** + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.dataflow.api.v3; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.links.Link; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.eclipse.edc.api.model.ApiCoreSchema; + +@OpenAPIDefinition(info = @Info(version = "v3")) +@Tag(name = "DataFlow API V3") +public interface DataFlowV3Api { + + String ASYNC_WARNING = "Due to the asynchronous nature of transfers, a successful response only indicates that the request was successfully received."; + + @Operation(description = "Requests the trigger of a data transfer. " + ASYNC_WARNING, + responses = { + @ApiResponse(responseCode = "204", description = "Request was sucessfully received", links = @Link(name = "poll-state", operationId = "triggerDataTransferV3")), + @ApiResponse(responseCode = "400", description = "Request was malformed", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), + @ApiResponse(responseCode = "404", description = "Data flow with the given ID does not exist", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), + @ApiResponse(responseCode = "409", description = "Data flow is not in a required state", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) + } + ) + void triggerDataTransferV3(String id); + +} diff --git a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v3/DataFlowV3ApiController.java b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v3/DataFlowV3ApiController.java new file mode 100644 index 0000000000..7545d457ba --- /dev/null +++ b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v3/DataFlowV3ApiController.java @@ -0,0 +1,50 @@ +/******************************************************************************** + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.dataflow.api.v3; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import org.eclipse.tractusx.edc.dataflow.api.DataFlowApiController; + +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; + +@Consumes(APPLICATION_JSON) +@Produces(APPLICATION_JSON) +@Path("/v3/dataflows") +public class DataFlowV3ApiController implements DataFlowV3Api { + + private final DataFlowApiController delegate; + + public DataFlowV3ApiController(DataFlowApiController delegate) { + this.delegate = delegate; + } + + @POST + @Path("/{id}/trigger") + @Override + public void triggerDataTransferV3(@PathParam("id") String id) { + delegate.trigger(id); + } + +} diff --git a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApi.java b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowV4AlphaApi.java similarity index 97% rename from edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApi.java rename to edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowV4AlphaApi.java index 13098dc740..1c52271ee0 100644 --- a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApi.java +++ b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowV4AlphaApi.java @@ -30,9 +30,10 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.eclipse.edc.api.model.ApiCoreSchema; +@Deprecated(since = "0.13.0") @OpenAPIDefinition(info = @Info(version = "v4alpha")) @Tag(name = "DataFlow API V4Alpha") -public interface DataFlowApi { +public interface DataFlowV4AlphaApi { String ASYNC_WARNING = "Due to the asynchronous nature of transfers, a successful response only indicates that the request was successfully received."; diff --git a/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowV4AlphaApiController.java b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowV4AlphaApiController.java new file mode 100644 index 0000000000..4b17333e48 --- /dev/null +++ b/edc-extensions/dataplane/dataflow/dataflow-api/src/main/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowV4AlphaApiController.java @@ -0,0 +1,56 @@ +/******************************************************************************** + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 Cofinity-X GmbH + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.dataflow.api.v4alpha; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.dataflow.api.DataFlowApiController; + +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; +import static org.eclipse.edc.api.ApiWarnings.deprecationWarning; + +@Deprecated(since = "0.13.0") +@Consumes(APPLICATION_JSON) +@Produces(APPLICATION_JSON) +@Path("/v4alpha/dataflows") +public class DataFlowV4AlphaApiController implements DataFlowV4AlphaApi { + + private final DataFlowApiController delegate; + private final Monitor monitor; + + public DataFlowV4AlphaApiController(DataFlowApiController delegate, Monitor monitor) { + this.delegate = delegate; + this.monitor = monitor; + } + + @POST + @Path("/{id}/trigger") + @Override + public void triggerDataTransferV4Alpha(@PathParam("id") String id) { + monitor.warning(deprecationWarning("/v4alpha", "/v3")); + delegate.trigger(id); + } + +} diff --git a/edc-extensions/dataplane/dataflow/dataflow-api/src/test/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiControllerTest.java b/edc-extensions/dataplane/dataflow/dataflow-api/src/test/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiControllerTest.java new file mode 100644 index 0000000000..0c2342db24 --- /dev/null +++ b/edc-extensions/dataplane/dataflow/dataflow-api/src/test/java/org/eclipse/tractusx/edc/dataflow/api/DataFlowApiControllerTest.java @@ -0,0 +1,84 @@ +/******************************************************************************** + * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.dataflow.api; + +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.ServiceResult; +import org.eclipse.edc.web.spi.exception.InvalidRequestException; +import org.eclipse.edc.web.spi.exception.ObjectConflictException; +import org.eclipse.edc.web.spi.exception.ObjectNotFoundException; +import org.eclipse.tractusx.edc.spi.dataflow.DataFlowService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class DataFlowApiControllerTest { + + private static final String DATAFLOW_ID = "123"; + + private final Monitor monitor = mock(); + private final DataFlowService service = mock(); + + private DataFlowApiController controller; + + @BeforeEach + void setUp() { + when(monitor.withPrefix(anyString())).thenReturn(monitor); + controller = new DataFlowApiController(monitor, service); + } + + @Test + void trigger_shouldSucceed_whenServiceReturnsSuccess() { + when(service.trigger(DATAFLOW_ID)).thenReturn(ServiceResult.success()); + + assertThatNoException().isThrownBy(() -> controller.trigger(DATAFLOW_ID)); + + verify(service).trigger(DATAFLOW_ID); + } + + @Test + void trigger_shouldThrowObjectNotFound_whenServiceReturnsNotFound() { + when(service.trigger(DATAFLOW_ID)).thenReturn(ServiceResult.notFound("not-found")); + + assertThatThrownBy(() -> controller.trigger(DATAFLOW_ID)).isInstanceOf(ObjectNotFoundException.class); + } + + @Test + void trigger_shouldThrowInvalidRequest_whenServiceReturnsBadRequest() { + when(service.trigger(DATAFLOW_ID)).thenReturn(ServiceResult.badRequest("bad-request")); + + assertThatThrownBy(() -> controller.trigger(DATAFLOW_ID)).isInstanceOf(InvalidRequestException.class); + } + + @Test + void trigger_shouldThrowObjectConflict_whenServiceReturnsConflict() { + when(service.trigger(DATAFLOW_ID)).thenReturn(ServiceResult.conflict("conflict")); + + assertThatThrownBy(() -> controller.trigger(DATAFLOW_ID)).isInstanceOf(ObjectConflictException.class); + } + +} + diff --git a/edc-extensions/dataplane/dataflow/dataflow-api/src/test/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApiControllerTest.java b/edc-extensions/dataplane/dataflow/dataflow-api/src/test/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApiControllerTest.java deleted file mode 100644 index 7926222676..0000000000 --- a/edc-extensions/dataplane/dataflow/dataflow-api/src/test/java/org/eclipse/tractusx/edc/dataflow/api/v4alpha/DataFlowApiControllerTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * 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. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -package org.eclipse.tractusx.edc.dataflow.api.v4alpha; - -import io.restassured.specification.RequestSpecification; -import org.eclipse.edc.junit.annotations.ApiTest; -import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.edc.web.jersey.testfixtures.RestControllerTestBase; -import org.eclipse.tractusx.edc.spi.dataflow.DataFlowService; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import static io.restassured.RestAssured.given; -import static io.restassured.http.ContentType.JSON; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@ApiTest -class DataFlowApiControllerTest extends RestControllerTestBase { - - private static final String DATAFLOW_ID = "123"; - - private final DataFlowService service = mock(); - - @Override - protected Object controller() { - when(monitor.withPrefix(anyString())).thenReturn(monitor); - return new DataFlowApiController(monitor, service); - } - - private RequestSpecification baseRequest() { - return given() - .baseUri("http://localhost:" + port) - .basePath("/v4alpha/dataflows"); - } - - @Nested - class Trigger { - - @Test - void triggerDataTransfer_shouldReturnNotFound_whenServiceReturnsNotFound() { - when(service.trigger(DATAFLOW_ID)).thenReturn(ServiceResult.notFound("not-found")); - - baseRequest() - .when() - .contentType(JSON) - .post("/{id}/trigger", DATAFLOW_ID) - .then() - .statusCode(404); - } - - @Test - void triggerDataTransfer_shouldReturnBadRequest_whenServiceReturnsBadRequest() { - when(service.trigger(DATAFLOW_ID)).thenReturn(ServiceResult.badRequest("bad-request")); - - baseRequest() - .when() - .contentType(JSON) - .post("/{id}/trigger", DATAFLOW_ID) - .then() - .statusCode(400); - } - - @Test - void triggerDataTransfer_shouldReturnConflict_whenServiceReturnsConflict() { - when(service.trigger(DATAFLOW_ID)).thenReturn(ServiceResult.conflict("conflict")); - - baseRequest() - .when() - .contentType(JSON) - .post("/{id}/trigger", DATAFLOW_ID) - .then() - .statusCode(409); - } - - @Test - void triggerDataTransfer_shouldReturnNoContent_whenServiceReturnsSuccess() { - when(service.trigger(DATAFLOW_ID)).thenReturn(ServiceResult.success()); - - baseRequest() - .when() - .contentType(JSON) - .post("/{id}/trigger", DATAFLOW_ID) - .then() - .log().ifError() - .statusCode(204); - } - - } - -} diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java index 839156c9d1..1c62a7fee3 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java @@ -295,7 +295,7 @@ public String getTransferProcessField(String transferProcessId, String fieldName public void triggerDataTransfer(String dataFlowId) { baseManagementRequest() - .basePath("v4alpha") + .basePath("v3") .contentType(JSON) .when() .post("/dataflows/{id}/trigger", dataFlowId) @@ -306,7 +306,7 @@ public void triggerDataTransfer(String dataFlowId) { public ValidatableResponse discoverDspParameters(JsonObject requestBody) { return baseManagementRequest() - .basePath("v4alpha") + .basePath("v3") .contentType(JSON) .body(requestBody) .when() @@ -316,7 +316,7 @@ public ValidatableResponse discoverDspParameters(JsonObject requestBody) { public ValidatableResponse discoverConnectorServices(JsonObject requestBody) { return baseManagementRequest() - .basePath("v4alpha") + .basePath("v3") .contentType(JSON) .body(requestBody) .when() diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DataFlowApiEndToEndTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DataFlowApiEndToEndTest.java index e814d0bb1d..a3d53890f0 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DataFlowApiEndToEndTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DataFlowApiEndToEndTest.java @@ -171,7 +171,7 @@ private DataAddress.Builder dataAddressBuilder() { private ValidatableResponse triggerDataTransfer(String dataFlowId) { return PARTICIPANT.baseManagementRequest() - .basePath("/v4alpha/dataflows") + .basePath("/v3/dataflows") .when() .contentType(JSON) .post("/{id}/trigger", dataFlowId) From d162c43dcafb12fe7873435a6765e08123d6bc08 Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Thu, 9 Jul 2026 09:30:38 +0200 Subject: [PATCH 186/259] fix: make token response rfc6749 compliant (#2937) Signed-off-by: Lars Geyer-Blaumeiser --- .../api/v1/TokenRefreshApiControllerTest.java | 4 ++-- .../core/DataPlaneTokenRefreshServiceImpl.java | 2 +- .../common/tokenrefresh/TokenRefreshHandlerImplTest.java | 3 ++- .../tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java | 2 +- .../spi/tokenrefresh/dataplane/model/TokenResponse.java | 8 +++++++- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiControllerTest.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiControllerTest.java index cc76aa7b93..bd52dd654e 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiControllerTest.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-api/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/api/v1/TokenRefreshApiControllerTest.java @@ -59,7 +59,7 @@ void refresh_noAuthHeader_expect401() { @DisplayName("Expect HTTP 200 when the token was successfully refreshed and query params used") @Test void refresh_expect200query() { - when(refreshService.refreshToken(any(), any())).thenReturn(Result.success(new TokenResponse("new-accesstoken", "new-refreshtoken", 3000L, "bearer"))); + when(refreshService.refreshToken(any(), any())).thenReturn(Result.success(new TokenResponse("new-accesstoken", "new-refreshtoken", null, 3000L, "bearer"))); baseRequest() .queryParam("grant_type", "refresh_token") .queryParam("refresh_token", "foo-token") @@ -73,7 +73,7 @@ void refresh_expect200query() { @DisplayName("Expect HTTP 200 when the token was successfully refreshed and correct body used") @Test void refresh_expect200body() { - when(refreshService.refreshToken(any(), any())).thenReturn(Result.success(new TokenResponse("new-accesstoken", "new-refreshtoken", 3000L, "bearer"))); + when(refreshService.refreshToken(any(), any())).thenReturn(Result.success(new TokenResponse("new-accesstoken", "new-refreshtoken", 3000L, null, "bearer"))); baseRequest() .header(AUTHORIZATION, "auth-token") .contentType(ContentType.URLENC) diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java index cc817ca68e..87ab771466 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java @@ -216,7 +216,7 @@ public Result refreshToken(String refreshToken, String authentica monitor.severe("Failed to store refreshed access token data: %s".formatted(storeResult.getFailureDetail())); return Result.failure(storeResult.getFailureMessages()); } - return Result.success(new TokenResponse(newAccessToken.getContent(), newRefreshToken.getContent(), tokenExpirySeconds, "bearer")); + return Result.success(new TokenResponse(newAccessToken.getContent(), newRefreshToken.getContent(), tokenExpirySeconds, tokenExpirySeconds, "bearer")); } @Override diff --git a/edc-extensions/tokenrefresh-handler/src/test/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImplTest.java b/edc-extensions/tokenrefresh-handler/src/test/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImplTest.java index 49d242121c..7cd18bad68 100644 --- a/edc-extensions/tokenrefresh-handler/src/test/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImplTest.java +++ b/edc-extensions/tokenrefresh-handler/src/test/java/org/eclipse/tractusx/edc/common/tokenrefresh/TokenRefreshHandlerImplTest.java @@ -116,7 +116,8 @@ void setup() { void refresh_validateCorrectRequest() throws IOException { when(edrCache.get(anyString())).thenReturn(StoreResult.success(createEdr().build())); when(mockedTokenService.createToken(any(), anyMap(), isNull())).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("foo-auth-token").build())); - var tokenResponse = new TokenResponse("new-access-token", "new-refresh-token", 60 * 5L, "bearer"); + var expires = 60 * 5L; + var tokenResponse = new TokenResponse("new-access-token", "new-refresh-token", expires, expires, "bearer"); var successResponse = createResponse(tokenResponse, 200, ""); when(mockedHttpClient.execute(any())).thenReturn(successResponse); var res = tokenRefreshHandler.refreshToken("token-id"); diff --git a/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java b/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java index d0f0e03586..c068000a5f 100644 --- a/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java +++ b/edc-tests/e2e/edr-api-tests/src/test/java/org/eclipse/tractusx/edc/tests/edrv2/EdrCacheApiEndToEndTest.java @@ -280,7 +280,7 @@ private String tokenResponseBody() { } private String tokenResponseBody(String accessToken, String refreshToken) { - var response = new TokenResponse(accessToken, refreshToken, 300L, "bearer"); + var response = new TokenResponse(accessToken, refreshToken, null, 300L, "bearer"); try { return mapper.writeValueAsString(response); } catch (JsonProcessingException e) { diff --git a/spi/tokenrefresh-spi/src/main/java/org/eclipse/tractusx/edc/spi/tokenrefresh/dataplane/model/TokenResponse.java b/spi/tokenrefresh-spi/src/main/java/org/eclipse/tractusx/edc/spi/tokenrefresh/dataplane/model/TokenResponse.java index 148bf95d88..efff4e2d5c 100644 --- a/spi/tokenrefresh-spi/src/main/java/org/eclipse/tractusx/edc/spi/tokenrefresh/dataplane/model/TokenResponse.java +++ b/spi/tokenrefresh-spi/src/main/java/org/eclipse/tractusx/edc/spi/tokenrefresh/dataplane/model/TokenResponse.java @@ -23,6 +23,12 @@ public record TokenResponse(@JsonProperty("access_token") String accessToken, @JsonProperty("refresh_token") String refreshToken, - @JsonProperty("expires") Long expiresInSeconds, + @JsonProperty("expires") Long expiresInLegacy, // TODO: Still needed because older implementations use this non-spec-compliant value, can be removed when only 0.12.x based connectors are in the field + @JsonProperty("expires_in") Long expiresIn, @JsonProperty("token_type") String tokenType) { + + public Long expiresInSeconds() { + // Remove when the expiresInLegacy becomes obsolete, change expiresIn to expiresInSeconds + return expiresIn() != null ? expiresIn() : expiresInLegacy(); + } } From eff02c0e515e944dbbeab53380142f93d8fb5551 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 09:58:55 +0200 Subject: [PATCH 187/259] chore(deps): bump docker/setup-qemu-action (#2955) Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 4.1.0 to 4.2.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/06116385d9baf250c9f4dcb4858b16962ea869c3...96fe6ef7f33517b61c61be40b68a1882f3264fb8) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 07f2ce51b7..0c83390880 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -54,7 +54,7 @@ runs: # Enable emulation for cross-arch builds ############################################### - name: Set up QEMU - uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0 + uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0 ############################################### # Use Docker Buildx (required for multi-arch) From c3e5c140c98fd1ecfefbd15d9bab279afb25ac28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 09:59:20 +0200 Subject: [PATCH 188/259] chore(deps): bump docker/login-action (#2954) Bumps [docker/login-action](https://github.com/docker/login-action) from 4.2.0 to 4.4.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/650006c6eb7dba73a995cc03b0b2d7f5ca915bee...af1e73f918a031802d376d3c8bbc3fe56130a9b0) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: 4.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 0c83390880..6bc3f4c7c2 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -66,7 +66,7 @@ runs: # Login to DockerHub ##################### - name: DockerHub login - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0 + uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0 with: username: ${{ inputs.docker_user }} password: ${{ inputs.docker_token }} From 3e45c725c1f02185b8944df01530ca62c46e2c30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 09:59:57 +0200 Subject: [PATCH 189/259] chore(deps): bump docker/setup-buildx-action (#2953) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 4.1.0 to 4.2.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5...bb05f3f5519dd87d3ba754cc423b652a5edd6d2c) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-version: 4.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 6bc3f4c7c2..1aa2540d7a 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -60,7 +60,7 @@ runs: # Use Docker Buildx (required for multi-arch) ############################################### - name: Set up Docker Buildx - uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 + uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 ##################### # Login to DockerHub From c72a4887b834ced86b2856e693df44f55b64ab42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:00:56 +0200 Subject: [PATCH 190/259] chore(deps): bump docker/build-push-action (#2952) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.2.0 to 7.3.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/f9f3042f7e2789586610d6e8b85c8f03e5195baf...53b7df96c91f9c12dcc8a07bcb9ccacbed38856a) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-version: 7.3.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 1aa2540d7a..56886504f7 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -105,7 +105,7 @@ runs: # Build and push the image ############################### - name: Build and push - uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 + uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 env: ROOT_DIR: ${{ inputs.rootDir }} IMAGE_NAME: ${{ inputs.imagename }} From 815d8420ac5a737f738165166d22e77100fcd223 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:02:02 +0200 Subject: [PATCH 191/259] chore(deps): bump docker/metadata-action (#2951) Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 6.1.0 to 6.2.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9...dc802804100637a589fabce1cb79ff13a1411302) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-version: 6.2.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 56886504f7..73de3ee614 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -88,7 +88,7 @@ runs: # Create SemVer or ref tags dependent of trigger event - name: Docker meta id: meta - uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0 + uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 with: images: | ${{ inputs.namespace }}/${{ inputs.imagename }} From ba247611a92fe2c024c91b3c24a85f3ed8f8a28b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:02:27 +0200 Subject: [PATCH 192/259] chore(deps): bump trufflesecurity/trufflehog from 3.95.6 to 3.95.8 (#2948) Bumps [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) from 3.95.6 to 3.95.8. - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/30d5bb91af1a771378349dbbb0c82129392acf70...00155c9dc586f34d189adc83d3ac2698c2ec551f) --- updated-dependencies: - dependency-name: trufflesecurity/trufflehog dependency-version: 3.95.8 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/secrets-scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 066c78a08c..f26ff9f7be 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -53,7 +53,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@30d5bb91af1a771378349dbbb0c82129392acf70 + uses: trufflesecurity/trufflehog@00155c9dc586f34d189adc83d3ac2698c2ec551f continue-on-error: true with: path: ./ # Scan the entire repository From 09b9dc46889a0416c2f38ee0eaf077b79918c696 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:05:30 +0200 Subject: [PATCH 193/259] chore(deps): bump gradle-wrapper from 9.6.0 to 9.6.1 (#2943) Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.6.0 to 9.6.1. - [Release notes](https://github.com/gradle/gradle/releases) - [Commits](https://github.com/gradle/gradle/compare/v9.6.0...v9.6.1) --- updated-dependencies: - dependency-name: gradle-wrapper dependency-version: 9.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index eb84db68da..a9db11550c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip networkTimeout=10000 retries=0 retryBackOffMs=500 From 3d4408c9e4302d820c2ddfa635e400f80e6462cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:05:53 +0200 Subject: [PATCH 194/259] chore(deps): bump aws from 2.46.17 to 2.46.21 (#2942) Bumps `aws` from 2.46.17 to 2.46.21. Updates `software.amazon.awssdk:s3` from 2.46.17 to 2.46.21 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.46.17 to 2.46.21 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.46.21 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.46.21 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7cbed602cd..e2783cfd95 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.3" awaitility = "4.3.0" -aws = "2.46.17" +aws = "2.46.21" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" From 1b8a9b897ec12ab5141723103fe2b145c7bb649d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:06:17 +0200 Subject: [PATCH 195/259] chore(deps): bump flyway from 12.9.0 to 12.10.0 (#2941) Bumps `flyway` from 12.9.0 to 12.10.0. Updates `org.flywaydb:flyway-core` from 12.9.0 to 12.10.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.9.0 to 12.10.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.10.0 dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e2783cfd95..dd63208edc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" -flyway = "12.9.0" +flyway = "12.10.0" jackson = "2.22.0" jakarta-json = "2.1.3" junit = "6.1.0" From 4571d8985de3eef99eaa7596bf1decc022b6c9ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:14:15 +0200 Subject: [PATCH 196/259] chore(deps): bump github/codeql-action/upload-sarif (#2950) Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.36.2 to 4.36.3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...54f647b7e1bb85c95cddabcd46b0c578ec92bc1a) --- updated-dependencies: - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.36.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/kics.yml | 2 +- .github/workflows/workflow-security-lint.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 2fcd50ead6..982590791b 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index d12dd35e67..9e0ab500cc 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 if: always() with: sarif_file: results-fixed.sarif From cf72d44662c6720a21a1bc5995a75742a85d5d3b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:14:45 +0200 Subject: [PATCH 197/259] chore(deps): bump com.gradleup.shadow from 9.4.2 to 9.4.3 (#2946) Bumps [com.gradleup.shadow](https://github.com/GradleUp/shadow) from 9.4.2 to 9.4.3. - [Release notes](https://github.com/GradleUp/shadow/releases) - [Commits](https://github.com/GradleUp/shadow/compare/9.4.2...9.4.3) --- updated-dependencies: - dependency-name: com.gradleup.shadow dependency-version: 9.4.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dd63208edc..3c6839ee3c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -254,6 +254,6 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } -shadow = { id = "com.gradleup.shadow", version = "9.4.2" } +shadow = { id = "com.gradleup.shadow", version = "9.4.3" } swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.52" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From 7e5e19619ec5a93bf54ec6a5d7af6cf3378c08a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:15:09 +0200 Subject: [PATCH 198/259] chore(deps): bump org.postgresql:postgresql from 42.7.11 to 42.7.12 (#2945) Bumps [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc) from 42.7.11 to 42.7.12. - [Release notes](https://github.com/pgjdbc/pgjdbc/releases) - [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md) - [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.7.11...REL42.7.12) --- updated-dependencies: - dependency-name: org.postgresql:postgresql dependency-version: 42.7.12 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3c6839ee3c..ad0ddb96a3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,7 @@ okhttp = "5.4.0" opentelemetry = "2.29.0" opentelemetry-instrumentation = "2.29.0" opentelemetry-log4j-appender = "2.28.1-alpha" -postgres = "42.7.11" +postgres = "42.7.12" restAssured = "6.0.0" rsApi = "4.0.0" testcontainers = "2.0.5" From 5a8b8964e8d83bb27e9ddc62fe88ccb05b7eabdb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:15:39 +0200 Subject: [PATCH 199/259] chore(deps): bump org.junit.platform:junit-platform-launcher (#2944) Bumps [org.junit.platform:junit-platform-launcher](https://github.com/junit-team/junit-framework) from 6.1.0 to 6.1.1. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.1.0...r6.1.1) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-launcher dependency-version: 6.1.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ad0ddb96a3..de65f27512 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ common-tck = "1.0.0" flyway = "12.10.0" jackson = "2.22.0" jakarta-json = "2.1.3" -junit = "6.1.0" +junit = "6.1.1" nimbus = "10.9.1" okhttp = "5.4.0" opentelemetry = "2.29.0" From 63734cb6d7d00f309e1e2733cf5f186224591609 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 10:16:03 +0200 Subject: [PATCH 200/259] chore(deps): bump log4j2 from 2.26.0 to 2.26.1 (#2940) Bumps `log4j2` from 2.26.0 to 2.26.1. Updates `org.apache.logging.log4j:log4j-api` from 2.26.0 to 2.26.1 Updates `org.apache.logging.log4j:log4j-core` from 2.26.0 to 2.26.1 Updates `org.apache.logging.log4j:log4j-core-test` from 2.26.0 to 2.26.1 Updates `org.apache.logging.log4j:log4j-layout-template-json` from 2.26.0 to 2.26.1 --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-version: 2.26.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-core dependency-version: 2.26.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-core-test dependency-version: 2.26.1 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: org.apache.logging.log4j:log4j-layout-template-json dependency-version: 2.26.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index de65f27512..8d46309313 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,7 +27,7 @@ rsApi = "4.0.0" testcontainers = "2.0.5" testcontainers-keycloak = "4.2.1" titanium = "1.7.0" -log4j2 = "2.26.0" +log4j2 = "2.26.1" wiremock = "3.13.2" From 76b1c96aa1d96bc3489ea76eabff6f73b8286b5d Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Fri, 10 Jul 2026 10:28:49 +0200 Subject: [PATCH 201/259] Update CodeQL consistently (#2956) Signed-off-by: Lars Geyer-Blaumeiser --- .github/workflows/codeql.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 58550557ca..4f214284d9 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 + uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 with: category: "/language:${{matrix.language}}" From cf2d3ccbbf597a054c58fa2d4f5a43eee05438be Mon Sep 17 00:00:00 2001 From: Lars Geyer-Blaumeiser Date: Thu, 16 Jul 2026 08:16:07 +0200 Subject: [PATCH 202/259] infra: Use dependabot grouping to reduce PR flood (#2957) * infra: Use dependabot grouping to reduce PR flood Signed-off-by: Lars Geyer-Blaumeiser * Add attribution of ai agent Signed-off-by: Lars Geyer-Blaumeiser * Add ai attribution option to header file templates Signed-off-by: Lars Geyer-Blaumeiser * feat: update groups --------- Signed-off-by: Lars Geyer-Blaumeiser Co-authored-by: AndrYurk --- .github/dependabot.yml | 56 ++++++++++++++++++++++++++++-- resources/hashtag.header | 1 + resources/java.header | 1 + resources/tx-checkstyle-config.xml | 4 +-- 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4378581791..aa716f2bb3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -16,6 +16,7 @@ # under the License. # # SPDX-License-Identifier: Apache-2.0 +# Assisted-By: Claude-Opus-4.8 ################################################################################# @@ -37,8 +38,51 @@ updates: cooldown: default-days: 7 ignore: - - dependency-name: "org.eclipse.dataspacetck.dsp:*" - - dependency-name: "org.eclipse.dataspacetck.dcp:*" + - dependency-name: "org.eclipse.dataspacetck.*" + groups: + test-dependencies: + patterns: + - "org.junit*" + - "org.mockito*" + - "org.assertj*" + - "org.awaitility*" + - "org.testcontainers*" + - "com.github.dasniko:testcontainers-keycloak" + - "io.rest-assured*" + - "org.wiremock*" + - "io.qameta.allure*" + build-tooling: + patterns: + - "com.bmuschko*" + - "com.gradleup*" + - "io.swagger*" + - "com.diffplug.spotless*" + - "org.sonarqube*" + - "com.github.ben-manes*" + - "org.jreleaser*" + logging: + patterns: + - "org.apache.logging.log4j*" + - "org.slf4j*" + - "ch.qos.logback*" + - "io.opentelemetry*" + serialization-and-crypto: + patterns: + - "com.fasterxml.jackson*" + - "jakarta.json*" + - "jakarta.ws.rs*" + - "com.apicatalog*" + - "com.networknt*" + - "org.bouncycastle*" + - "com.nimbusds*" + cloud-sdks: + patterns: + - "software.amazon.awssdk*" + - "com.azure*" + database: + patterns: + - "org.postgresql*" + - "org.flywaydb*" # Github Actions - @@ -55,6 +99,10 @@ updates: open-pull-requests-limit: 50 cooldown: default-days: 7 + groups: + github-actions-all: + patterns: + - "*" # Docker - package-ecosystem: "docker" @@ -71,3 +119,7 @@ updates: open-pull-requests-limit: 50 cooldown: default-days: 7 + groups: + docker-base-images: + patterns: + - "*" diff --git a/resources/hashtag.header b/resources/hashtag.header index 15b2ffccba..f6ccc4b0d9 100644 --- a/resources/hashtag.header +++ b/resources/hashtag.header @@ -16,5 +16,6 @@ ^# under the License\.$ ^#$ ^# SPDX-License-Identifier: Apache\-2\.0$ +^# Assisted-By:.*$ ^##+$ ^$ diff --git a/resources/java.header b/resources/java.header index da5ccc67e5..d1e8dc86e9 100644 --- a/resources/java.header +++ b/resources/java.header @@ -15,4 +15,5 @@ ^ \* under the License\.$ ^ \*$ ^ \* SPDX-License-Identifier: Apache\-2\.0$ +^ \* Assisted-By:.*$ ^ \*+/$ \ No newline at end of file diff --git a/resources/tx-checkstyle-config.xml b/resources/tx-checkstyle-config.xml index 5ca5d0548b..361cd7b51c 100644 --- a/resources/tx-checkstyle-config.xml +++ b/resources/tx-checkstyle-config.xml @@ -46,13 +46,13 @@ - + - + From a0140489a9c9c9abdff26b2c3d23194d0d6c66c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:13:13 +0200 Subject: [PATCH 203/259] chore(deps): bump the github-actions-all group across 2 directories with 7 updates (#2966) Bumps the github-actions-all group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.19.4` | `2.20.0` | | [github/codeql-action/init](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` | | [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` | | [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) | `3.95.8` | `3.95.9` | | [actions/stale](https://github.com/actions/stale) | `10.3.0` | `10.4.0` | Bumps the github-actions-all group with 1 update in the /.github/actions/setup-java directory: [actions/setup-java](https://github.com/actions/setup-java). Updates `step-security/harden-runner` from 2.19.4 to 2.20.0 - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/9af89fc71515a100421586dfdb3dc9c984fbf411...bf7454d06d71f1098171f2acdf0cd4708d7b5920) Updates `github/codeql-action/init` from 4.36.3 to 4.37.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9) Updates `github/codeql-action/analyze` from 4.36.3 to 4.37.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9) Updates `github/codeql-action/upload-sarif` from 4.36.3 to 4.37.0 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/54f647b7e1bb85c95cddabcd46b0c578ec92bc1a...99df26d4f13ea111d4ec1a7dddef6063f76b97e9) Updates `trufflesecurity/trufflehog` from 3.95.8 to 3.95.9 - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/00155c9dc586f34d189adc83d3ac2698c2ec551f...27b0417c16317ca9a472a9a8092acce143b49c55) Updates `actions/stale` from 10.3.0 to 10.4.0 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899...1e223db275d687790206a7acac4d1a11bd6fe629) Updates `actions/setup-java` from 5.4.0 to 5.5.0 - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/1bcf9fb12cf4aa7d266a90ae39939e61372fe520...0f481fcb613427c0f801b606911222b5b6f3083a) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.20.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: github/codeql-action/init dependency-version: 4.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: github/codeql-action/analyze dependency-version: 4.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: trufflesecurity/trufflehog dependency-version: 3.95.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: actions/stale dependency-version: 10.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: actions/setup-java dependency-version: 5.5.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-java/action.yml | 2 +- .github/workflows/codeql.yaml | 6 ++--- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/deployment-test.yaml | 6 ++--- .github/workflows/draft-release.yaml | 2 +- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 4 ++-- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 6 ++--- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 4 ++-- .github/workflows/stale-bot.yml | 4 ++-- .github/workflows/triage-issue.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 4 ++-- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 6 ++--- 19 files changed, 45 insertions(+), 45 deletions(-) diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index e7e4603cb3..e15c5f9c11 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -26,7 +26,7 @@ runs: using: "composite" steps: - name: Setup JDK 21 - uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 + uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 with: java-version: '21' distribution: 'temurin' diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 4f214284d9..1cbc1c9113 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -55,7 +55,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Checkout repository @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 + uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 + uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index 016d6f07b8..d6340c923e 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Copy labels from linked issue to PR diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 408b1a0b62..270b107aaa 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: test-prepare steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -84,7 +84,7 @@ jobs: "v1.33.7" ] steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index e30a2adfda..036d5e9d7b 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -44,7 +44,7 @@ jobs: is_official_release: ${{ steps.validation.outputs.is_official_release }} steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index 4f9808434b..fefaa11d2f 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 1e55b62213..745cfbd682 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit ############## diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 982590791b..2423d72da3 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 + uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index 90a0934892..c2e1244a84 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -38,7 +38,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index 610007f26c..baa29b0029 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -72,7 +72,7 @@ jobs: HAS_SWAGGER: ${{ steps.secret-presence.outputs.HAS_SWAGGER }} steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Check whether secrets exist @@ -95,7 +95,7 @@ jobs: DATED: ${{ steps.get-version.outputs.DATED }} steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -165,7 +165,7 @@ jobs: if: ${{ needs.determine-version.outputs.DATED == 'true' }} steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0f2306f2e3..86c46da03d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,7 +60,7 @@ jobs: update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -152,7 +152,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -192,7 +192,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -255,7 +255,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit @@ -298,7 +298,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Checkout main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index f26ff9f7be..dcf35b831b 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -42,7 +42,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Checkout Repository @@ -53,7 +53,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@00155c9dc586f34d189adc83d3ac2698c2ec551f + uses: trufflesecurity/trufflehog@27b0417c16317ca9a472a9a8092acce143b49c55 continue-on-error: true with: path: ./ # Scan the entire repository diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index b0cdae23af..aa563a3d77 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -39,10 +39,10 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 + - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0 with: operations-per-run: 1000 days-before-issue-stale: 32 diff --git a/.github/workflows/triage-issue.yml b/.github/workflows/triage-issue.yml index b4103c5161..9117a40692 100644 --- a/.github/workflows/triage-issue.yml +++ b/.github/workflows/triage-issue.yml @@ -36,7 +36,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - run: gh issue edit "$NUMBER" --add-label "$LABELS" diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index bdd27b3500..bb1b567b8a 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -70,7 +70,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 95bfb2eb07..934f6c5297 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 8ae111edb2..83d42f4709 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: [ test-prepare ] steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 15327ba0cb..3c4bd7050b 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -36,7 +36,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -152,7 +152,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -171,7 +171,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -191,7 +191,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -213,7 +213,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -247,7 +247,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -265,7 +265,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -287,7 +287,7 @@ jobs: contents: write steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 9e0ab500cc..014547f7b3 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -46,7 +46,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit @@ -71,7 +71,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 + uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 if: always() with: sarif_file: results-fixed.sarif From b03f4853ada3b5591ca81334f18bbe18a921ba7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:13:35 +0200 Subject: [PATCH 204/259] chore(deps): bump the cloud-sdks group with 2 updates (#2964) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.46.21 to 2.47.3 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.46.21 to 2.47.3 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.46.21 to 2.47.3 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.47.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.47.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.47.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8d46309313..28eef3d31b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.3" awaitility = "4.3.0" -aws = "2.46.21" +aws = "2.47.3" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" From 41ef38e62628d11b75746ae3fdc1b35d3f23db1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:14:06 +0200 Subject: [PATCH 205/259] chore(deps): bump the serialization-and-crypto group with 2 updates (#2963) Bumps the serialization-and-crypto group with 2 updates: [com.networknt:json-schema-validator](https://github.com/networknt/json-schema-validator) and [com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp](https://github.com/FasterXML/jackson-datatypes-misc). Updates `com.networknt:json-schema-validator` from 3.0.5 to 3.0.6 - [Release notes](https://github.com/networknt/json-schema-validator/releases) - [Changelog](https://github.com/networknt/json-schema-validator/blob/master/CHANGELOG.md) - [Commits](https://github.com/networknt/json-schema-validator/compare/3.0.5...3.0.6) Updates `com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp` from 2.22.0 to 2.22.1 - [Commits](https://github.com/FasterXML/jackson-datatypes-misc/compare/jackson-datatypes-misc-parent-2.22.0...jackson-datatypes-misc-parent-2.22.1) --- updated-dependencies: - dependency-name: com.networknt:json-schema-validator dependency-version: 3.0.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: serialization-and-crypto - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp dependency-version: 2.22.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: serialization-and-crypto ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts | 2 +- gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts index 138c57ef5f..df2f0735e6 100644 --- a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts @@ -43,7 +43,7 @@ dependencies { } constraints { - implementation("com.networknt:json-schema-validator:3.0.5") { + implementation("com.networknt:json-schema-validator:3.0.6") { because("older versions cause runtime issues") } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 28eef3d31b..a2e562c300 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" flyway = "12.10.0" -jackson = "2.22.0" +jackson = "2.22.1" jakarta-json = "2.1.3" junit = "6.1.1" nimbus = "10.9.1" From 86fb1f0435c91960a73bb56544663979421f5f06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:14:40 +0200 Subject: [PATCH 206/259] chore(deps): bump com.gradleup.shadow in the build-tooling group (#2961) Bumps the build-tooling group with 1 update: [com.gradleup.shadow](https://github.com/GradleUp/shadow). Updates `com.gradleup.shadow` from 9.4.3 to 9.5.1 - [Release notes](https://github.com/GradleUp/shadow/releases) - [Commits](https://github.com/GradleUp/shadow/compare/9.4.3...9.5.1) --- updated-dependencies: - dependency-name: com.gradleup.shadow dependency-version: 9.5.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tooling ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a2e562c300..f828dcfa13 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -254,6 +254,6 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } -shadow = { id = "com.gradleup.shadow", version = "9.4.3" } +shadow = { id = "com.gradleup.shadow", version = "9.5.1" } swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.52" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From 5d5db022201f49ae5f2b1f35c3e550152c6e6e20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:17:23 +0200 Subject: [PATCH 207/259] chore(deps): bump io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 (#2962) Bumps the logging group with 1 update: [io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17](https://github.com/open-telemetry/opentelemetry-java-instrumentation). Updates `io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17` from 2.28.1-alpha to 2.29.0-alpha - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/commits) --- updated-dependencies: - dependency-name: io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 dependency-version: 2.29.0-alpha dependency-type: direct:production update-type: version-update:semver-minor dependency-group: logging ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f828dcfa13..975200afa4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ nimbus = "10.9.1" okhttp = "5.4.0" opentelemetry = "2.29.0" opentelemetry-instrumentation = "2.29.0" -opentelemetry-log4j-appender = "2.28.1-alpha" +opentelemetry-log4j-appender = "2.29.0-alpha" postgres = "42.7.12" restAssured = "6.0.0" rsApi = "4.0.0" From 20b583330a7a798c690e9cc591bac853503347a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:18:37 +0200 Subject: [PATCH 208/259] chore(deps): bump org.postgresql:postgresql in the database group (#2965) Bumps the database group with 1 update: [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc). Updates `org.postgresql:postgresql` from 42.7.12 to 42.7.13 - [Release notes](https://github.com/pgjdbc/pgjdbc/releases) - [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md) - [Commits](https://github.com/pgjdbc/pgjdbc/compare/REL42.7.12...REL42.7.13) --- updated-dependencies: - dependency-name: org.postgresql:postgresql dependency-version: 42.7.13 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: database ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrii Yurkevych --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 975200afa4..7baca41291 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,7 @@ okhttp = "5.4.0" opentelemetry = "2.29.0" opentelemetry-instrumentation = "2.29.0" opentelemetry-log4j-appender = "2.29.0-alpha" -postgres = "42.7.12" +postgres = "42.7.13" restAssured = "6.0.0" rsApi = "4.0.0" testcontainers = "2.0.5" From 3dfa60c26fe8fb529a67841d9bb5d19fd55d416d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 08:49:42 +0200 Subject: [PATCH 209/259] chore(deps): bump com.github.dasniko:testcontainers-keycloak (#2967) Bumps the test-dependencies group with 1 update: [com.github.dasniko:testcontainers-keycloak](https://github.com/dasniko/testcontainers-keycloak). Updates `com.github.dasniko:testcontainers-keycloak` from 4.2.1 to 4.3.0 - [Release notes](https://github.com/dasniko/testcontainers-keycloak/releases) - [Commits](https://github.com/dasniko/testcontainers-keycloak/compare/v4.2.1...v4.3.0) --- updated-dependencies: - dependency-name: com.github.dasniko:testcontainers-keycloak dependency-version: 4.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: test-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7baca41291..d442b7757c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ postgres = "42.7.13" restAssured = "6.0.0" rsApi = "4.0.0" testcontainers = "2.0.5" -testcontainers-keycloak = "4.2.1" +testcontainers-keycloak = "4.3.0" titanium = "1.7.0" log4j2 = "2.26.1" wiremock = "3.13.2" From 5d6f17ba57a6ab750a91f2bcc67724e6e5cf0c0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 08:50:03 +0200 Subject: [PATCH 210/259] chore(deps): bump the cloud-sdks group with 2 updates (#2968) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.47.3 to 2.47.4 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.47.3 to 2.47.4 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.47.3 to 2.47.4 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.47.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.47.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.47.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d442b7757c..2b56fe2437 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.3" awaitility = "4.3.0" -aws = "2.47.3" +aws = "2.47.4" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" From 105c7ecf9cb72da7f803667234f5dca1b5ae8936 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 08:50:20 +0200 Subject: [PATCH 211/259] chore(deps): bump the database group with 2 updates (#2969) Bumps the database group with 2 updates: org.flywaydb:flyway-core and org.flywaydb:flyway-database-postgresql. Updates `org.flywaydb:flyway-core` from 12.10.0 to 12.11.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.10.0 to 12.11.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.10.0 to 12.11.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 12.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 12.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2b56fe2437..4ef081c0a9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" -flyway = "12.10.0" +flyway = "12.11.0" jackson = "2.22.1" jakarta-json = "2.1.3" junit = "6.1.1" From 2299a41fd874519e77d586d2b006bd205a9b35fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:00:12 +0200 Subject: [PATCH 212/259] chore(deps): bump the github-actions-all group across 4 directories with 6 updates (#2977) Bumps the github-actions-all group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [actions/checkout](https://github.com/actions/checkout) | `7.0.0` | `7.0.1` | | [github/codeql-action/init](https://github.com/github/codeql-action) | `4.37.0` | `4.37.1` | | [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.37.0` | `4.37.1` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.0` | `4.37.1` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.7` | `0.6.0` | Bumps the github-actions-all group with 1 update in the /.github/actions/publish-docker-image directory: [actions/checkout](https://github.com/actions/checkout). Bumps the github-actions-all group with 1 update in the /.github/actions/run-deployment-test directory: [actions/checkout](https://github.com/actions/checkout). Bumps the github-actions-all group with 1 update in the /.github/actions/setup-java directory: [actions/setup-java](https://github.com/actions/setup-java). Updates `actions/checkout` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1) Updates `github/codeql-action/init` from 4.37.0 to 4.37.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a) Updates `github/codeql-action/analyze` from 4.37.0 to 4.37.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a) Updates `github/codeql-action/upload-sarif` from 4.37.0 to 4.37.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/99df26d4f13ea111d4ec1a7dddef6063f76b97e9...7188fc363630916deb702c7fdcf4e481b751f97a) Updates `zizmorcore/zizmor-action` from 0.5.7 to 0.6.0 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/192e21d79ab29983730a13d1382995c2307fbcaa...6599ee8b7a49aef6a770f63d261d214911a7ce02) Updates `actions/checkout` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1) Updates `actions/checkout` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1) Updates `actions/setup-java` from 5.5.0 to 5.6.0 - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/0f481fcb613427c0f801b606911222b5b6f3083a...03ad4de0992f5dab5e18fcb136590ce7c4a0ac95) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/init dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/analyze dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: zizmorcore/zizmor-action dependency-version: 0.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: actions/setup-java dependency-version: 5.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../actions/publish-docker-image/action.yml | 2 +- .../actions/run-deployment-test/action.yml | 2 +- .github/actions/setup-java/action.yml | 2 +- .github/workflows/codeql.yaml | 6 ++--- .github/workflows/deployment-test.yaml | 4 ++-- .github/workflows/draft-release.yaml | 4 ++-- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 4 ++-- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 4 ++-- .github/workflows/publish-openapi-ui.yml | 4 ++-- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 2 +- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 8 +++---- 19 files changed, 43 insertions(+), 43 deletions(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 73de3ee614..b91f83a547 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -46,7 +46,7 @@ inputs: runs: using: "composite" steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false diff --git a/.github/actions/run-deployment-test/action.yml b/.github/actions/run-deployment-test/action.yml index b9b4324f20..f4f5b3a039 100644 --- a/.github/actions/run-deployment-test/action.yml +++ b/.github/actions/run-deployment-test/action.yml @@ -49,7 +49,7 @@ inputs: runs: using: "composite" steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/setup-java diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index e15c5f9c11..c6afdb417d 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -26,7 +26,7 @@ runs: using: "composite" steps: - name: Setup JDK 21 - uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5.5.0 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 with: java-version: '21' distribution: 'temurin' diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 1cbc1c9113..7ddd42175d 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -59,13 +59,13 @@ jobs: with: egress-policy: audit - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + uses: github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + uses: github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 270b107aaa..bb3d53fbb0 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -53,7 +53,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/run-deployment-test @@ -88,7 +88,7 @@ jobs: with: egress-policy: audit - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/run-deployment-test diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 036d5e9d7b..5d81b13655 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -47,7 +47,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false @@ -120,7 +120,7 @@ jobs: packages: write pages: write steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6.0.2 # zizmor: ignore[artipacked] + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6.0.2 # zizmor: ignore[artipacked] with: persist-credentials: true - name: Create Release branch diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index fefaa11d2f..a9656178b5 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -38,7 +38,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: true - uses: ./.github/actions/setup-java diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 745cfbd682..cbf48f195e 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -52,7 +52,7 @@ jobs: ############## ### Set-Up ### ############## - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 2423d72da3..eb8a1db4d3 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -48,7 +48,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index c2e1244a84..aa7b0abfe4 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -41,7 +41,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: copy contexts into public folder diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index baa29b0029..838ff11c73 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -98,7 +98,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: "Get version" @@ -168,7 +168,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/publish-latest-versioned-snapshot diff --git a/.github/workflows/publish-openapi-ui.yml b/.github/workflows/publish-openapi-ui.yml index 31316b8f7a..5bc0527b01 100644 --- a/.github/workflows/publish-openapi-ui.yml +++ b/.github/workflows/publish-openapi-ui.yml @@ -53,7 +53,7 @@ jobs: generate-openapi-spec: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -75,7 +75,7 @@ jobs: { name: "data-plane", folder: "edc-dataplane/edc-dataplane-base" } ] steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/setup-java diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 86c46da03d..c692efd2b5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,7 +63,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false @@ -155,7 +155,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: true @@ -195,7 +195,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: true - name: Prepare Git Config @@ -259,7 +259,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -302,7 +302,7 @@ jobs: with: egress-policy: audit - name: Checkout main - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 ref: main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index dcf35b831b..6f8d73a383 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -46,7 +46,7 @@ jobs: with: egress-policy: audit - name: Checkout Repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 # Ensure full clone for pull request workflows persist-credentials: false diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index bb1b567b8a..1edc83e02b 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -73,7 +73,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Log inputs diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 934f6c5297..0d76003c1c 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -62,7 +62,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/setup-java diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 83d42f4709..6907ee9db0 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -54,7 +54,7 @@ jobs: with: egress-policy: audit - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 3c4bd7050b..e9ba721240 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -39,7 +39,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - run: | @@ -62,7 +62,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -80,7 +80,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -97,7 +97,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -155,7 +155,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -174,7 +174,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -194,7 +194,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: get api groups and create matrix for next job @@ -216,7 +216,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -250,7 +250,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -268,7 +268,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: ./.github/actions/setup-java @@ -291,7 +291,7 @@ jobs: with: egress-policy: audit - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 014547f7b3..189b680a01 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -51,12 +51,12 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7 + uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 # v0.6.0 with: version: "1.23.1" advanced-security: "true" @@ -76,7 +76,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@99df26d4f13ea111d4ec1a7dddef6063f76b97e9 # v4.37.0 + uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 if: always() with: sarif_file: results-fixed.sarif From 1caf99bea1a79abfae02334f8e417875b40c1061 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:00:35 +0200 Subject: [PATCH 213/259] chore(deps): bump the cloud-sdks group with 2 updates (#2976) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.47.4 to 2.48.2 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.47.4 to 2.48.2 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.47.4 to 2.48.2 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.48.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.48.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.48.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4ef081c0a9..fcac5e1458 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.3" awaitility = "4.3.0" -aws = "2.47.4" +aws = "2.48.2" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.84" dcp-tck = "1.0.1" From 6a176fe277b6c2b6d3724ec9c243b1a7ff0074c4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:01:10 +0200 Subject: [PATCH 214/259] chore(deps): bump org.bouncycastle:bcpkix-jdk18on (#2975) Bumps the serialization-and-crypto group with 1 update: [org.bouncycastle:bcpkix-jdk18on](https://github.com/bcgit/bc-java). Updates `org.bouncycastle:bcpkix-jdk18on` from 1.84 to 1.85 - [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html) - [Commits](https://github.com/bcgit/bc-java/commits) --- updated-dependencies: - dependency-name: org.bouncycastle:bcpkix-jdk18on dependency-version: '1.85' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: serialization-and-crypto ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fcac5e1458..11e40084a7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ allure = "2.35.3" awaitility = "4.3.0" aws = "2.48.2" azure-storage-blob = "12.35.0" -bouncyCastle-jdk18on = "1.84" +bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" From 2aab963bb6813ae4bad7d5373a0d26308fa7ad51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:01:34 +0200 Subject: [PATCH 215/259] chore(deps): bump com.gradleup.shadow in the build-tooling group (#2974) Bumps the build-tooling group with 1 update: [com.gradleup.shadow](https://github.com/GradleUp/shadow). Updates `com.gradleup.shadow` from 9.5.1 to 9.6.0 - [Release notes](https://github.com/GradleUp/shadow/releases) - [Commits](https://github.com/GradleUp/shadow/compare/9.5.1...9.6.0) --- updated-dependencies: - dependency-name: com.gradleup.shadow dependency-version: 9.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tooling ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 11e40084a7..2a011315db 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -254,6 +254,6 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } -shadow = { id = "com.gradleup.shadow", version = "9.5.1" } +shadow = { id = "com.gradleup.shadow", version = "9.6.0" } swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.52" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From 4095898ebe04b099464ce8a1c687e315dc59310b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Jul 2026 09:02:04 +0200 Subject: [PATCH 216/259] chore(deps): bump the test-dependencies group with 2 updates (#2973) Bumps the test-dependencies group with 2 updates: [org.junit.platform:junit-platform-launcher](https://github.com/junit-team/junit-framework) and [io.rest-assured:rest-assured](https://github.com/rest-assured/rest-assured). Updates `org.junit.platform:junit-platform-launcher` from 6.1.1 to 6.1.2 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.1.1...r6.1.2) Updates `io.rest-assured:rest-assured` from 6.0.0 to 6.0.1 - [Changelog](https://github.com/rest-assured/rest-assured/blob/master/changelog.txt) - [Commits](https://github.com/rest-assured/rest-assured/compare/rest-assured-6.0.0...rest-assured-6.0.1) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-launcher dependency-version: 6.1.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: test-dependencies - dependency-name: io.rest-assured:rest-assured dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: test-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2a011315db..7c4ae71764 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,14 +15,14 @@ common-tck = "1.0.0" flyway = "12.11.0" jackson = "2.22.1" jakarta-json = "2.1.3" -junit = "6.1.1" +junit = "6.1.2" nimbus = "10.9.1" okhttp = "5.4.0" opentelemetry = "2.29.0" opentelemetry-instrumentation = "2.29.0" opentelemetry-log4j-appender = "2.29.0-alpha" postgres = "42.7.13" -restAssured = "6.0.0" +restAssured = "6.0.1" rsApi = "4.0.0" testcontainers = "2.0.5" testcontainers-keycloak = "4.3.0" From 6e96ec300058fef9114e713d1fc588c12b453b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo?= <18561736+bmg13@users.noreply.github.com> Date: Fri, 24 Jul 2026 11:01:30 +0100 Subject: [PATCH 217/259] Feat/update the compatability tests (#2958) * feat: update the compatability tests. * feat: update the compatability tests. * feat: update the compatability tests. * feat: update the compatability tests. * feat: update the compatability tests. * Updated Docker Host. * feat: update the compatability tests. * Changes from pr. * Considerable clean up. * Small clean uo. * Remove Legacy Participant. * Refactor Test Logic. * Refactor Test Logic. * Clean up override. * Fix small formatting. * Added proposed refactor. * Added proposed refactor. * Remove legacy terminology. * Removed uneeded mapping. * Removed uneeded change. * Removed uneeded changes. --- .github/workflows/verify.yaml | 1 - .../compatibility-tests/build.gradle.kts | 1 - .../tests/fixtures/DcpHelperFunctions.java | 2 +- .../fixtures/IdentityHubParticipant.java | 2 +- .../tests/fixtures/RemoteParticipant.java | 81 +++++++- .../tests/transfer/TransferEndToEndTest.java | 174 ++++++++++++------ .../stable/connector-stable/build.gradle.kts | 3 +- .../tests/AudienceSeedExtension.java | 31 +++- gradle/libs.stable.versions.toml | 6 +- 9 files changed, 230 insertions(+), 71 deletions(-) diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index e9ba721240..0d54fa4aaf 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -259,7 +259,6 @@ jobs: run: ./gradlew test -DincludeTags="PostgresqlIntegrationTest" -PverboseTest=true compatibility-tests: - if: false # Disabled while compatibility tests are being migrated to the updated EDC runtime. runs-on: ubuntu-latest permissions: contents: read diff --git a/edc-tests/compatibility-tests/build.gradle.kts b/edc-tests/compatibility-tests/build.gradle.kts index d2c9e06ada..7dd12b49cb 100644 --- a/edc-tests/compatibility-tests/build.gradle.kts +++ b/edc-tests/compatibility-tests/build.gradle.kts @@ -23,7 +23,6 @@ plugins { } configurations.all { - exclude("org.eclipse.edc", "decentralized-claims-core") exclude("com.networknt", "json-schema-validator") } diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java index 56a0150cee..3d59e0cfb3 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/DcpHelperFunctions.java @@ -76,7 +76,7 @@ public static void configureParticipant(TractusxDcpParticipantBase participant, credentials.forEach(credentialStore::create); - accountService.findById(participant.getDid()) + accountService.findById(participant.getParticipantContextId()) .onSuccess(account -> vault.storeSecret(account.getSecretAlias(), "clientSecret")); } diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java index accba6d38c..c2871d318f 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/IdentityHubParticipant.java @@ -70,7 +70,7 @@ public LazySupplier getSts() { } public URI getResolutionApi() { - return credentialsApi.get(); + return URI.create(credentialsApi.get().toString()); } public String didFor(String participantId) { diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipant.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipant.java index 7c77e61c7a..e5fe326396 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipant.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/fixtures/RemoteParticipant.java @@ -20,6 +20,9 @@ package org.eclipse.tractusx.edc.compatibility.tests.fixtures; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import org.eclipse.edc.connector.controlplane.test.system.utils.Participant; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.eclipse.tractusx.edc.tests.participant.DcpParticipant; @@ -29,18 +32,81 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import static io.restassured.http.ContentType.JSON; +import static jakarta.json.Json.createObjectBuilder; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +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.ODRL_ASSIGNER_ATTRIBUTE; +import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_TARGET_ATTRIBUTE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.eclipse.edc.util.io.Ports.getFreePort; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025; public class RemoteParticipant extends DcpParticipant { private final List datasources = List.of("asset", "contractdefinition", "contractnegotiation", "policy", "transferprocess", "bpn", "policy-monitor", "edr", "dataplane", "accesstokendata", "dataplaneinstance"); + private final Map agreementAssetIds = new ConcurrentHashMap<>(); + private static final String HTTP_PULL_TRANSFER_TYPE = "HttpData-PULL"; + + @Override + public String negotiateContract(Participant provider, JsonObject offer) { + var participant = (TractusxDcpParticipantBase) provider; + var correctedOffer = createObjectBuilder(offer) + .add(ODRL_ASSIGNER_ATTRIBUTE, createObjectBuilder().add(ID, participant.getDid())) + .build(); + + var agreementId = super.negotiateContract(provider, correctedOffer); + agreementAssetIds.put(agreementId, extractAssetId(offer)); + return agreementId; + } + + @Override + public String initiateTransfer( + Participant provider, + String agreementId, + JsonObject privateProperties, + JsonObject destination, + String transferType, + JsonArray callbacks) { + + var transferRequest = createObjectBuilder() + .add(CONTEXT, createObjectBuilder() + .add("@vocab", EDC_NAMESPACE) + .build()) + .add(TYPE, "TransferRequest") + .add("counterPartyAddress", provider.getProtocolUrl()) + .add("contractId", agreementId) + .add("assetId", agreementAssetIds.remove(agreementId)) + .add("protocol", DSP_2025) + .add("transferType", transferType != null ? transferType : HTTP_PULL_TRANSFER_TYPE) + .build(); + + return baseManagementRequest() + .contentType(JSON) + .body(transferRequest) + .when() + .post("/transferprocesses") + .then() + .statusCode(200) + .extract() + .jsonPath() + .getString("'@id'"); + } + + private String extractAssetId(JsonObject offer) { + var target = offer.get(ODRL_TARGET_ATTRIBUTE); + var targetObj = (JsonObject) target; + return targetObj.getString(ID, null); + } public Config getConfig(DcpParticipant participant, PostgresExtension postgresql) { var postgresqlConfig = postgresql.getConfig(getName()); - Map settings = new HashMap<>() { + Map settings = new HashMap<>() { { put("edc.participant.id", id); put("edc.api.auth.key", MANAGEMENT_API_KEY); @@ -67,10 +133,12 @@ public Config getConfig(DcpParticipant participant, PostgresExtension postgresql put("testing.edc.vaults.3.value", getPublicKeyAsString()); put("edc.iam.issuer.id", getDid()); put("edc.iam.did.web.use.https", "false"); + put("tractusx.edc.participant.bpn", getBpn()); put("testing.edc.bdrs.1.key", participant.getId()); put("testing.edc.bdrs.1.value", participant.getDid()); put("edc.iam.trusted-issuer.issuer.id", trustedIssuer); put("edc.sql.schema.autocreate", "false"); + put("edc.participant.context.id", "participant-context-id"); put("web.http.public.path", dataPlanePublic.get().getPath()); put("web.http.public.port", String.valueOf(dataPlanePublic.get().getPort())); put("edc.transfer.proxy.token.signer.privatekey.alias", getPrivateKeyAlias()); @@ -89,7 +157,7 @@ private Map datasourceConfig(Config postgresqlConfig) { config.put("edc.datasource." + ds + ".name", ds); config.putAll(datasourceEnvironmentVariables(ds, postgresqlConfig)); }); - config.put("org.eclipse.tractusx.edc.postgresql.migration.schema", postgresqlConfig.getString("tx.edc.postgresql.migration.schema")); + config.put("tx.edc.postgresql.migration.schema", postgresqlConfig.getString("tx.edc.postgresql.migration.schema")); return config; } @@ -107,10 +175,19 @@ protected Builder() { super(new RemoteParticipant()); } + protected Builder(RemoteParticipant participant) { + super(participant); + } + public static Builder newInstance() { return new Builder(); } + public Builder protocol(String protocolName, String path) { + participant.protocol = new Protocol(protocolName, path); + return protocolVersionPath(path); + } + @Override public RemoteParticipant build() { super.build(); diff --git a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java index c122324da9..b9cba171f7 100644 --- a/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java +++ b/edc-tests/compatibility-tests/src/test/java/org/eclipse/tractusx/edc/compatibility/tests/transfer/TransferEndToEndTest.java @@ -21,9 +21,7 @@ package org.eclipse.tractusx.edc.compatibility.tests.transfer; import com.github.tomakehurst.wiremock.junit5.WireMockExtension; -import jakarta.json.Json; import jakarta.json.JsonObject; -import org.eclipse.edc.connector.controlplane.test.system.utils.PolicyFixtures; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.junit.extensions.RuntimePerClassExtension; import org.eclipse.edc.spi.iam.AudienceResolver; @@ -49,6 +47,8 @@ import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Map; import java.util.Objects; import java.util.UUID; @@ -76,12 +76,17 @@ import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.eclipse.tractusx.edc.compatibility.tests.fixtures.DcpHelperFunctions.configureParticipant; import static org.eclipse.tractusx.edc.compatibility.tests.fixtures.DcpHelperFunctions.configureParticipantContext; -import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_08; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.inForceDatePolicyLegacy; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.dataUsageEndDate; @CompatibilityTest public class TransferEndToEndTest { + private static final String OLDEST_STABLE_VERSION = "/v3"; + private static final String HTTP_PULL_TRANSFER_TYPE = "HttpData-PULL"; + private static final String DUMMY_DATA_RESPONSE = "data"; + private static final String SOURCE_PATH_SUFFIX = "/source"; + protected static final IdentityHubParticipant IDENTITY_HUB_PARTICIPANT = IdentityHubParticipant.Builder.newInstance() .name("identity-hub") .id("identity-hub") @@ -93,9 +98,11 @@ public class TransferEndToEndTest { protected static final RemoteParticipant REMOTE_PARTICIPANT = RemoteParticipant.Builder.newInstance() .name("remote") - .id(IDENTITY_HUB_PARTICIPANT.bpnFor("remote")) + .id(IDENTITY_HUB_PARTICIPANT.didFor("remote")) .stsUri(IDENTITY_HUB_PARTICIPANT.getSts()) .did(IDENTITY_HUB_PARTICIPANT.didFor("remote")) + .bpn(IDENTITY_HUB_PARTICIPANT.bpnFor("remote")) + .managementVersionBasePath(OLDEST_STABLE_VERSION) .trustedIssuer(ISSUER.didUrl()) .build(); @@ -136,8 +143,12 @@ public String resolveBpn(String did) { .findFirst().orElseThrow().getKey(); } }) - .registerServiceMock(AudienceResolver.class, message -> Result - .success(DIDS.get(message.getCounterPartyId())))); + .registerServiceMock(AudienceResolver.class, message -> { + var audience = DIDS.get(message.getCounterPartyId()); + return audience != null + ? Result.success(audience) + : Result.failure("No DID found for counter-party: " + message.getCounterPartyId()); + })); @Order(2) @RegisterExtension @@ -156,6 +167,7 @@ public String resolveBpn(String did) { @BeforeAll static void beforeAll() { + configureParticipant(LOCAL_PARTICIPANT, ISSUER, IDENTITY_HUB_PARTICIPANT, LOCAL_IDENTITY_HUB); configureParticipant(REMOTE_PARTICIPANT, ISSUER, IDENTITY_HUB_PARTICIPANT, LOCAL_IDENTITY_HUB); configureParticipantContext(ISSUER, IDENTITY_HUB_PARTICIPANT, LOCAL_IDENTITY_HUB); @@ -171,33 +183,19 @@ static void beforeAll() { void httpPullTransfer(TractusxDcpParticipantBase consumer, TractusxDcpParticipantBase provider, String protocol) { consumer.setProtocol(protocol); provider.setProtocol(protocol); - providerDataSource.stubFor(any(anyUrl()).willReturn(ok("data"))); + providerDataSource.stubFor(any(anyUrl()).willReturn(ok(DUMMY_DATA_RESPONSE))); var assetId = UUID.randomUUID().toString(); - var usagePolicy = inForceDatePolicyLegacy("gteq", "contractAgreement+0s", "lteq", "contractAgreement+5s"); + var usagePolicy = dataUsageEndDate(Instant.now().plusSeconds(300).truncatedTo(ChronoUnit.SECONDS).toString()); createResourcesOnProvider(provider, assetId, usagePolicy, httpSourceDataAddress()); - var transferProcessId = consumer.requestAssetFrom(assetId, provider) - .withTransferType("HttpData-PULL") - .execute(); + var transferProcessId = startTransferProcess(consumer, provider, assetId); consumer.awaitTransferToBeInState(transferProcessId, STARTED); - var edr = await().atMost(consumer.getTimeout()) - .until(() -> consumer.edrs().getEdr(transferProcessId), Objects::nonNull); - - // Do the transfer - var msg = UUID.randomUUID().toString(); - var data = consumer.data().pullData(edr, Map.of("message", msg)); - assertThat(data).isNotNull().isEqualTo("data"); - - // checks that the EDR is gone once the contract expires - await().atMost(consumer.getTimeout()) - .untilAsserted(() -> assertThatThrownBy(() -> consumer.edrs().getEdr(transferProcessId))); + var edr = obtainEdr(consumer, transferProcessId); - // checks that transfer fails - await().atMost(consumer.getTimeout()).untilAsserted(() -> assertThatThrownBy(() -> consumer.data().pullData(edr, Map.of("message", msg)))); - - providerDataSource.verify(getRequestedFor(urlPathEqualTo("/source"))); + pullAndAssertData(consumer, edr); + providerDataSource.verify(getRequestedFor(urlPathEqualTo(SOURCE_PATH_SUFFIX))); } @ParameterizedTest @@ -205,23 +203,18 @@ void httpPullTransfer(TractusxDcpParticipantBase consumer, TractusxDcpParticipan void suspendAndResume_httpPull_dataTransfer(TractusxDcpParticipantBase consumer, TractusxDcpParticipantBase provider, String protocol) { consumer.setProtocol(protocol); provider.setProtocol(protocol); - providerDataSource.stubFor(any(anyUrl()).willReturn(ok("data"))); + providerDataSource.stubFor(any(anyUrl()).willReturn(ok(DUMMY_DATA_RESPONSE))); var assetId = UUID.randomUUID().toString(); - createResourcesOnProvider(provider, assetId, PolicyFixtures.noConstraintPolicy(), httpSourceDataAddress()); + createResourcesOnProvider(provider, assetId, noConstraintPolicy(), httpSourceDataAddress()); - var transferProcessId = consumer.requestAssetFrom(assetId, provider) - .withTransferType("HttpData-PULL") - .execute(); + var transferProcessId = startTransferProcess(consumer, provider, assetId); consumer.awaitTransferToBeInState(transferProcessId, STARTED); - - var edr = await().atMost(consumer.getTimeout()).until(() -> consumer.edrs().getEdr(transferProcessId), Objects::nonNull); - + var edr = obtainEdr(consumer, transferProcessId); var msg = UUID.randomUUID().toString(); - var data = consumer.data().pullData(edr, Map.of("message", msg)); - assertThat(data).isNotNull().isEqualTo("data"); + pullAndAssertData(consumer, edr); - consumer.suspendTransfer(transferProcessId, "supension"); + consumer.suspendTransfer(transferProcessId, "suspension"); consumer.awaitTransferToBeInState(transferProcessId, SUSPENDED); @@ -234,41 +227,104 @@ void suspendAndResume_httpPull_dataTransfer(TractusxDcpParticipantBase consumer, // check that transfer is available again consumer.awaitTransferToBeInState(transferProcessId, STARTED); - var secondEdr = await().atMost(consumer.getTimeout()).until(() -> consumer.edrs().getEdr(transferProcessId), Objects::nonNull); - var secondMessage = UUID.randomUUID().toString(); - data = consumer.data().pullData(secondEdr, Map.of("message", secondMessage)); - assertThat(data).isNotNull().isEqualTo("data"); + var secondEdr = obtainEdr(consumer, transferProcessId); + pullAndAssertData(consumer, secondEdr); - providerDataSource.verify(getRequestedFor(urlPathEqualTo("/source"))); + providerDataSource.verify(getRequestedFor(urlPathEqualTo(SOURCE_PATH_SUFFIX))); } - protected void createResourcesOnProvider(TractusxDcpParticipantBase provider, String assetId, JsonObject contractPolicy, Map dataAddressProperties) { - provider.createAsset(assetId, Map.of("description", "description"), dataAddressProperties); - var contractPolicyId = provider.createPolicyDefinition(contractPolicy); - var noConstraintPolicyId = provider.createPolicyDefinition(noConstraintPolicy()); + private void createResourcesOnProvider(TractusxDcpParticipantBase provider, String assetId, JsonObject contractPolicy, Map dataAddressProperties) { + createAssetManagementContext(provider, assetId, Map.of("description", "description"), dataAddressProperties); + var contractPolicyId = createPolicyDefinitionManagementContext(provider, contractPolicy); + var noConstraintPolicyId = createPolicyDefinitionManagementContext(provider, noConstraintPolicy()); - createContractDefinitionLegacyManagementContext(provider, assetId, UUID.randomUUID().toString(), noConstraintPolicyId, contractPolicyId); + createContractDefinitionManagementContext(provider, assetId, UUID.randomUUID().toString(), noConstraintPolicyId, contractPolicyId); } - public String createContractDefinitionLegacyManagementContext(TractusxDcpParticipantBase participant, String assetId, String definitionId, String accessPolicyId, String contractPolicyId) { + private String startTransferProcess(TractusxDcpParticipantBase consumer, TractusxDcpParticipantBase provider, String assetId) { + return consumer.requestAssetFrom(assetId, provider) + .withTransferType(HTTP_PULL_TRANSFER_TYPE) + .execute(); + } + + private void pullAndAssertData(TractusxDcpParticipantBase consumer, JsonObject edr) { + var randomMessage = Map.of("message", UUID.randomUUID().toString()); + var data = consumer.data().pullData(edr, randomMessage); + assertThat(data).isNotNull().isEqualTo(DUMMY_DATA_RESPONSE); + } + + private JsonObject obtainEdr(TractusxDcpParticipantBase consumer, String transferProcessId) { + return await().atMost(consumer.getTimeout()) + .until(() -> consumer.edrs().getEdr(transferProcessId), Objects::nonNull); + } + + private void createAssetManagementContext(TractusxDcpParticipantBase participant, String assetId, Map properties, Map dataAddressProperties) { + var propertiesBuilder = createObjectBuilder(); + properties.forEach((key, value) -> propertiesBuilder.add(key, String.valueOf(value))); + + var dataAddressBuilder = createObjectBuilder().add(TYPE, "DataAddress"); + dataAddressProperties.forEach((key, value) -> dataAddressBuilder.add(key, String.valueOf(value))); + var requestBody = createObjectBuilder() .add(CONTEXT, createArrayBuilder().add(EDC_CONNECTOR_MANAGEMENT_CONTEXT)) + .add(ID, assetId) + .add(TYPE, "Asset") + .add(EDC_NAMESPACE + "properties", propertiesBuilder.build()) + .add(EDC_NAMESPACE + "dataAddress", dataAddressBuilder.build()) + .build(); + + participant.baseManagementRequest() + .basePath(OLDEST_STABLE_VERSION) + .contentType(JSON) + .body(requestBody) + .when() + .post("/assets") + .then() + .log().ifValidationFails() + .statusCode(200); + } + + private String createPolicyDefinitionManagementContext(TractusxDcpParticipantBase participant, JsonObject policy) { + var requestBody = createObjectBuilder() + .add(CONTEXT, createArrayBuilder().add(EDC_CONNECTOR_MANAGEMENT_CONTEXT)) + .add(ID, UUID.randomUUID().toString()) + .add(TYPE, "PolicyDefinition") + .add(EDC_NAMESPACE + "policy", policy) + .build(); + + return participant.baseManagementRequest() + .basePath(OLDEST_STABLE_VERSION) + .contentType(JSON) + .body(requestBody) + .when() + .post("/policydefinitions") + .then() + .log().ifValidationFails() + .statusCode(200) + .extract().jsonPath().getString(ID); + } + + private void createContractDefinitionManagementContext(TractusxDcpParticipantBase participant, String assetId, String definitionId, String accessPolicyId, String contractPolicyId) { + var requestBody = createObjectBuilder() + .add(CONTEXT, createObjectBuilder() + .add("@vocab", EDC_NAMESPACE) + .build()) .add(ID, definitionId) .add(TYPE, "ContractDefinition") - .add(EDC_NAMESPACE + "accessPolicyId", accessPolicyId) - .add(EDC_NAMESPACE + "contractPolicyId", contractPolicyId) - .add(EDC_NAMESPACE + "assetsSelector", Json.createArrayBuilder() + .add("accessPolicyId", accessPolicyId) + .add("contractPolicyId", contractPolicyId) + .add("assetsSelector", createArrayBuilder() .add(createObjectBuilder() .add(TYPE, "Criterion") - .add(EDC_NAMESPACE + "operandLeft", EDC_NAMESPACE + "id") - .add(EDC_NAMESPACE + "operator", "=") - .add(EDC_NAMESPACE + "operandRight", assetId) + .add("operandLeft", "https://w3id.org/edc/v0.0.1/ns/id") + .add("operator", "=") + .add("operandRight", assetId) .build()) .build()) .build(); - return participant.baseManagementRequest() - .basePath("/v3") + participant.baseManagementRequest() + .basePath(OLDEST_STABLE_VERSION) .contentType(JSON) .body(requestBody) .when() @@ -292,8 +348,8 @@ private static class ParticipantsArgProvider implements ArgumentsProvider { @Override public Stream provideArguments(ExtensionContext context) { return Stream.of( - Arguments.of(REMOTE_PARTICIPANT, LOCAL_PARTICIPANT, DSP_08), - Arguments.of(LOCAL_PARTICIPANT, REMOTE_PARTICIPANT, DSP_08) + Arguments.of(REMOTE_PARTICIPANT, LOCAL_PARTICIPANT, DSP_2025), + Arguments.of(LOCAL_PARTICIPANT, REMOTE_PARTICIPANT, DSP_2025) ); } } diff --git a/edc-tests/runtime/runtime-compatibility/stable/connector-stable/build.gradle.kts b/edc-tests/runtime/runtime-compatibility/stable/connector-stable/build.gradle.kts index 9c48852d5e..0ee6eefbb8 100644 --- a/edc-tests/runtime/runtime-compatibility/stable/connector-stable/build.gradle.kts +++ b/edc-tests/runtime/runtime-compatibility/stable/connector-stable/build.gradle.kts @@ -37,7 +37,7 @@ dependencies { exclude("org.eclipse.edc", "vault-hashicorp") } runtimeOnly(project(":edc-tests:runtime:runtime-compatibility:stable:extensions")) - runtimeOnly(stableLibs.edc.identity.trust.sts.remote.client) + runtimeOnly(stableLibs.edc.spi.decentralized.claims) runtimeOnly(stableLibs.edc.auth.oauth2.client) } @@ -55,6 +55,7 @@ tasks.shadowJar { mergeServiceFiles() duplicatesStrategy = DuplicatesStrategy.INCLUDE archiveFileName.set("${project.name}.jar") + transform(com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer()) } // configure the "dockerize" task diff --git a/edc-tests/runtime/runtime-compatibility/stable/extensions/src/main/java/org/eclipse/tractusx/edc/compatibility/tests/AudienceSeedExtension.java b/edc-tests/runtime/runtime-compatibility/stable/extensions/src/main/java/org/eclipse/tractusx/edc/compatibility/tests/AudienceSeedExtension.java index ff2dda3210..f6252ca56d 100644 --- a/edc-tests/runtime/runtime-compatibility/stable/extensions/src/main/java/org/eclipse/tractusx/edc/compatibility/tests/AudienceSeedExtension.java +++ b/edc-tests/runtime/runtime-compatibility/stable/extensions/src/main/java/org/eclipse/tractusx/edc/compatibility/tests/AudienceSeedExtension.java @@ -46,13 +46,40 @@ public class AudienceSeedExtension implements ServiceExtension { @Provider public BdrsClient bdrsClient(ServiceExtensionContext context) { var dids = readDidsMapping(context); - return dids::get; + return new BdrsClient() { + @Override + public String resolveDid(String bpn) { + return dids.get(bpn); + } + + @Override + public String resolveBpn(String did) { + return dids.entrySet().stream() + .filter(e -> e.getValue().equals(did)) + .map(Map.Entry::getKey) + .findFirst() + .orElse(null); + } + }; } @Provider public AudienceResolver audienceResolver(ServiceExtensionContext context) { var dids = readDidsMapping(context); - return message -> Result.success(dids.get(message.getCounterPartyId())); + return message -> { + var counterPartyId = message.getCounterPartyId(); + + if (counterPartyId.startsWith("did:")) { + return Result.success(counterPartyId); + } + + var audience = dids.get(counterPartyId); + if (audience != null) { + return Result.success(audience); + } + + return Result.failure("No DID found for counter-party: " + counterPartyId); + }; } private Map readDidsMapping(ServiceExtensionContext context) { diff --git a/gradle/libs.stable.versions.toml b/gradle/libs.stable.versions.toml index c7e36ad42f..aa79129916 100644 --- a/gradle/libs.stable.versions.toml +++ b/gradle/libs.stable.versions.toml @@ -2,8 +2,8 @@ format.version = "1.1" [versions] -tractusx = "0.9.0" -edc = "0.11.1" +tractusx = "0.12.1" +edc = "0.15.1" [libraries] tx-edc-controlplane-postgresql-hashicorp-vault = { module = "org.eclipse.tractusx.edc:edc-controlplane-postgresql-hashicorp-vault", version.ref = "tractusx" } @@ -11,5 +11,5 @@ tx-edc-dataplane-postgresql-hashicorp-vault = { module = "org.eclipse.tractusx.e edc-boot-spi = { module = "org.eclipse.edc:boot-spi", version.ref = "edc" } edc-core-spi = { module = "org.eclipse.edc:core-spi", version.ref = "edc" } tx-bdrs-client-spi = { module = "org.eclipse.tractusx.edc:bdrs-client-spi", version.ref = "tractusx" } -edc-identity-trust-sts-remote-client = { module = "org.eclipse.edc:identity-trust-sts-remote-client", version.ref = "edc" } +edc-spi-decentralized-claims = { module = "org.eclipse.edc:decentralized-claims-spi", version.ref = "edc" } edc-auth-oauth2-client = { module = "org.eclipse.edc:oauth2-client", version.ref = "edc" } From 72b06aa8b2e1753e796b47830c666f49bfb998d1 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Fri, 24 Jul 2026 13:04:58 +0200 Subject: [PATCH 218/259] feat: update allure action to avoid simple-elf action and fix 2 zizmor foundings (#2979) * feat: update alure action to avoid simple-elf action and fix 2 zizmor foundings * feat:fix code injection via template expansion --- .../generate-and-publish-allure-report/action.yml | 11 ++++++----- .github/workflows/draft-release.yaml | 2 +- .github/workflows/verify.yaml | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/actions/generate-and-publish-allure-report/action.yml b/.github/actions/generate-and-publish-allure-report/action.yml index d5709660e5..df683b376f 100644 --- a/.github/actions/generate-and-publish-allure-report/action.yml +++ b/.github/actions/generate-and-publish-allure-report/action.yml @@ -42,11 +42,12 @@ runs: path: allure-results - name: Build Allure test report - uses: simple-elf/allure-report-action@e463a472d3b1d750f9544369d60589ff1964c820 # v1.14 - with: - gh_pages: gh-pages - allure_results: allure-results - allure_report: ${{ inputs.version }} + shell: bash + env: + VERSION: ${{ inputs.version }} + run: | + npm install -g allure-commandline + allure generate allure-results --clean -o "$VERSION" - name: Publish Allure test report to gh-pages uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0 diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 5d81b13655..54ea0e85c3 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -120,7 +120,7 @@ jobs: packages: write pages: write steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6.0.2 # zizmor: ignore[artipacked] + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: true - name: Create Release branch diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 0d54fa4aaf..5ea32b3d26 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -117,7 +117,7 @@ jobs: # generates coverage-report.md - name: JaCoCo Code Coverage Report id: jacoco_reporter - uses: PavanMudigonda/jacoco-reporter@e8b54bfea6a667d1a68624dae8a06ba31670667d # v5.1 + uses: PavanMudigonda/jacoco-reporter@112997f0c32da82d8bfa4a972b4afe67a15529fe # v5.2.1 with: coverage_results_path: build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml skip_check_run: true From 482180b0e928005b29ec56db9b8b06de0743a4f3 Mon Sep 17 00:00:00 2001 From: Jaro Hartmann <57985712+ds-jhartmann@users.noreply.github.com> Date: Tue, 28 Jul 2026 15:09:33 +0200 Subject: [PATCH 219/259] =?UTF-8?q?feat:=20add=20Kafka=20broker=20extensio?= =?UTF-8?q?n=20with=20OAuth2=20integration=20for=20data=20flo=E2=80=A6=20(?= =?UTF-8?q?#2876)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add Kafka broker extension with OAuth2 integration for data flow management (#1) * feat(kafka): add Kafka streaming dataplane extension (Kafka-PULL) * fix(kafka): re-architect Kafka-PULL onto the EDC 0.16.0 data-plane SPI EDC 0.16.0 removed DataFlowManager and made DataFlowController a single mandatory service, so the control-plane controller model the extension used no longer compiles. Re-implement as a data-plane extension: - add a ResourceDefinitionGenerator + Provisioner/Deprovisioner that mint the OAuth2 token and create/revoke Kafka ACLs, and an EndpointDataReferenceService that returns the broker EDR - the transfer type is now derived as KafkaBroker-PULL (from the KafkaBroker source type) - wire the extension into edc-dataplane-base instead of edc-controlplane-base; keep the DataAddress validator on the control plane - remove the control-plane KafkaBrokerDataFlowController and its tests; rewrite the extension test for the data-plane registrations Docs/ADRs and the e2e functional flow are updated in a follow-up. * docs(kafka): align docs/ADR with the EDC 0.16.0 data-plane model Transfer type is now KafkaBroker-PULL; the extension is a data-plane component wired into edc-dataplane-base. Updates the streaming README, extension README and the migration ADR (runtime wiring + the now-obsolete selector-strategy note). * chore(kafka): wire data-plane extension via implementation(project) to match edc-dataplane-base convention * fix(kafka): revoke broker ACLs on suspend via the EDR service suspend() only invokes revokeEndpointDataReference (it does not deprovision), so the previous no-op left ACLs/token live until TTL on suspend. Revoke the ACLs there now (it fires on both suspend and terminate; the id it receives is dataFlow.getId(), matching the ACL tracking key). Token revocation stays in the deprovisioner on terminate, where the client credentials are available; revokeAclsForTransferProcess is idempotent so the double call on terminate is a no-op. * fix(kafka): align e2e test with EDC 0.16.0 participant builder API TransferParticipant.Builder.protocol(...) now takes (protocol, path) in one call; the old protocol(..).protocolVersionPath(..) no longer compiles. This compile error in kafka-transfer-tests cascaded into every CI job (each compiles the full cross-module test source set before tag-filtering). * chore(kafka): add missing @Override annotations (CodeQL) Adds @Override on getAccessToken/revokeToken (KafkaOauthServiceImpl), validate (KafkaBrokerDataAddressValidator) and initialize (KafkaBrokerDataAddressValidatorExtension), per CodeQL code-scanning comments on the PR. * fix(kafka): manage broker ACLs per activation in the EDR service - create ACLs in createEndpointDataReference (runs on start AND resume), so resume restores access that suspend revoked; revoke stays on suspend/terminate (review #1) - read dataFlow.getActualSource() (EDC-idiomatic, like DataPlaneAuthorizationServiceImpl) instead of provisionedDataAddress() (review #2) - fail fast when the consumer-group prefix cannot be resolved (review #4) - the provisioner now only mints the OAuth token and builds the EDR * fix(kafka): harden Kafka deprovisioner and add coverage - throw a clear EdcException when the client secret is missing, mirroring the provisioner (review #5) - add KafkaDeprovisionerTest: token+ACL revoke, idempotent when token gone, ACL-disabled, failure propagation (review #3) * chore(kafka): wire validator via implementation(project) to match edc-controlplane-base convention * test(kafka): align KafkaBroker-PULL e2e tests to a shared pattern * test(kafka): verify EDR connection info and token revocation on terminate * test(kafka): retry flaky kafka-native testcontainer startup in e2e * docs(kafka): align docs with data-plane lifecycle and wiring * refactor(kafka): exclude Kafka extension from the base runtimes * docs(kafka): remove the PoC decision records * docs(kafka): move the documentation into the extension module --- edc-extensions/dataplane/kafka/README.md | 345 ++++++++++++++++ .../kafka/data-address-kafka/build.gradle.kts | 26 ++ .../KafkaBrokerDataAddressSchema.java | 93 +++++ .../Component diagram EDC Kafka Extension.png | Bin 0 -> 33047 bytes ...Component diagram EDC Kafka Extension.puml | 43 ++ ...ram EDC Kafka Extension data streaming.png | Bin 0 -> 37767 bytes ...am EDC Kafka Extension data streaming.puml | 28 ++ ... Extension provisioning-deprovisioning.png | Bin 0 -> 29466 bytes ...Extension provisioning-deprovisioning.puml | 35 ++ ...Kafka Extension start transfer process.png | Bin 0 -> 33997 bytes ...afka Extension start transfer process.puml | 31 ++ ...Kafka Extension suspending-terminating.png | Bin 0 -> 30148 bytes ...afka Extension suspending-terminating.puml | 38 ++ .../kafka/kafka-broker-extension/README.md | 48 +++ .../kafka-broker-extension/build.gradle.kts | 35 ++ .../dataplane/kafka/KafkaBrokerExtension.java | 136 +++++++ .../kafka/acl/AdminClientFactory.java | 29 ++ .../kafka/acl/DefaultAdminClientFactory.java | 32 ++ .../dataplane/kafka/acl/KafkaAclService.java | 60 +++ .../kafka/acl/KafkaAclServiceImpl.java | 175 ++++++++ .../kafka/auth/KafkaOauthService.java | 43 ++ .../kafka/auth/KafkaOauthServiceImpl.java | 123 ++++++ .../kafka/auth/OauthCredentials.java | 33 ++ .../KafkaEndpointDataReferenceService.java | 117 ++++++ .../kafka/provision/KafkaDeprovisioner.java | 111 +++++ .../provision/KafkaProvisionConstants.java | 44 ++ .../kafka/provision/KafkaProvisioner.java | 134 ++++++ .../KafkaResourceDefinitionGenerator.java | 53 +++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 + .../kafka/KafkaBrokerExtensionTest.java | 70 ++++ .../kafka/acl/KafkaAclServiceImplTest.java | 192 +++++++++ ...KafkaAclServiceImplTestcontainersTest.java | 380 ++++++++++++++++++ .../auth/KafkaOauthServiceComponentTest.java | 140 +++++++ .../kafka/auth/KafkaOauthServiceImplTest.java | 166 ++++++++ ...KafkaEndpointDataReferenceServiceTest.java | 144 +++++++ .../provision/KafkaDeprovisionerTest.java | 131 ++++++ .../kafka/provision/KafkaProvisionerTest.java | 124 ++++++ .../build.gradle.kts | 30 ++ .../KafkaBrokerDataAddressValidator.java | 60 +++ ...kaBrokerDataAddressValidatorExtension.java | 46 +++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 + ...okerDataAddressValidatorExtensionTest.java | 54 +++ .../KafkaBrokerDataAddressValidatorTest.java | 72 ++++ edc-tests/e2e-fixtures/build.gradle.kts | 2 + .../edc/tests/kafka/KafkaExtension.java | 123 ++++++ .../e2e/kafka-transfer-tests/build.gradle.kts | 40 ++ .../tests/transfer/KafkaPullEndToEndTest.java | 229 +++++++++++ .../runtime-postgresql/build.gradle.kts | 4 + gradle/libs.versions.toml | 3 + settings.gradle.kts | 4 + 50 files changed, 3866 insertions(+) create mode 100644 edc-extensions/dataplane/kafka/README.md create mode 100644 edc-extensions/dataplane/kafka/data-address-kafka/build.gradle.kts create mode 100644 edc-extensions/dataplane/kafka/data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/dataaddress/KafkaBrokerDataAddressSchema.java create mode 100644 edc-extensions/dataplane/kafka/diagrams/Component diagram EDC Kafka Extension.png create mode 100644 edc-extensions/dataplane/kafka/diagrams/Component diagram EDC Kafka Extension.puml create mode 100644 edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension data streaming.png create mode 100644 edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension data streaming.puml create mode 100644 edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension provisioning-deprovisioning.png create mode 100644 edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension provisioning-deprovisioning.puml create mode 100644 edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension start transfer process.png create mode 100644 edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension start transfer process.puml create mode 100644 edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension suspending-terminating.png create mode 100644 edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension suspending-terminating.puml create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/README.md create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/build.gradle.kts create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/KafkaBrokerExtension.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/AdminClientFactory.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/DefaultAdminClientFactory.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclService.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImpl.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthService.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceImpl.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/OauthCredentials.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/flow/KafkaEndpointDataReferenceService.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaDeprovisioner.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisionConstants.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisioner.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaResourceDefinitionGenerator.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/KafkaBrokerExtensionTest.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTest.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTestcontainersTest.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceComponentTest.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceImplTest.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/flow/KafkaEndpointDataReferenceServiceTest.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaDeprovisionerTest.java create mode 100644 edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisionerTest.java create mode 100644 edc-extensions/dataplane/kafka/validator-data-address-kafka/build.gradle.kts create mode 100644 edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidator.java create mode 100644 edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorExtension.java create mode 100644 edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/dataplane/kafka/validator-data-address-kafka/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorExtensionTest.java create mode 100644 edc-extensions/dataplane/kafka/validator-data-address-kafka/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorTest.java create mode 100644 edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/kafka/KafkaExtension.java create mode 100644 edc-tests/e2e/kafka-transfer-tests/build.gradle.kts create mode 100644 edc-tests/e2e/kafka-transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/KafkaPullEndToEndTest.java diff --git a/edc-extensions/dataplane/kafka/README.md b/edc-extensions/dataplane/kafka/README.md new file mode 100644 index 0000000000..f469087d94 --- /dev/null +++ b/edc-extensions/dataplane/kafka/README.md @@ -0,0 +1,345 @@ +# Kafka Streaming Extension + +The Kafka streaming extension provides the `KafkaBroker-PULL` transfer type, enabling real-time, +event-driven data exchange between sovereign partners over Apache Kafka. + +Unlike a proxied transfer, data flows **directly** from the provider's Kafka broker to the consumer. +The EDC stays in charge of access: the data-plane extension provisions short-lived OAuth2 +credentials (and, optionally, Kafka ACLs) for the duration of a negotiated transfer, so the provider +retains full control over the consumer's access throughout. + + +* [Including the extension in a runtime](#including-the-extension-in-a-runtime) +* [Overview](#overview) +* [Architecture](#architecture) + * [Components](#components) + * [Component diagram](#component-diagram) +* [Transfer Workflow](#transfer-workflow) + * [A. Provisioning/Deprovisioning](#a-provisioningdeprovisioning) + * [B. Initiating the Transfer](#b-initiating-the-transfer) + * [C. Data Streaming](#c-data-streaming) + * [D. Suspending/Terminating](#d-suspendingterminating) +* [DataAddress Schema](#dataaddress-schema) +* [Configuration](#configuration) + * [EDC data plane properties](#edc-data-plane-properties) + * [Kafka broker](#kafka-broker) + * [Keycloak](#keycloak) +* [Security and Token Model](#security-and-token-model) + * [Authentication flow](#authentication-flow) + * [Token expiry and revocation](#token-expiry-and-revocation) + * [Kafka ACL management (optional)](#kafka-acl-management-optional) + * [Transport encryption (SASL_SSL)](#transport-encryption-sasl_ssl) +* [Interoperability and Standards](#interoperability-and-standards) +* [Troubleshooting](#troubleshooting) +* [NOTICE](#notice) + + +## Including the extension in a runtime + +The extension is **not** part of the released `tractusx-connector` runtimes — it is opt-in, so +adopters who need Kafka streaming assemble it into their own runtime. Add the data-plane extension +to the data plane and the data address validator to the control plane: + +```kotlin +// data plane +implementation(project(":edc-extensions:dataplane:kafka:kafka-broker-extension")) + +// control plane +implementation(project(":edc-extensions:dataplane:kafka:validator-data-address-kafka")) +``` + +Both modules are published as regular Maven artifacts under the `org.eclipse.tractusx.edc` group, so +runtimes built outside this repository can depend on them the same way. + +## Overview + +Kafka topics are treated as EDC data assets: a topic carries domain-specific business data (e.g. +semantic models such as `SerialPart` or `Batch`), the provider registers it as an asset with a usage +policy, and consumers gain access through the standard EDC contract negotiation. On successful +negotiation the consumer receives an Endpoint Data Reference (EDR) containing the connection details +and an OAuth2 token, which it uses to subscribe to and poll the topic directly. All exchanges are +tracked in the EDC (contract id, asset id, timestamps) for auditability. + +`SASL/OAUTHBEARER` ([RFC 7628](https://datatracker.ietf.org/doc/html/rfc7628)) is used as the Kafka +authentication mechanism, allowing OAuth2 tokens to authenticate the consumer against the broker. + +Typical Catena-X use cases that benefit from Kafka streaming include Quality Management (predictive +maintenance, early-warning notifications), Digital Twin / Asset Administration Shell (real-time +operational and condition monitoring), Demand & Capacity Management, Traceability, Circular Economy / +Product Pass, and ESG monitoring. + +## Architecture + +### Components + +The extension consists of three modules under `edc-extensions/dataplane/kafka/`: + +1. **Kafka Broker Extension** (`kafka-broker-extension`): a data-plane extension that adds the + `KafkaBroker-PULL` transfer type. It provisions OAuth2 credentials and optional Kafka ACLs, stores + tokens in the EDC Vault, builds the EDR for the consumer, and revokes credentials on + suspend/terminate. +2. **Data Address Kafka** (`data-address-kafka`): defines the `KafkaBroker` data address format + (topic, bootstrap servers, security protocol, SASL mechanism, OAuth2 settings, consumer group). +3. **Validator Data Address Kafka** (`validator-data-address-kafka`): validates that a Kafka data + address contains all required properties with valid values. + +These integrate with: + +- **Eclipse Dataspace Connector (EDC)** — the core framework for negotiation and data exchange +- **Apache Kafka** — the messaging platform for data streaming +- **OAuth2 provider** (e.g. Keycloak) — for authentication and authorization + +The roles involved at runtime are the **Control Plane** (negotiation, policy checks), the **Kafka +Extension** (credential orchestration and Vault access), the **Kafka Service** (broker enforcing +SASL/OAUTHBEARER and topic authorization), the **OAuth Service** (issues and revokes tokens), and the +**Vault** (secure storage of temporary credentials). On the consumer side, the **Consumer Control +Plane** receives the EDR and the **Consumer Application** uses it to instantiate a Kafka consumer. + +### Component diagram + +![Component diagram EDC Kafka Extension](diagrams/Component%20diagram%20EDC%20Kafka%20Extension.png) + +## Transfer Workflow + +The transfer is defined by four phases, each illustrated by a sequence diagram. + +### A. Provisioning/Deprovisioning + +**Purpose:** securely create or delete consumer credentials. + +1. **Provisioning:** the Consumer Control Plane sends a `TransferRequestMessage` to the Provider + Control Plane, which sends a `DataFlowStartMessage` (Data Plane Signaling) to the data plane. + There the Kafka Extension reads the OAuth2 client secret from the Vault, obtains a short-lived + access token from the OAuth Service, stores it in the Vault, and returns the provisioned Kafka + `DataAddress` in the `DataFlowResponseMessage`. +2. **Deprovisioning:** when the transfer is terminated, the Provider Control Plane signals the + termination to the data plane; the Kafka Extension revokes the token via the OAuth Service and + deletes it from the Vault. + +![Sequence diagram EDC Kafka Extension provisioning-deprovisioning](diagrams/Sequence%20diagram%20EDC%20Kafka%20Extension%20provisioning-deprovisioning.png) + +### B. Initiating the Transfer + +**Purpose:** start a transfer process with dynamic credentials and EDR creation. + +1. The Consumer Control Plane instructs the Provider Control Plane to start the transfer; the Provider + Control Plane performs policy and contract verification. +2. The Provider Control Plane sends a `DataFlowStartMessage` (Data Plane Signaling) to the data + plane, where the Kafka Extension requests a fresh OAuth2 access token from the OAuth Service via + the Client Credentials flow (no refresh token) and creates a `DataAddress` containing the + connection details (bootstrap servers, topic, security protocol, SASL mechanism, OAuth token, + poll duration, and consumer group prefix). The Provider Control Plane then sends a + `TransferStartMessage` with the complete DataAddress to the Consumer Control Plane, which + constructs the final EDR. + +![Sequence diagram EDC Kafka Extension start transfer process](diagrams/Sequence%20diagram%20EDC%20Kafka%20Extension%20start%20transfer%20process.png) + +### C. Data Streaming + +**Purpose:** establish a secure, token-based data stream between consumer and Kafka Service. + +The Consumer Application requests the EDR, instantiates a Kafka consumer, and authenticates against +the Kafka Service (which validates the token). It then polls the topic for messages. The token is +short-lived; the consumer polls until it expires — there is no token refresh, a new transfer mints a +new token. + +![Sequence diagram EDC Kafka Extension data streaming](diagrams/Sequence%20diagram%20EDC%20Kafka%20Extension%20data%20streaming.png) + +### D. Suspending/Terminating + +**Purpose:** securely suspend or terminate the transfer by revoking consumer credentials. + +The Provider Control Plane signals the suspension or termination to the data plane. On suspend, the +Kafka Extension revokes the consumer's ACLs (when ACL management is enabled); the short-lived token +remains valid until it expires, and a resume re-creates the ACLs. On terminate, the extension +additionally calls the OAuth Service to revoke the token and removes it from the Vault. The Consumer +Control Plane is notified that the transfer has been suspended or terminated. + +![Sequence diagram EDC Kafka Extension suspending-terminating](diagrams/Sequence%20diagram%20EDC%20Kafka%20Extension%20suspending-terminating.png) + +## DataAddress Schema + +A Kafka asset is published with a `DataAddress` of type `KafkaBroker`: + +| Property | Description | Mandatory | +|---|---|---| +| `type` | Must be `KafkaBroker` | Yes | +| `https://w3id.org/edc/v0.0.1/ns/topic` | Kafka topic name | Yes | +| `https://w3id.org/edc/v0.0.1/ns/kafka.bootstrap.servers` | Kafka bootstrap servers | Yes | +| `https://w3id.org/edc/v0.0.1/ns/kafka.sasl.mechanism` | SASL mechanism (e.g., `OAUTHBEARER`) | Yes | +| `https://w3id.org/edc/v0.0.1/ns/kafka.security.protocol` | Security protocol (e.g., `SASL_PLAINTEXT`, `SASL_SSL`) | Yes | +| `https://w3id.org/edc/v0.0.1/ns/tokenUrl` | OAuth2 token endpoint URL | Yes | +| `https://w3id.org/edc/v0.0.1/ns/clientId` | OAuth2 client ID | Yes | +| `https://w3id.org/edc/v0.0.1/ns/clientSecretKey` | Vault entry key for the OAuth2 client secret | Yes | +| `https://w3id.org/edc/v0.0.1/ns/revokeUrl` | OAuth2 token revocation endpoint | No | +| `https://w3id.org/edc/v0.0.1/ns/kafka.poll.duration` | ISO-8601 consumer poll duration (default `PT1S`) | No | +| `https://w3id.org/edc/v0.0.1/ns/kafka.group.prefix` | Consumer group prefix the consumer is authorized to use; also scopes the consumer-group ACL. Defaults to the consumer participant id when omitted. | No | + +> Property keys may be written as full IRIs (as in the table above) or with the `edc:` prefix (as in the +> example below); both are equivalent after JSON-LD expansion. + +Example asset registration: + +```json +{ + "@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/" }, + "@type": "Asset", + "@id": "kafka-asset-1", + "properties": { "name": "My Kafka Stream" }, + "dataAddress": { + "type": "KafkaBroker", + "edc:topic": "my-topic", + "edc:kafka.bootstrap.servers": "kafka:9092", + "edc:kafka.sasl.mechanism": "OAUTHBEARER", + "edc:kafka.security.protocol": "SASL_PLAINTEXT", + "edc:tokenUrl": "http://keycloak:8080/realms/kafka/protocol/openid-connect/token", + "edc:revokeUrl": "http://keycloak:8080/realms/kafka/protocol/openid-connect/revoke", + "edc:clientId": "edc-provider", + "edc:clientSecretKey": "edc-provider-secret" + } +} +``` + +## Configuration + +### EDC data plane properties + +| Property | Description | Default | +|---|---|---| +| `edc.dataplane.kafka.acl.enabled` | Enable Kafka ACL management | `false` | +| `edc.dataplane.kafka.acl.bootstrap.servers` | Kafka broker addresses for admin ACL operations | — | +| `edc.dataplane.kafka.acl.security.protocol` | Security protocol for the admin client | `PLAINTEXT` | +| `edc.dataplane.kafka.acl.sasl.mechanism` | SASL mechanism for the admin client | — | +| `edc.dataplane.kafka.acl.sasl.jaas.config` | JAAS config for the admin client | — | + +> **Note:** The bootstrap servers, security protocol, and SASL settings are only required when ACL +> management is enabled (`edc.dataplane.kafka.acl.enabled=true`). + +### Kafka broker + +Configure the Kafka broker for OAuth/SASL authentication: + +```properties +# KRaft mode (no ZooKeeper) +kafka.process.roles=broker,controller +kafka.controller.quorum.voters=1@kafka:29093 +kafka.controller.listener.names=CONTROLLER + +# Listeners & Protocols +kafka.listener.security.protocol.map=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,OIDC:SASL_PLAINTEXT +kafka.listeners=PLAINTEXT://kafka:29092,CONTROLLER://kafka:29093,OIDC://0.0.0.0:9092 +kafka.advertised.listeners=PLAINTEXT://kafka:29092,OIDC://kafka:9092 +kafka.inter.broker.listener.name=PLAINTEXT + +# Enable SASL/OAUTHBEARER authentication +kafka.sasl.enabled.mechanisms=OAUTHBEARER +kafka.sasl.oauthbearer.jwks.endpoint.url=http://keycloak:8080/realms/kafka/protocol/openid-connect/certs +kafka.sasl.oauthbearer.token.endpoint.url=http://keycloak:8080/realms/kafka/protocol/openid-connect/token +kafka.sasl.oauthbearer.expected.audience=account +``` + +### Keycloak + +Set up a realm (e.g. `kafka`) with clients for the EDC provider (`edc-provider`) and consumer +(`edc-consumer`), configure client credentials (client id + secret) for each, and set an appropriate +token TTL (recommended: 5 minutes). + +## Security and Token Model + +### Authentication flow + +The extension uses the OAuth2 Client Credentials flow: + +1. When a transfer process starts, the extension calls the OAuth2 token endpoint with the provider's + client credentials. +2. The returned JWT is stored in the EDC Vault keyed by the transfer process id. +3. The token is included in the EDR sent to the consumer. +4. On terminate, the extension calls the token revocation URL (if configured) and deletes the token + from the Vault. On suspend, broker access is cut by revoking the consumer's ACLs (when ACL + management is enabled) while the short-lived token simply expires. + +### Token expiry and revocation + +The implementation does not use refresh tokens — each transfer mints a single short-lived access +token, so access naturally ends when the token expires. Configure the token TTL in the OAuth2 +provider accordingly (recommended: 5 minutes). + +Because the broker validates the access token by signature and expiry (not by a revocation lookup), a +token that has been revoked at the OAuth2 server can remain usable at the broker until it expires. +Immediate broker-level cutoff is therefore provided by **ACL revocation** when ACL management is +enabled; otherwise access ends at the token's TTL. + +### Kafka ACL management (optional) + +When `edc.dataplane.kafka.acl.enabled=true`: + +1. On transfer start, the extension extracts the `sub` claim from the JWT (used as the Kafka + principal, `User:`). +2. It creates three ACL bindings for that principal: `READ` and `DESCRIBE` on the topic, and `READ` on + the consumer group prefix (the `kafka.group.prefix`, defaulting to the consumer participant id) — the same + prefix handed to the consumer in the EDR, so the broker grant matches what the consumer is told to + use. +3. On suspend/terminate, the ACLs are revoked immediately — closing the access window even before the + token expires. On resume they are re-created. + +### Transport encryption (SASL_SSL) + +Because the extension allows topic consumption across company borders, end-to-end encryption is +recommended for production: switch the security protocol from `SASL_PLAINTEXT` to `SASL_SSL` (set +`kafka.security.protocol` accordingly in the data address). With the default client configuration all +public CA-signed certificates are accepted; the consumer client can also be configured to trust a +custom certificate. + +## Interoperability and Standards + +The extension does not change anything related to IATP, DSP, or policy definitions, ensuring +conformity to [CX-0018 Dataspace Connectivity v.3.1.0](https://catenax-ev.github.io/docs/standards/CX-0018-DataspaceConnectivity) +(chapters 2.1, 2.3, 2.4 and 2.5). + +Since the extension introduces the new transfer type `KafkaBroker-PULL`, the standard should be extended +by this type. An example of such an extension: + +> 2.2.3 KafkaBroker-PULL +> +> A Consumer MUST send a `dspace:TransferRequestMessage` with `dct:format:dspace:KafkaBroker-PULL`. +> +> A Provider MUST send a `dspace:TransferStartMessage` with sufficient information in the +> `dspace:dataAddress` property so that a client connection to the `dspace:endpoint` may succeed when +> initialized with the properties `groupPrefix` and `topic`. +> +> A Provider Connector MUST ensure that the requested backend system has sufficient context from the +> negotiation to evaluate the legitimacy of the request. +> +> A Consumer may then use the provided data to execute requests against the endpoint. Despite the +> token, the endpoint still has the right to refuse serving a request — for instance when a consumer +> requests a different topic than the one specified in the `dspace:dataAddress`. + +For background on EDC extension development, see the +[EDC Contributors Manual](https://eclipse-edc.github.io/documentation/for-contributors/), in +particular [Modules, Runtimes, and Components](https://eclipse-edc.github.io/documentation/for-adopters/modules-runtimes-components/), +[Extensions](https://eclipse-edc.github.io/documentation/for-adopters/extensions/), and the +[Data Plane Signaling interface](https://eclipse-edc.github.io/documentation/for-contributors/data-plane/data-plane-signaling/). + +## Troubleshooting + +**Connection issues** +- Verify Kafka bootstrap servers are reachable from the EDC data plane. +- Check that the security protocol and SASL mechanism match the broker configuration. + +**Authentication issues** +- Verify the OAuth2 client credentials are correct and stored in the Vault. +- Check that the token URL is reachable from the EDC data plane. +- Confirm the Vault key name matches `clientSecretKey` in the data address. + +**ACL issues** (only when ACL management is enabled) +- Verify the admin client has superuser privileges in Kafka. +- Confirm the JWT contains a `sub` claim (used as the Kafka principal). +- Check that the Kafka broker has an authorizer configured (`StandardAuthorizer`). + +## NOTICE + +This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). + +- SPDX-License-Identifier: CC-BY-4.0 +- SPDX-FileCopyrightText: 2025 Contributors to the Eclipse Foundation +- Source URL: diff --git a/edc-extensions/dataplane/kafka/data-address-kafka/build.gradle.kts b/edc-extensions/dataplane/kafka/data-address-kafka/build.gradle.kts new file mode 100644 index 0000000000..b0a8b9f0a9 --- /dev/null +++ b/edc-extensions/dataplane/kafka/data-address-kafka/build.gradle.kts @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + `java-library` +} + +dependencies { + api(libs.edc.spi.core) +} diff --git a/edc-extensions/dataplane/kafka/data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/dataaddress/KafkaBrokerDataAddressSchema.java b/edc-extensions/dataplane/kafka/data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/dataaddress/KafkaBrokerDataAddressSchema.java new file mode 100644 index 0000000000..70adcdf389 --- /dev/null +++ b/edc-extensions/dataplane/kafka/data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/dataaddress/KafkaBrokerDataAddressSchema.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.dataaddress; + +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; + +/** + * Defines the schema of a DataAddress representing a Kafka endpoint. + */ +public interface KafkaBrokerDataAddressSchema { + + /** + * The transfer type. + */ + String KAFKA_TYPE = "KafkaBroker"; + + /** + * The Kafka topic that will be allowed to poll for the consumer. + */ + String TOPIC = EDC_NAMESPACE + "topic"; + + /** + * The kafka.bootstrap.servers property. + */ + String BOOTSTRAP_SERVERS = EDC_NAMESPACE + "kafka.bootstrap.servers"; + + /** + * The kafka.poll.duration property which specifies the duration of the consumer polling. + *

+ * The value should be a ISO-8601 duration e.g. "PT10S" for 10 seconds. + * This parameter is optional. The default value is 1 second. + * + * @see java.time.Duration#parse(CharSequence) for ISO-8601 duration format + */ + String POLL_DURATION = EDC_NAMESPACE + "kafka.poll.duration"; + + /** + * The kafka.group.prefix that will be allowed to use for the consumer. + */ + String GROUP_PREFIX = EDC_NAMESPACE + "kafka.group.prefix"; + + /** + * The security.protocol property. + */ + String PROTOCOL = EDC_NAMESPACE + "kafka.security.protocol"; + + /** + * The sasl.mechanism property. + */ + String MECHANISM = EDC_NAMESPACE + "kafka.sasl.mechanism"; + + /** + * The authentication token. + */ + String TOKEN = EDC_NAMESPACE + "token"; + + /** + * The OAuth token URL for retrieving access tokens. + */ + String OAUTH_TOKEN_URL = EDC_NAMESPACE + "tokenUrl"; + + /** + * The OAuth revoke URL for invalidating tokens. + */ + String OAUTH_REVOKE_URL = EDC_NAMESPACE + "revokeUrl"; + + /** + * The OAuth client ID. + */ + String OAUTH_CLIENT_ID = EDC_NAMESPACE + "clientId"; + + /** + * The OAuth client secret key. + */ + String OAUTH_CLIENT_SECRET_KEY = EDC_NAMESPACE + "clientSecretKey"; +} diff --git a/edc-extensions/dataplane/kafka/diagrams/Component diagram EDC Kafka Extension.png b/edc-extensions/dataplane/kafka/diagrams/Component diagram EDC Kafka Extension.png new file mode 100644 index 0000000000000000000000000000000000000000..2d1de24deea03c14894212bbf8ac6dd4961ec400 GIT binary patch literal 33047 zcmZ6x18`=~6D}NcW7`|s-e_ZNY;BSaHnwfs-q^Nn+qO5>clP(cx4x=-s@}ZyPI`Lg z%uIJrKmCL%$cZDs;lhD{fFMXph$@1BfE@v!LKtwMWo4tA6$AuyNkK+g4EPBH0}Trc zi-Zh3h?tmISXkJ&xLDZO*n~vHM8qUyWJDBSDZf%uQBqOU(tf35V5DbcVq|7vWu<3h z=Va&L;^g8H6yy{X6yz5a68I)8B*ZNuCNBD2LR?Z>LPAhlT38x*

BT6crS{tEtH- zs;DWcs;j7LYG}ym=_zRfkB+{M{!e{< z+uIvEIhoqn*w{O}Ik|bdxR`l++jx3AD;XXX`U4`v-@3H4G`+Mjv%ERCy1l&Ixwh85wzjssb+EjBxN&f{vom;jIJ&>TzkPJMb9{Al zd4GOBb$K~+adB~c^>BRsc=h;kb2I<&uzUkNkMGw{pC2DvpP$>GpP!D*DrUge(m05z zJN&e^as6#<;s7FUY-Ma`;9zV-Z0JgC>fm5w&%?-Q^V`76!O`+J!%u5Vr^!(w;FKhr zDXTmD-*ymCK#xnth3XIaH6~=Q$Es#WqBBo{+hP(`j~wrc zv!UbAgwLo%jfR$dn+xtC=IM$SAS76dktVUt84EAgxo9!JCW08=^5%_e((JI3gk|93Mfy@S>N8j^|n+Heslx9QlJO zXKM6J(8%d)*JpSz< z{DJG7A=WNBVG$LczVZkSX0(R7)H@K)FmS(CtBTJ>Y=UTc#riatIqrGxh2CkSERChZ z2$hTj6?CaZv*Q|&O53bdQbJO96^k{Z8;sgdTWMdeBl*G*CQCwne&J|-+Lh$0&)KI_ z1n>!*Zw_bp8P>-tW5h`tbzy>0o`t5hsA^iTl4sI_O+V=b^;PQ zOUX<&gs?1hEp+RLCAS`=g`=!bBSS8d-n5V#vlqNFd{lixL-K|s3(g?t$m3eokr|8J z5Wmy+q*u_<$q#nv$9zk{)rWt7KDuTec7{L0d3oO9@lAE_oEN&vK|nl6B}IjlT~^OC zVLi}PKDxaV1!p5K#G1VIIg8Rt!+JKAS{P&ebX`Mh!sH* zQ&vZJE@?wg6v@S>7e=8{qn);c__HHXFB?YQV6=Lh&CANYI&Ks1@pjs`jhxCnC zXM$B)4Z7B=pM~m&n4EaG{;?YLt)<>G-7IPLdjP@yk)3`J%8Jw)GLtLC=URGMJ<1N$ zM)0UFJP(znABN28{Jx|Kg0F$K4 z`D{w^9gf|o^>S^CiJv7MMxo_^^4Lk9rYK!S{kPORILLFn@a^bz8y?n=H zY0bK2n$pZ^H~evpjB;_Y{_ca<+gK@1H5VZ-20Tn3<(J`3j2D5&x!-TBwep>8^gkB^ z!2=s62o6gamX0Aw=^2YZU>Ci)4x3aX$OFE=^*m?fKM8>xO^D#B%gW?=f@AAWr){)S zR>R$er*XU)Skp%6m$^Lek*#|BBvr-eq2zMp-^uMC!HjJGts(>2

iH6MwmwI}Wv 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 ProducerAPI : Send stream of data to topic +ConsumerCP <--> ProviderCP : Initiate negotiation, transfer +ProviderCP --> ProviderKE : Start/suspend/terminate data flow\n(Data Plane Signaling) +ProviderKE --> OAuth2API : Mint/revoke access token +[Vault] <--> ProviderKE : Read client secret,\nstore/delete token +ProviderKE --> Kafka : Create/revoke ACLs (optional,\nvia admin client) +Kafka --> OAuth2API : Validate token +ConsumerApp --> ConsumerCP : Get EDR +ConsumerApp --> ConsumeAPI : Poll data (SASL/OAUTHBEARER) +@enduml diff --git a/edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension data streaming.png b/edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension data streaming.png new file mode 100644 index 0000000000000000000000000000000000000000..67840bc4065f20885f994eafce6189369cc1959b GIT binary patch literal 37767 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 ConsumerCP : Request for EDR +ConsumerApp <-- ConsumerCP : Response with EDR +ConsumerApp -> Kafka : Authentication +Kafka -> OAuth2 : Authentication +Kafka <-- OAuth2 : Authentication success +ConsumerApp <-- Kafka : Authentication success +loop while token is valid + ConsumerApp -> Kafka : Poll data + ConsumerApp <-- Kafka : Polling data +end loop +@enduml \ No newline at end of file diff --git a/edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension provisioning-deprovisioning.png b/edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension provisioning-deprovisioning.png new file mode 100644 index 0000000000000000000000000000000000000000..8ee528979d5858e4501df4828d7788835fbb0dac GIT binary patch literal 29466 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 ProviderCP : Send TransferRequestMessage +ProviderCP -> ProviderDP : Send DataFlowStartMessage\n(Data Plane Signaling) +ProviderDP -> Vault : Read OAuth2 client secret +ProviderDP <-- Vault : Client secret +ProviderDP -> OAuth2 : Request access token\n(Client Credentials flow) +ProviderDP <-- OAuth2 : Access token +ProviderDP -> Vault : Store token (keyed by flow id) +ProviderCP <-- ProviderDP : DataFlowResponseMessage\nwith Kafka DataAddress (EDR) + +== Deprovision (transfer terminate) == +ProviderCP -> ProviderDP : Terminate data flow\n(Data Plane Signaling) +ProviderDP -> Vault : Read token +ProviderDP <-- Vault : Token +ProviderDP -> OAuth2 : Revoke token (revokeUrl) +ProviderDP <-- OAuth2 : Token revoked +ProviderDP -> Vault : Delete token +ProviderCP <-- ProviderDP : Flow terminated +@enduml diff --git a/edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension start transfer process.png b/edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension start transfer process.png new file mode 100644 index 0000000000000000000000000000000000000000..1ea6397e5867939dd8b258521737cd64475c52cc GIT binary patch literal 33997 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 ProviderCP : Start transfer process\n(TransferRequestMessage) +ProviderCP -> ProviderCP : Check policy, contract etc. +ProviderCP -> ProviderDP : Send DataFlowStartMessage\n(Data Plane Signaling) +ProviderDP -> OAuth2 : Request access token\n(Client Credentials flow, no refresh token) +ProviderDP <-- OAuth2 : Access token +ProviderDP -> ProviderDP : Build Kafka DataAddress\n(bootstrap servers, topic, security protocol,\nSASL mechanism, group prefix, poll duration, token) +opt ACL management enabled + ProviderDP -> Kafka : Create ACLs for token subject + ProviderDP <-- Kafka : ACLs created +end +ProviderCP <-- ProviderDP : DataFlowResponseMessage\nwith Kafka DataAddress +ProviderCP -> ConsumerCP : Send TransferStartMessage\nattaching DataAddress +ConsumerCP -> ConsumerCP : Create EDR with DataAddress +@enduml diff --git a/edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension suspending-terminating.png b/edc-extensions/dataplane/kafka/diagrams/Sequence diagram EDC Kafka Extension suspending-terminating.png new file mode 100644 index 0000000000000000000000000000000000000000..8df4907fc4cc7bd2fb9af26258d9f7a9888ef2a9 GIT binary patch literal 30148 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 ProviderDP : Suspend data flow\n(Data Plane Signaling) +opt ACL management enabled + ProviderDP -> Kafka : Revoke consumer ACLs + ProviderDP <-- Kafka : ACLs revoked +end +note over ProviderDP : The token is not revoked on suspend —\nit expires on its own; a resume\nre-creates the ACLs +ProviderCP <-- ProviderDP : Flow suspended +ConsumerCP <-- ProviderCP : Transfer suspended + +== Terminate == +ProviderCP -> ProviderDP : Terminate data flow\n(Data Plane Signaling) +opt ACL management enabled + ProviderDP -> Kafka : Revoke consumer ACLs + ProviderDP <-- Kafka : ACLs revoked +end +ProviderDP -> OAuth2 : Revoke token (revokeUrl) +ProviderDP <-- OAuth2 : Token revoked +ProviderDP -> ProviderDP : Delete token from vault +ProviderCP <-- ProviderDP : Flow terminated +ConsumerCP <-- ProviderCP : Transfer terminated +@enduml diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/README.md b/edc-extensions/dataplane/kafka/kafka-broker-extension/README.md new file mode 100644 index 0000000000..3e742ef0dc --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/README.md @@ -0,0 +1,48 @@ +# Kafka Broker Extension + +## Overview + +The Kafka Broker Extension is a data-plane extension that enables secure, dynamic +access to Kafka topics within the Tractus-X EDC. It allows data providers to share +Kafka streams with consumers while maintaining full control over access permissions +through per-transfer OAuth2 credentials. + +## Sibling modules + +This extension lives alongside two supporting modules under `edc-extensions/dataplane/kafka/`: + +- **`data-address-kafka`** — defines the `KafkaBrokerDataAddressSchema` constants for + Kafka data address properties. +- **`validator-data-address-kafka`** — validates that a `DataAddress` of type + `KafkaBroker` carries all required properties before a transfer is initiated. + +## Transfer type + +The extension adds the **`KafkaBroker-PULL`** transfer type to the EDC data plane +via a provisioner and an EDR service. The provisioning lifecycle: + +1. **start** — provisions a fresh OAuth2 access token via the Client Credentials + flow, stores it in the provider vault keyed by the transfer process id, and + returns an EDR containing the bootstrap servers, topic, security protocol, SASL + mechanism, consumer group prefix, poll duration, and token. When ACL + management is enabled, it also creates the consumer's Kafka ACLs. +2. **suspend** — revokes the consumer's ACLs (when ACL management is enabled), cutting + broker access immediately; the short-lived token itself stays in the vault and remains + valid until it expires. On **resume** the ACLs are re-created. +3. **terminate** — revokes the token at the OAuth2 server's revocation endpoint (if a + `revokeUrl` is configured), removes it from the vault, and — when ACL management is + enabled — revokes the consumer's ACLs. + +## Configuration + +Kafka ACL management is optional and disabled by default. When enabled, the data plane manages +broker-level authorization for each transfer through a Kafka admin client, configured via the +`edc.dataplane.kafka.acl.*` settings — see +[Configuration](../README.md#configuration). + +## Further reading + +The `KafkaBroker` data address schema, the full configuration reference (EDC data plane, Kafka +broker, Keycloak), the security and token model, the end-to-end transfer workflow, and how to +include the extension in a runtime are documented in +[Kafka Streaming Extension](../README.md). diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/build.gradle.kts b/edc-extensions/dataplane/kafka/kafka-broker-extension/build.gradle.kts new file mode 100644 index 0000000000..c89111eaf0 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/build.gradle.kts @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + `java-library` +} + +dependencies { + implementation(libs.edc.spi.core) + implementation(libs.edc.spi.dataplane.dataplane) + implementation(libs.edc.spi.http) + implementation(libs.edc.lib.util) + implementation(libs.kafka.clients) + implementation(project(":edc-extensions:dataplane:kafka:data-address-kafka")) + + testImplementation(libs.edc.junit) + testImplementation(libs.testcontainers.junit) + testImplementation(libs.testcontainers.kafka) +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/KafkaBrokerExtension.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/KafkaBrokerExtension.java new file mode 100644 index 0000000000..6f6bd2a6ae --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/KafkaBrokerExtension.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka; + +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.eclipse.edc.connector.dataplane.spi.edr.EndpointDataReferenceServiceRegistry; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionerManager; +import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGeneratorManager; +import org.eclipse.edc.http.spi.EdcHttpClient; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.runtime.metamodel.annotation.Setting; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.tractusx.edc.dataplane.kafka.acl.KafkaAclService; +import org.eclipse.tractusx.edc.dataplane.kafka.acl.KafkaAclServiceImpl; +import org.eclipse.tractusx.edc.dataplane.kafka.auth.KafkaOauthService; +import org.eclipse.tractusx.edc.dataplane.kafka.auth.KafkaOauthServiceImpl; +import org.eclipse.tractusx.edc.dataplane.kafka.flow.KafkaEndpointDataReferenceService; +import org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaDeprovisioner; +import org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisioner; +import org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaResourceDefinitionGenerator; + +import java.util.Properties; + +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.KAFKA_TYPE; + +/** + * Kafka streaming data-plane extension. + *

+ * Adds the {@code KafkaBroker-PULL} transfer type to the EDC data plane: on transfer start a fresh OAuth2 + * token is minted and (optionally) broker ACLs are created, and the consumer is handed an EDR pointing + * directly at the Kafka broker. On suspend/terminate the ACLs and token are revoked. + *

+ * Set {@code edc.dataplane.kafka.acl.enabled=true} to activate Kafka ACL management for immediate + * broker-level revocation independent of token expiry. + */ +@Extension(value = KafkaBrokerExtension.NAME) +public class KafkaBrokerExtension implements ServiceExtension { + + public static final String NAME = "Kafka stream extension"; + + @Setting(description = "Enable Kafka ACL management for immediate broker-level access revocation on transfer termination", defaultValue = "false") + static final String ACL_ENABLED = "edc.dataplane.kafka.acl.enabled"; + + @Setting(description = "Kafka bootstrap servers used by the ACL admin client (required when ACL management is enabled)") + static final String ACL_BOOTSTRAP_SERVERS = "edc.dataplane.kafka.acl.bootstrap.servers"; + + @Setting(description = "Security protocol for the ACL admin client", defaultValue = "PLAINTEXT") + static final String ACL_SECURITY_PROTOCOL = "edc.dataplane.kafka.acl.security.protocol"; + + @Setting(description = "SASL mechanism for the ACL admin client (e.g. OAUTHBEARER, PLAIN)") + static final String ACL_SASL_MECHANISM = "edc.dataplane.kafka.acl.sasl.mechanism"; + + @Setting(description = "SASL JAAS config for the ACL admin client") + static final String ACL_SASL_JAAS_CONFIG = "edc.dataplane.kafka.acl.sasl.jaas.config"; + + @Inject + private Vault vault; + + @Inject + private TypeManager typeManager; + + @Inject + private EdcHttpClient httpClient; + + @Inject + private ResourceDefinitionGeneratorManager resourceDefinitionGeneratorManager; + + @Inject + private ProvisionerManager provisionerManager; + + @Inject + private EndpointDataReferenceServiceRegistry endpointDataReferenceServiceRegistry; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(final ServiceExtensionContext context) { + var monitor = context.getMonitor(); + KafkaOauthService oauthService = new KafkaOauthServiceImpl(httpClient, typeManager.getMapper()); + KafkaAclService aclService = buildAclService(context); + + resourceDefinitionGeneratorManager.registerProviderGenerator(new KafkaResourceDefinitionGenerator()); + provisionerManager.register(new KafkaProvisioner(vault, oauthService, monitor)); + provisionerManager.register(new KafkaDeprovisioner(vault, oauthService, aclService, monitor)); + endpointDataReferenceServiceRegistry.register(KAFKA_TYPE, new KafkaEndpointDataReferenceService(aclService, monitor, typeManager.getMapper())); + } + + private KafkaAclService buildAclService(ServiceExtensionContext context) { + if (!Boolean.parseBoolean(context.getSetting(ACL_ENABLED, "false"))) { + return null; + } + return new KafkaAclServiceImpl(buildAdminProperties(context), context.getMonitor()); + } + + private Properties buildAdminProperties(ServiceExtensionContext context) { + var props = new Properties(); + props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, context.getSetting(ACL_BOOTSTRAP_SERVERS, "")); + props.put("security.protocol", context.getSetting(ACL_SECURITY_PROTOCOL, "PLAINTEXT")); + + var saslMechanism = context.getSetting(ACL_SASL_MECHANISM, null); + if (saslMechanism != null) { + props.put("sasl.mechanism", saslMechanism); + } + + var jaasConfig = context.getSetting(ACL_SASL_JAAS_CONFIG, null); + if (jaasConfig != null) { + props.put("sasl.jaas.config", jaasConfig); + } + + return props; + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/AdminClientFactory.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/AdminClientFactory.java new file mode 100644 index 0000000000..f4f743390f --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/AdminClientFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.acl; + +import org.apache.kafka.clients.admin.Admin; + +import java.util.Properties; + +public interface AdminClientFactory { + + Admin createAdmin(Properties properties); +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/DefaultAdminClientFactory.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/DefaultAdminClientFactory.java new file mode 100644 index 0000000000..93bf4f71c2 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/DefaultAdminClientFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.acl; + +import org.apache.kafka.clients.admin.Admin; + +import java.util.Properties; + +public class DefaultAdminClientFactory implements AdminClientFactory { + + @Override + public Admin createAdmin(Properties properties) { + return Admin.create(properties); + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclService.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclService.java new file mode 100644 index 0000000000..6d36377ab0 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclService.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.acl; + +import org.eclipse.edc.spi.result.Result; + +/** + * Manages Kafka ACLs (Access Control Lists) for transfer processes. + *

+ * When ACL management is enabled, each started transfer creates topic-scoped + * READ/DESCRIBE ACLs for the consumer's OAuth subject, and those ACLs are + * revoked immediately on suspend or terminate — providing broker-level + * enforcement that is independent of OAuth token expiry. + */ +public interface KafkaAclService { + + /** + * Creates READ and DESCRIBE ACLs on the given topic plus a READ ACL on the consumer group. + *

+ * The ACL principal is always {@code User:} (the broker identity carried in the + * consumer's OAUTHBEARER token). The consumer-group resource is named by {@code groupPrefix} + * (PREFIXED), which must be the same group prefix that is handed to the consumer in the EDR so the + * broker grant and the consumer instruction cannot diverge. + * + * @param oauthSubject the OAuth {@code sub} claim extracted from the consumer's JWT (the principal) + * @param topicName the Kafka topic to grant access to + * @param groupPrefix the consumer-group prefix to grant READ on (PREFIXED match) + * @param transferProcessId used to track the ACLs for later revocation + */ + Result createAclsForSubject(String oauthSubject, String topicName, String groupPrefix, String transferProcessId); + + /** + * Revokes all ACLs that were created for the given transfer process. + */ + Result revokeAclsForTransferProcess(String transferProcessId); + + /** + * Revokes ACLs for the given subject, topic and group prefix directly, without requiring a transfer + * process ID. The arguments must match those used at {@link #createAclsForSubject} for the deletion + * filters to match the created bindings. + */ + Result revokeAclsForSubject(String oauthSubject, String topicName, String groupPrefix); +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImpl.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImpl.java new file mode 100644 index 0000000000..c41776a2d2 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImpl.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.acl; + +import org.apache.kafka.clients.admin.Admin; +import org.apache.kafka.clients.admin.CreateAclsResult; +import org.apache.kafka.clients.admin.DeleteAclsResult; +import org.apache.kafka.common.acl.AccessControlEntry; +import org.apache.kafka.common.acl.AccessControlEntryFilter; +import org.apache.kafka.common.acl.AclBinding; +import org.apache.kafka.common.acl.AclBindingFilter; +import org.apache.kafka.common.acl.AclOperation; +import org.apache.kafka.common.acl.AclPermissionType; +import org.apache.kafka.common.resource.PatternType; +import org.apache.kafka.common.resource.ResourcePattern; +import org.apache.kafka.common.resource.ResourcePatternFilter; +import org.apache.kafka.common.resource.ResourceType; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; + +public class KafkaAclServiceImpl implements KafkaAclService { + + private final Properties kafkaProperties; + private final Monitor monitor; + private final AdminClientFactory adminClientFactory; + private final Map transferProcessAcls = new ConcurrentHashMap<>(); + + public KafkaAclServiceImpl(Properties kafkaProperties, Monitor monitor) { + this(kafkaProperties, monitor, new DefaultAdminClientFactory()); + } + + public KafkaAclServiceImpl(Properties kafkaProperties, Monitor monitor, AdminClientFactory adminClientFactory) { + this.kafkaProperties = kafkaProperties; + this.monitor = monitor; + this.adminClientFactory = adminClientFactory; + } + + @Override + public Result createAclsForSubject(String oauthSubject, String topicName, String groupPrefix, String transferProcessId) { + monitor.debug("Creating ACLs for OAuth subject: %s, topic: %s, groupPrefix: %s, transferProcessId: %s" + .formatted(oauthSubject, topicName, groupPrefix, transferProcessId)); + + try (Admin adminClient = adminClientFactory.createAdmin(kafkaProperties)) { + Collection aclBindings = buildAclBindings(oauthSubject, topicName, groupPrefix); + CreateAclsResult result = adminClient.createAcls(aclBindings); + result.all().get(); + + transferProcessAcls.put(transferProcessId, new AclTrackingInfo(oauthSubject, topicName, aclBindings)); + + monitor.debug("Successfully created ACLs for OAuth subject: %s, topic: %s, transferProcessId: %s" + .formatted(oauthSubject, topicName, transferProcessId)); + return Result.success(); + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + String message = "Interrupted while creating ACLs for subject: %s".formatted(oauthSubject); + monitor.severe(message, e); + return failure(message, e); + } catch (ExecutionException e) { + String message = "Failed to create ACLs for OAuth subject: %s".formatted(oauthSubject); + monitor.severe(message, e); + return failure(message, e); + } + } + + @Override + public Result revokeAclsForTransferProcess(String transferProcessId) { + monitor.debug("Revoking ACLs for transferProcessId: %s".formatted(transferProcessId)); + + AclTrackingInfo aclInfo = transferProcessAcls.remove(transferProcessId); + if (aclInfo == null) { + monitor.debug("No ACLs found for transferProcessId: %s".formatted(transferProcessId)); + return Result.success(); + } + + try (Admin adminClient = adminClientFactory.createAdmin(kafkaProperties)) { + Collection aclFilters = toAclBindingFilters(aclInfo.aclBindings()); + DeleteAclsResult result = adminClient.deleteAcls(aclFilters); + result.all().get(); + + monitor.debug("Successfully revoked ACLs for transferProcessId: %s".formatted(transferProcessId)); + return Result.success(); + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + String message = "Interrupted while revoking ACLs for transferProcessId: %s".formatted(transferProcessId); + monitor.severe(message, e); + return failure(message, e); + } catch (ExecutionException e) { + String message = "Failed to revoke ACLs for transferProcessId: %s".formatted(transferProcessId); + monitor.severe(message, e); + return failure(message, e); + } + } + + @Override + public Result revokeAclsForSubject(String oauthSubject, String topicName, String groupPrefix) { + monitor.debug("Revoking ACLs for OAuth subject: %s, topic: %s, groupPrefix: %s".formatted(oauthSubject, topicName, groupPrefix)); + + try (Admin adminClient = adminClientFactory.createAdmin(kafkaProperties)) { + Collection aclFilters = toAclBindingFilters(buildAclBindings(oauthSubject, topicName, groupPrefix)); + DeleteAclsResult result = adminClient.deleteAcls(aclFilters); + result.all().get(); + + monitor.debug("Successfully revoked ACLs for OAuth subject: %s, topic: %s".formatted(oauthSubject, topicName)); + return Result.success(); + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + String message = "Interrupted while revoking ACLs for subject: %s".formatted(oauthSubject); + monitor.severe(message, e); + return failure(message, e); + } catch (ExecutionException e) { + String message = "Failed to revoke ACLs for OAuth subject: %s".formatted(oauthSubject); + monitor.severe(message, e); + return failure(message, e); + } + } + + private @NotNull Result failure(String message, Exception e) { + return Result.failure("%s: %s".formatted(message, e.getMessage())); + } + + private Collection buildAclBindings(String oauthSubject, String topicName, String groupPrefix) { + String principal = "User:" + oauthSubject; + ResourcePattern topicResource = new ResourcePattern(ResourceType.TOPIC, topicName, PatternType.LITERAL); + ResourcePattern groupResource = new ResourcePattern(ResourceType.GROUP, groupPrefix, PatternType.PREFIXED); + + return List.of( + new AclBinding(topicResource, new AccessControlEntry(principal, "*", AclOperation.READ, AclPermissionType.ALLOW)), + new AclBinding(topicResource, new AccessControlEntry(principal, "*", AclOperation.DESCRIBE, AclPermissionType.ALLOW)), + new AclBinding(groupResource, new AccessControlEntry(principal, "*", AclOperation.READ, AclPermissionType.ALLOW)) + ); + } + + private Collection toAclBindingFilters(Collection aclBindings) { + Collection filters = new ArrayList<>(); + for (AclBinding b : aclBindings) { + filters.add(new AclBindingFilter( + new ResourcePatternFilter(b.pattern().resourceType(), b.pattern().name(), b.pattern().patternType()), + new AccessControlEntryFilter(b.entry().principal(), b.entry().host(), b.entry().operation(), b.entry().permissionType()) + )); + } + return filters; + } + + private record AclTrackingInfo(String oauthSubject, String topicName, Collection aclBindings) { + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthService.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthService.java new file mode 100644 index 0000000000..c72d00fef1 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthService.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.auth; + +/** + * Interface for services that handle Oauth2 access token operations for Kafka authentication. + * Defines methods to fetch and revoke Oauth2 access tokens using the Client Credentials flow. + */ +public interface KafkaOauthService { + + /** + * Always performs a client_credentials flow and returns a fresh token. + * + * @param creds The Oauth credentials to use for token acquisition + * @return The acquired access token as a string + */ + String getAccessToken(OauthCredentials creds); + + /** + * Revokes the given token. + * + * @param creds The Oauth credentials used for token revocation + * @param token The token to revoke + */ + void revokeToken(OauthCredentials creds, String token); +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceImpl.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceImpl.java new file mode 100644 index 0000000000..de8d6afee7 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceImpl.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.auth; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.FormBody; +import okhttp3.Request; +import okhttp3.Response; +import org.eclipse.edc.http.spi.EdcHttpClient; + +import java.io.IOException; + +/** + * Stateless service to fetch and revoke Oauth2 access tokens using the Client Credentials flow. + * No token is cached—each getAccessToken() call always retrieves a new token. + */ +public class KafkaOauthServiceImpl implements KafkaOauthService { + static final String ACCESS_TOKEN_KEY = "access_token"; + static final String GRANT_TYPE_KEY = "grant_type"; + static final String CLIENT_CREDENTIALS_GRANT_TYPE = "client_credentials"; + static final String CLIENT_ID_KEY = "client_id"; + static final String CLIENT_SECRET_KEY = "client_secret"; + static final String CONTENT_TYPE_HEADER = "Content-Type"; + static final String APPLICATION_X_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; + static final String TOKEN_KEY = "token"; + + private final EdcHttpClient httpClient; + private final ObjectMapper objectMapper; + + public KafkaOauthServiceImpl(final EdcHttpClient httpClient, final ObjectMapper objectMapper) { + this.httpClient = httpClient; + this.objectMapper = objectMapper; + } + + /** + * Always performs a client_credentials flow and returns a fresh token. + */ + @Override + public String getAccessToken(final OauthCredentials creds) { + return fetchNewToken(creds); + } + + private String fetchNewToken(final OauthCredentials creds) { + try { + FormBody formBody = new FormBody.Builder() + .add(GRANT_TYPE_KEY, CLIENT_CREDENTIALS_GRANT_TYPE) + .add(CLIENT_ID_KEY, creds.clientId()) + .add(CLIENT_SECRET_KEY, creds.clientSecret()) + .build(); + + Request request = new Request.Builder() + .url(creds.tokenUrl()) + .header(CONTENT_TYPE_HEADER, APPLICATION_X_WWW_FORM_URLENCODED) + .post(formBody) + .build(); + + try (Response response = httpClient.execute(request)) { + if (!response.isSuccessful()) { + throw new RuntimeException("Oauth2 token endpoint returned HTTP " + response.code()); + } + + String responseBody = response.body() != null ? response.body().string() : ""; + JsonNode json = objectMapper.readTree(responseBody); + JsonNode accessToken = json.get(ACCESS_TOKEN_KEY); + if (accessToken == null || accessToken.isNull()) { + throw new RuntimeException("Oauth2 token endpoint response did not contain an '" + ACCESS_TOKEN_KEY + "' field"); + } + return accessToken.asText(); + } + } catch (IOException e) { + throw new RuntimeException("Failed to fetch Oauth2 token", e); + } + } + + /** + * Revokes the given token. + */ + @Override + public void revokeToken(final OauthCredentials creds, final String token) { + if (creds.revocationUrl().isEmpty()) { + return; + } + try { + FormBody formBody = new FormBody.Builder() + .add(TOKEN_KEY, token) + .add(CLIENT_ID_KEY, creds.clientId()) + .add(CLIENT_SECRET_KEY, creds.clientSecret()) + .build(); + + Request request = new Request.Builder() + .url(creds.revocationUrl().get()) + .header(CONTENT_TYPE_HEADER, APPLICATION_X_WWW_FORM_URLENCODED) + .post(formBody) + .build(); + + try (Response response = httpClient.execute(request)) { + if (!response.isSuccessful()) { + throw new RuntimeException("Revoke endpoint returned HTTP " + response.code()); + } + } + } catch (IOException e) { + throw new RuntimeException("Failed to revoke Oauth2 token", e); + } + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/OauthCredentials.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/OauthCredentials.java new file mode 100644 index 0000000000..0041598734 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/OauthCredentials.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.auth; + +import java.util.Optional; + +/** + * Simple immutable holder for the four Oauth2 parameters. + * + * @param tokenUrl The endpoint URL to fetch Oauth2 tokens using client credentials flow. + * @param revocationUrl The optional endpoint URL used to revoke tokens. This may be empty if token revocation is not supported. + * @param clientId The identifier of the client application attempting to authenticate. + * @param clientSecret The secret associated with the client identifier for authentication. + */ +public record OauthCredentials(String tokenUrl, Optional revocationUrl, String clientId, String clientSecret) { +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/flow/KafkaEndpointDataReferenceService.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/flow/KafkaEndpointDataReferenceService.java new file mode 100644 index 0000000000..5aa92b6eba --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/flow/KafkaEndpointDataReferenceService.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.flow; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.edc.connector.dataplane.spi.DataFlow; +import org.eclipse.edc.connector.dataplane.spi.edr.EndpointDataReferenceService; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.result.ServiceResult; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.dataplane.kafka.acl.KafkaAclService; +import org.jetbrains.annotations.Nullable; + +import java.util.Base64; + +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.GROUP_PREFIX; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOKEN; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOPIC; + +/** + * Produces the consumer-facing EDR for a {@code KafkaBroker} PULL flow, and owns the per-activation broker + * ACL lifecycle. + *

+ * {@link #createEndpointDataReference} runs on transfer start and resume, so it (re)creates the + * broker ACLs each time — restoring access on resume after a suspend revoked them. The EDR itself is the + * provisioned {@link DataAddress} ({@link DataFlow#getActualSource()}: broker coordinates, topic, security + * settings, consumer-group prefix and the minted token) built by + * {@link org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisioner}. + *

+ * {@link #revokeEndpointDataReference} runs on suspend and terminate, revoking the ACLs so suspend + * cuts access immediately; the OAuth token is revoked by the deprovisioner on terminate (where the client + * credentials are available). When ACL management is disabled both are no-ops and access ends at the + * token's TTL. + */ +public class KafkaEndpointDataReferenceService implements EndpointDataReferenceService { + + @Nullable + private final KafkaAclService aclService; + private final Monitor monitor; + private final ObjectMapper objectMapper; + + public KafkaEndpointDataReferenceService(@Nullable KafkaAclService aclService, Monitor monitor, ObjectMapper objectMapper) { + this.aclService = aclService; + this.monitor = monitor; + this.objectMapper = objectMapper; + } + + @Override + public Result createEndpointDataReference(DataFlow dataFlow) { + var edr = dataFlow.getActualSource(); + if (edr == null) { + return Result.failure("No provisioned Kafka EDR available for data flow " + dataFlow.getId()); + } + + if (aclService != null) { + try { + var subject = extractOauthSubject(edr.getStringProperty(TOKEN)); + var aclResult = aclService.createAclsForSubject(subject, edr.getStringProperty(TOPIC), + edr.getStringProperty(GROUP_PREFIX), dataFlow.getId()); + if (aclResult.failed()) { + return Result.failure("Failed to create Kafka ACLs: " + aclResult.getFailureDetail()); + } + } catch (EdcException e) { + return Result.failure(e.getMessage()); + } + } + + return Result.success(edr); + } + + @Override + public ServiceResult revokeEndpointDataReference(String transferProcessId, String reason) { + if (aclService == null) { + return ServiceResult.success(); + } + monitor.debug("Revoking Kafka ACLs for data flow %s".formatted(transferProcessId)); + return ServiceResult.from(aclService.revokeAclsForTransferProcess(transferProcessId)); + } + + private String extractOauthSubject(String token) { + try { + var parts = token.split("\\."); + if (parts.length != 3) { + throw new EdcException("Invalid JWT token format"); + } + var payload = new String(Base64.getUrlDecoder().decode(parts[1])); + var subNode = objectMapper.readTree(payload).get("sub"); + if (subNode == null || subNode.isNull()) { + throw new EdcException("No 'sub' claim found in JWT token"); + } + return subNode.asText(); + } catch (EdcException e) { + throw e; + } catch (Exception e) { + throw new EdcException("Failed to extract OAuth subject from token: " + e.getMessage(), e); + } + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaDeprovisioner.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaDeprovisioner.java new file mode 100644 index 0000000000..7969857ac9 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaDeprovisioner.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.provision; + +import org.eclipse.edc.connector.dataplane.spi.provision.DeprovisionedResource; +import org.eclipse.edc.connector.dataplane.spi.provision.Deprovisioner; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.response.ResponseStatus; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.dataplane.kafka.acl.KafkaAclService; +import org.eclipse.tractusx.edc.dataplane.kafka.auth.KafkaOauthService; +import org.eclipse.tractusx.edc.dataplane.kafka.auth.OauthCredentials; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_ID; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_SECRET_KEY; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_REVOKE_URL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_TOKEN_URL; +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.KAFKA_RESOURCE_TYPE; + +/** + * Data-plane {@link Deprovisioner} for {@code KafkaBroker} flows: revokes the broker ACLs and the OAuth2 + * token when the flow is deprovisioned on terminate, closing the access window independently of token + * expiry. Cleanup is idempotent — a missing token or untracked ACLs is treated as success. + */ +public class KafkaDeprovisioner implements Deprovisioner { + + private final Vault vault; + private final KafkaOauthService oauthService; + @Nullable + private final KafkaAclService aclService; + private final Monitor monitor; + + public KafkaDeprovisioner(Vault vault, KafkaOauthService oauthService, @Nullable KafkaAclService aclService, Monitor monitor) { + this.vault = vault; + this.oauthService = oauthService; + this.aclService = aclService; + this.monitor = monitor; + } + + @Override + public String supportedType() { + return KAFKA_RESOURCE_TYPE; + } + + @Override + public CompletableFuture> deprovision(ProvisionResource resource) { + try { + var flowId = resource.getFlowId(); + + if (aclService != null) { + var aclResult = aclService.revokeAclsForTransferProcess(flowId); + if (aclResult.failed()) { + return completed(StatusResult.failure(ResponseStatus.FATAL_ERROR, "Failed to revoke Kafka ACLs: " + aclResult.getFailureDetail())); + } + } + + var token = vault.resolveSecret(flowId); + if (token != null) { + oauthService.revokeToken(extractOauthCredentials(resource.getDataAddress()), token); + vault.deleteSecret(flowId); + } + + monitor.debug("Deprovisioned Kafka flow %s".formatted(flowId)); + return completed(StatusResult.success(DeprovisionedResource.Builder.newInstance() + .id(resource.getId()) + .flowId(flowId) + .build())); + } catch (Exception e) { + return completed(StatusResult.failure(ResponseStatus.FATAL_ERROR, "Failed to deprovision Kafka data flow: " + e.getMessage())); + } + } + + private OauthCredentials extractOauthCredentials(DataAddress source) { + var clientSecret = Optional.ofNullable(vault.resolveSecret(source.getStringProperty(OAUTH_CLIENT_SECRET_KEY))) + .orElseThrow(() -> new EdcException("Kafka client secret was not found in the vault")); + return new OauthCredentials( + source.getStringProperty(OAUTH_TOKEN_URL), + Optional.ofNullable(source.getStringProperty(OAUTH_REVOKE_URL)), + source.getStringProperty(OAUTH_CLIENT_ID), + clientSecret); + } + + private static CompletableFuture> completed(StatusResult result) { + return CompletableFuture.completedFuture(result); + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisionConstants.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisionConstants.java new file mode 100644 index 0000000000..78fb228da4 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisionConstants.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.provision; + +/** + * Constants shared by the Kafka data-plane provisioning components. + */ +public interface KafkaProvisionConstants { + + /** + * Provision-resource type for Kafka flows. Matches the {@code KafkaBroker} source DataAddress type so + * the data plane advertises {@code KafkaBroker} as an allowed source type and {@code KafkaBroker-PULL} + * as an allowed transfer type. + */ + String KAFKA_RESOURCE_TYPE = "KafkaBroker"; + + /** + * ProvisionResource property carrying the consumer participant id, used as the consumer-group prefix + * fallback when the {@code kafka.group.prefix} DataAddress property is absent. + */ + String CONSUMER_GROUP_PREFIX_PROPERTY = "tx:kafka:consumerGroupPrefix"; + + /** + * Default consumer poll duration (ISO-8601) when {@code kafka.poll.duration} is not set. + */ + String DEFAULT_POLL_DURATION = "PT1S"; +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisioner.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisioner.java new file mode 100644 index 0000000000..8c729942ef --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisioner.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.provision; + +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionedResource; +import org.eclipse.edc.connector.dataplane.spi.provision.Provisioner; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.response.ResponseStatus; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.dataplane.kafka.auth.KafkaOauthService; +import org.eclipse.tractusx.edc.dataplane.kafka.auth.OauthCredentials; + +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.BOOTSTRAP_SERVERS; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.GROUP_PREFIX; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.KAFKA_TYPE; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.MECHANISM; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_ID; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_SECRET_KEY; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_REVOKE_URL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_TOKEN_URL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.POLL_DURATION; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.PROTOCOL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOKEN; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOPIC; +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.CONSUMER_GROUP_PREFIX_PROPERTY; +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.DEFAULT_POLL_DURATION; +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.KAFKA_RESOURCE_TYPE; + +/** + * Data-plane {@link Provisioner} for the {@code KafkaBroker} source type. On provision it mints a fresh + * OAuth2 access token (Client Credentials flow) and builds the provisioned {@link DataAddress} — the EDR + * handed to the consumer: the broker coordinates, topic, security settings, consumer-group prefix and the + * minted token. The token is also stored in the vault keyed by the data-flow id so + * {@link KafkaDeprovisioner} can revoke it on terminate. Broker ACLs are managed per activation by + * {@code KafkaEndpointDataReferenceService} (so suspend/resume toggle access), not here. + */ +public class KafkaProvisioner implements Provisioner { + + private final Vault vault; + private final KafkaOauthService oauthService; + private final Monitor monitor; + + public KafkaProvisioner(Vault vault, KafkaOauthService oauthService, Monitor monitor) { + this.vault = vault; + this.oauthService = oauthService; + this.monitor = monitor; + } + + @Override + public String supportedType() { + return KAFKA_RESOURCE_TYPE; + } + + @Override + public CompletableFuture> provision(ProvisionResource resource) { + try { + var flowId = resource.getFlowId(); + var source = resource.getDataAddress(); + + var groupPrefix = Optional.ofNullable(source.getStringProperty(GROUP_PREFIX)) + .orElse((String) resource.getProperty(CONSUMER_GROUP_PREFIX_PROPERTY)); + if (groupPrefix == null || groupPrefix.isBlank()) { + return completed(StatusResult.failure(ResponseStatus.FATAL_ERROR, + "Cannot determine Kafka consumer-group prefix: neither the '%s' property nor a consumer participant id is present" + .formatted(GROUP_PREFIX))); + } + + var token = oauthService.getAccessToken(extractOauthCredentials(source)); + vault.storeSecret(flowId, token); + + var pollDuration = Optional.ofNullable(source.getStringProperty(POLL_DURATION)).orElse(DEFAULT_POLL_DURATION); + + var edr = DataAddress.Builder.newInstance() + .type(KAFKA_TYPE) + .property(BOOTSTRAP_SERVERS, source.getStringProperty(BOOTSTRAP_SERVERS)) + .property(TOPIC, source.getStringProperty(TOPIC)) + .property(PROTOCOL, source.getStringProperty(PROTOCOL)) + .property(MECHANISM, source.getStringProperty(MECHANISM)) + .property(TOKEN, token) + .property(POLL_DURATION, pollDuration) + .property(GROUP_PREFIX, groupPrefix) + .build(); + + var provisioned = ProvisionedResource.Builder.newInstance() + .id(resource.getId()) + .flowId(flowId) + .dataAddress(edr) + .build(); + + monitor.debug("Provisioned Kafka EDR for flow %s, topic %s".formatted(flowId, source.getStringProperty(TOPIC))); + return completed(StatusResult.success(provisioned)); + } catch (Exception e) { + return completed(StatusResult.failure(ResponseStatus.FATAL_ERROR, "Failed to provision Kafka data flow: " + e.getMessage())); + } + } + + private OauthCredentials extractOauthCredentials(DataAddress source) { + var clientSecret = Optional.ofNullable(vault.resolveSecret(source.getStringProperty(OAUTH_CLIENT_SECRET_KEY))) + .orElseThrow(() -> new EdcException("Kafka client secret was not found in the vault")); + return new OauthCredentials( + source.getStringProperty(OAUTH_TOKEN_URL), + Optional.ofNullable(source.getStringProperty(OAUTH_REVOKE_URL)), + source.getStringProperty(OAUTH_CLIENT_ID), + clientSecret); + } + + private static CompletableFuture> completed(StatusResult result) { + return CompletableFuture.completedFuture(result); + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaResourceDefinitionGenerator.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaResourceDefinitionGenerator.java new file mode 100644 index 0000000000..5f7f178ad6 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaResourceDefinitionGenerator.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.provision; + +import org.eclipse.edc.connector.dataplane.spi.DataFlow; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGenerator; + +import java.util.UUID; + +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.CONSUMER_GROUP_PREFIX_PROPERTY; +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.KAFKA_RESOURCE_TYPE; + +/** + * Provider-side {@link ResourceDefinitionGenerator} for the {@code KafkaBroker} source type. Registering it + * makes the data plane advertise {@code KafkaBroker} as an allowed source type (and, via the EDR service, + * {@code KafkaBroker-PULL} as a transfer type) and triggers {@link KafkaProvisioner} on transfer start. + */ +public class KafkaResourceDefinitionGenerator implements ResourceDefinitionGenerator { + + @Override + public String supportedType() { + return KAFKA_RESOURCE_TYPE; + } + + @Override + public ProvisionResource generate(DataFlow dataFlow) { + return ProvisionResource.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .flowId(dataFlow.getId()) + .type(KAFKA_RESOURCE_TYPE) + .dataAddress(dataFlow.getSource()) + .property(CONSUMER_GROUP_PREFIX_PROPERTY, dataFlow.getParticipantId()) + .build(); + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..6c8d0be418 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.tractusx.edc.dataplane.kafka.KafkaBrokerExtension diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/KafkaBrokerExtensionTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/KafkaBrokerExtensionTest.java new file mode 100644 index 0000000000..8b2e3315f9 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/KafkaBrokerExtensionTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka; + +import org.eclipse.edc.connector.dataplane.spi.edr.EndpointDataReferenceServiceRegistry; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionerManager; +import org.eclipse.edc.connector.dataplane.spi.provision.ResourceDefinitionGeneratorManager; +import org.eclipse.edc.http.spi.EdcHttpClient; +import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.tractusx.edc.dataplane.kafka.flow.KafkaEndpointDataReferenceService; +import org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaDeprovisioner; +import org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisioner; +import org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaResourceDefinitionGenerator; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.KAFKA_TYPE; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +@ExtendWith(DependencyInjectionExtension.class) +class KafkaBrokerExtensionTest { + + private final ResourceDefinitionGeneratorManager generatorManager = mock(); + private final ProvisionerManager provisionerManager = mock(); + private final EndpointDataReferenceServiceRegistry edrRegistry = mock(); + private final Vault vault = mock(); + private final EdcHttpClient httpClient = mock(); + + @BeforeEach + void setUp(final ServiceExtensionContext context) { + context.registerService(ResourceDefinitionGeneratorManager.class, generatorManager); + context.registerService(ProvisionerManager.class, provisionerManager); + context.registerService(EndpointDataReferenceServiceRegistry.class, edrRegistry); + context.registerService(Vault.class, vault); + context.registerService(EdcHttpClient.class, httpClient); + } + + @Test + void initialize_RegistersKafkaDataPlaneComponents(final KafkaBrokerExtension extension, final ServiceExtensionContext context) { + extension.initialize(context); + + verify(generatorManager).registerProviderGenerator(any(KafkaResourceDefinitionGenerator.class)); + verify(provisionerManager).register(any(KafkaProvisioner.class)); + verify(provisionerManager).register(any(KafkaDeprovisioner.class)); + verify(edrRegistry).register(eq(KAFKA_TYPE), any(KafkaEndpointDataReferenceService.class)); + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTest.java new file mode 100644 index 0000000000..42c97fbf3b --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTest.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.acl; + +import org.apache.kafka.clients.admin.Admin; +import org.apache.kafka.clients.admin.CreateAclsResult; +import org.apache.kafka.clients.admin.DeleteAclsResult; +import org.apache.kafka.common.KafkaFuture; +import org.apache.kafka.common.acl.AclBinding; +import org.apache.kafka.common.acl.AclOperation; +import org.apache.kafka.common.resource.PatternType; +import org.apache.kafka.common.resource.ResourceType; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Collection; +import java.util.Collections; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +class KafkaAclServiceImplTest { + + private static final String OAUTH_SUBJECT = "test-oauth-subject"; + private static final String TOPIC = "test-topic"; + // Distinct from the OAuth subject so the GROUP ACL is verified to be named by the group prefix + // (PREFIXED) while the principal stays the subject. + private static final String GROUP_PREFIX = "test-group-prefix"; + private static final String TRANSFER_PROCESS_ID = "test-transfer-process-id"; + + private final Monitor monitor = mock(); + private final Admin mockAdmin = mock(); + private final AdminClientFactory adminClientFactory = mock(); + private KafkaAclServiceImpl aclService; + + @BeforeEach + void setUp() { + var kafkaProperties = new Properties(); + kafkaProperties.put("bootstrap.servers", "localhost:9092"); + when(adminClientFactory.createAdmin(any(Properties.class))).thenReturn(mockAdmin); + aclService = new KafkaAclServiceImpl(kafkaProperties, monitor, adminClientFactory); + } + + @Test + void createAclsForSubject_shouldSucceed() throws ExecutionException, InterruptedException { + setupSuccessfulCreate(); + + Result result = aclService.createAclsForSubject(OAUTH_SUBJECT, TOPIC, GROUP_PREFIX, TRANSFER_PROCESS_ID); + + assertThat(result.succeeded()).isTrue(); + // 3 bindings: topic READ + DESCRIBE (LITERAL) and consumer-group READ (PREFIXED by the group + // prefix, not the subject), all for principal User:. + verify(mockAdmin).createAcls(argThat(bindings -> + bindings.size() == 3 && + hasBinding(bindings, ResourceType.TOPIC, TOPIC, PatternType.LITERAL, AclOperation.READ) && + hasBinding(bindings, ResourceType.TOPIC, TOPIC, PatternType.LITERAL, AclOperation.DESCRIBE) && + hasBinding(bindings, ResourceType.GROUP, GROUP_PREFIX, PatternType.PREFIXED, AclOperation.READ))); + } + + private static boolean hasBinding(Collection bindings, ResourceType resourceType, String name, + PatternType patternType, AclOperation operation) { + return bindings.stream().anyMatch(b -> + b.pattern().resourceType() == resourceType && + b.pattern().name().equals(name) && + b.pattern().patternType() == patternType && + b.entry().principal().equals("User:" + OAUTH_SUBJECT) && + b.entry().operation() == operation); + } + + @Test + void createAclsForSubject_shouldFail_whenExecutionExceptionOccurs() throws ExecutionException, InterruptedException { + CreateAclsResult createResult = mock(CreateAclsResult.class); + KafkaFuture future = mock(KafkaFuture.class); + when(mockAdmin.createAcls(anyCollection())).thenReturn(createResult); + when(createResult.all()).thenReturn(future); + when(future.get()).thenThrow(new ExecutionException("error", new RuntimeException())); + + Result result = aclService.createAclsForSubject(OAUTH_SUBJECT, TOPIC, GROUP_PREFIX, TRANSFER_PROCESS_ID); + + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureDetail()).contains("Failed to create ACLs for OAuth subject: " + OAUTH_SUBJECT); + } + + @Test + void revokeAclsForTransferProcess_shouldSucceed_afterCreate() throws Exception { + setupSuccessfulCreate(); + aclService.createAclsForSubject(OAUTH_SUBJECT, TOPIC, GROUP_PREFIX, TRANSFER_PROCESS_ID); + + setupSuccessfulDelete(); + + Result result = aclService.revokeAclsForTransferProcess(TRANSFER_PROCESS_ID); + + assertThat(result.succeeded()).isTrue(); + verify(mockAdmin).deleteAcls(anyCollection()); + } + + @Test + void revokeAclsForTransferProcess_shouldSucceed_whenNoAclsTracked() { + Result result = aclService.revokeAclsForTransferProcess("unknown-id"); + + assertThat(result.succeeded()).isTrue(); + verifyNoInteractions(mockAdmin); + verify(adminClientFactory, never()).createAdmin(any()); + } + + @Test + void revokeAclsForTransferProcess_shouldFail_whenExecutionExceptionOccurs() throws Exception { + setupSuccessfulCreate(); + aclService.createAclsForSubject(OAUTH_SUBJECT, TOPIC, GROUP_PREFIX, TRANSFER_PROCESS_ID); + + DeleteAclsResult deleteResult = mock(DeleteAclsResult.class); + KafkaFuture> future = mock(KafkaFuture.class); + when(mockAdmin.deleteAcls(anyCollection())).thenReturn(deleteResult); + when(deleteResult.all()).thenReturn(future); + when(future.get()).thenThrow(new ExecutionException("error", new RuntimeException())); + + Result result = aclService.revokeAclsForTransferProcess(TRANSFER_PROCESS_ID); + + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureDetail()).contains("Failed to revoke ACLs for transferProcessId: " + TRANSFER_PROCESS_ID); + } + + @Test + void revokeAclsForSubject_shouldSucceed() throws Exception { + setupSuccessfulDelete(); + + Result result = aclService.revokeAclsForSubject(OAUTH_SUBJECT, TOPIC, GROUP_PREFIX); + + assertThat(result.succeeded()).isTrue(); + verify(mockAdmin).deleteAcls(anyCollection()); + } + + @Test + void createAndRevoke_shouldTrackAndCleanUpAcls() throws Exception { + setupSuccessfulCreate(); + setupSuccessfulDelete(); + + aclService.createAclsForSubject(OAUTH_SUBJECT, TOPIC, GROUP_PREFIX, TRANSFER_PROCESS_ID); + aclService.revokeAclsForTransferProcess(TRANSFER_PROCESS_ID); + + // After revoke, re-revoking for the same ID should be a no-op (no admin call) + verify(adminClientFactory, times(2)).createAdmin(any()); + Result secondRevoke = aclService.revokeAclsForTransferProcess(TRANSFER_PROCESS_ID); + assertThat(secondRevoke.succeeded()).isTrue(); + verify(adminClientFactory, times(2)).createAdmin(any()); // still 2, no extra call + } + + private void setupSuccessfulCreate() throws ExecutionException, InterruptedException { + CreateAclsResult createResult = mock(CreateAclsResult.class); + KafkaFuture future = mock(KafkaFuture.class); + when(mockAdmin.createAcls(anyCollection())).thenReturn(createResult); + when(createResult.all()).thenReturn(future); + when(future.get()).thenReturn(null); + } + + private void setupSuccessfulDelete() throws ExecutionException, InterruptedException { + DeleteAclsResult deleteResult = mock(DeleteAclsResult.class); + KafkaFuture> future = mock(KafkaFuture.class); + when(mockAdmin.deleteAcls(anyCollection())).thenReturn(deleteResult); + when(deleteResult.all()).thenReturn(future); + when(future.get()).thenReturn(Collections.emptyList()); + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTestcontainersTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTestcontainersTest.java new file mode 100644 index 0000000000..c3b78dddb9 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTestcontainersTest.java @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.acl; + +import org.apache.kafka.clients.CommonClientConfigs; +import org.apache.kafka.clients.admin.Admin; +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.admin.CreateTopicsResult; +import org.apache.kafka.clients.admin.DescribeAclsResult; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.TopicPartition; +import org.apache.kafka.common.acl.AclBinding; +import org.apache.kafka.common.acl.AclBindingFilter; +import org.apache.kafka.common.acl.AclOperation; +import org.apache.kafka.common.config.SaslConfigs; +import org.apache.kafka.common.errors.GroupAuthorizationException; +import org.apache.kafka.common.errors.TopicAuthorizationException; +import org.apache.kafka.common.resource.ResourceType; +import org.apache.kafka.common.security.auth.SecurityProtocol; +import org.apache.kafka.common.security.plain.internals.PlainSaslServer; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.eclipse.edc.spi.monitor.ConsoleMonitor; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.kafka.KafkaContainer; +import org.testcontainers.utility.DockerImageName; + +import java.time.Duration; +import java.util.Collection; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.ExecutionException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@Testcontainers +class KafkaAclServiceImplTestcontainersTest { + + public static final String GROUP_ID = "groupId"; + private static final String TEST_TOPIC = "test-topic"; + private static final TopicPartition TEST_PARTITION = new TopicPartition(TEST_TOPIC, 0); + private static final Duration POLL_TIMEOUT = Duration.ofSeconds(2); + private static final String TEST_OAUTH_SUBJECT = "test-user"; + // Deliberately distinct from the OAuth subject: the GROUP ACL is named by the group prefix (PREFIXED), + // while the ACL principal remains the subject. + private static final String TEST_GROUP_PREFIX = "test-group-prefix"; + private static final String TEST_TRANSFER_PROCESS_ID = "transfer-process-123"; + private static final String UNAUTHORIZED_USER = "unauthorized-user"; + + private static final String ADMIN_LOGIN_MODULE = "org.apache.kafka.common.security.plain.PlainLoginModule required " + + "username=\"admin\" password=\"password\";"; + + @Container + static KafkaContainer kafkaContainer = new KafkaContainer(DockerImageName.parse("apache/kafka:4.0.0")) + .withEnv("KAFKA_AUTHORIZER_CLASS_NAME", "org.apache.kafka.metadata.authorizer.StandardAuthorizer") + .withEnv("KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND", "false") + .withEnv("KAFKA_SUPER_USERS", "User:admin;User:ANONYMOUS") + .withEnv("KAFKA_LISTENER_SECURITY_PROTOCOL_MAP", "PLAINTEXT:SASL_PLAINTEXT,BROKER:PLAINTEXT,CONTROLLER:PLAINTEXT") + .withEnv("KAFKA_SASL_ENABLED_MECHANISMS", "PLAIN") + .withEnv("KAFKA_INTER_BROKER_LISTENER_NAME", "PLAINTEXT") + .withEnv("KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL", "PLAIN") + .withEnv("KAFKA_SASL_JAAS_CONFIG", ADMIN_LOGIN_MODULE) + .withEnv("KAFKA_LISTENER_NAME_PLAINTEXT_PLAIN_SASL_JAAS_CONFIG", + "org.apache.kafka.common.security.plain.PlainLoginModule required " + + "user_admin=\"password\" user_test-user=\"password\" user_unauthorized-user=\"password\";"); + + private KafkaAclServiceImpl aclService; + private Admin adminClient; + + @BeforeEach + void setUp() throws ExecutionException, InterruptedException { + Properties adminProperties = new Properties(); + adminProperties.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaContainer.getBootstrapServers()); + adminProperties.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, SecurityProtocol.SASL_PLAINTEXT.name()); + adminProperties.put(SaslConfigs.SASL_MECHANISM, PlainSaslServer.PLAIN_MECHANISM); + adminProperties.put(SaslConfigs.SASL_JAAS_CONFIG, ADMIN_LOGIN_MODULE); + + adminClient = Admin.create(adminProperties); + + Monitor monitor = new ConsoleMonitor(); + aclService = new KafkaAclServiceImpl(adminProperties, monitor); + + NewTopic newTopic = new NewTopic(TEST_TOPIC, 1, (short) 1); + CreateTopicsResult createResult = adminClient.createTopics(List.of(newTopic)); + createResult.all().get(); + } + + @AfterEach + void tearDown() { + if (adminClient != null) { + adminClient.deleteTopics(List.of(TEST_TOPIC)); + adminClient.deleteAcls(List.of(AclBindingFilter.ANY)); + adminClient.close(); + } + } + + @Test + void createAclsForSubject_shouldCreateAclsSuccessfully() throws Exception { + Result result = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); + + assertThat(result.succeeded()).isTrue(); + + DescribeAclsResult describeResult = adminClient.describeAcls(AclBindingFilter.ANY); + Collection aclBindings = describeResult.values().get(); + + assertThat(aclBindings).hasSize(3); + + boolean hasTopicReadAcl = aclBindings.stream() + .anyMatch(acl -> acl.pattern().name().equals(TEST_TOPIC) && + acl.entry().principal().equals("User:" + TEST_OAUTH_SUBJECT) && + acl.entry().operation().equals(AclOperation.READ)); + + boolean hasTopicDescribeAcl = aclBindings.stream() + .anyMatch(acl -> acl.pattern().name().equals(TEST_TOPIC) && + acl.entry().principal().equals("User:" + TEST_OAUTH_SUBJECT) && + acl.entry().operation().equals(AclOperation.DESCRIBE)); + + boolean hasGroupReadAcl = aclBindings.stream() + .anyMatch(acl -> acl.pattern().name().equals(TEST_GROUP_PREFIX) && + acl.entry().principal().equals("User:" + TEST_OAUTH_SUBJECT) && + acl.entry().operation().equals(AclOperation.READ) && + acl.pattern().resourceType().equals(ResourceType.GROUP)); + + assertThat(hasTopicReadAcl).isTrue(); + assertThat(hasTopicDescribeAcl).isTrue(); + assertThat(hasGroupReadAcl).isTrue(); + } + + @Test + void topicAccess_withValidAcls_shouldBeAllowed() throws Exception { + Result aclResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); + assertThat(aclResult.succeeded()).isTrue(); + + produceTestMessage(TEST_TOPIC, "test-key", "test-value"); + + Properties consumerProps = createConsumerProperties(TEST_OAUTH_SUBJECT); + + try (KafkaConsumer consumer = new KafkaConsumer<>(consumerProps)) { + consumer.assign(List.of(TEST_PARTITION)); + consumer.seekToBeginning(List.of(TEST_PARTITION)); + + ConsumerRecords records = consumer.poll(POLL_TIMEOUT); + + assertThat(records.count()).isEqualTo(1); + assertThat(records.iterator().next().value()).isEqualTo("test-value"); + } + } + + @Test + void topicAccess_withWrongUser_shouldBeBlocked() { + Result aclResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); + assertThat(aclResult.succeeded()).isTrue(); + + Properties consumerProps = createConsumerProperties(UNAUTHORIZED_USER); + + try (KafkaConsumer consumer = new KafkaConsumer<>(consumerProps)) { + consumer.assign(List.of(TEST_PARTITION)); + assertThatThrownBy(() -> consumer.poll(POLL_TIMEOUT)).isInstanceOf(TopicAuthorizationException.class); + } + } + + @Test + void revokeAclsForTransferProcess_shouldRemoveAclsSuccessfully() throws Exception { + Result createResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); + assertThat(createResult.succeeded()).isTrue(); + + DescribeAclsResult describeResult = adminClient.describeAcls(AclBindingFilter.ANY); + Collection aclsBeforeRevoke = describeResult.values().get(); + + Result revokeResult = aclService.revokeAclsForTransferProcess(TEST_TRANSFER_PROCESS_ID); + + assertThat(revokeResult.succeeded()).isTrue(); + + DescribeAclsResult describeAfterRevoke = adminClient.describeAcls(AclBindingFilter.ANY); + Collection aclsAfterRevoke = describeAfterRevoke.values().get(); + + assertThat(aclsBeforeRevoke).hasSize(3); + assertThat(aclsAfterRevoke).isEmpty(); + } + + @Test + void revokeAclsForSubject_shouldRemoveAclsSuccessfully() throws Exception { + Result createResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); + assertThat(createResult.succeeded()).isTrue(); + + DescribeAclsResult describeResult = adminClient.describeAcls(AclBindingFilter.ANY); + Collection aclsBeforeRevoke = describeResult.values().get(); + + Result revokeResult = aclService.revokeAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX); + + assertThat(revokeResult.succeeded()).isTrue(); + + DescribeAclsResult describeAfterRevoke = adminClient.describeAcls(AclBindingFilter.ANY); + Collection aclsAfterRevoke = describeAfterRevoke.values().get(); + + assertThat(aclsBeforeRevoke).hasSize(3); + assertThat(aclsAfterRevoke).isEmpty(); + } + + @Test + void topicAccess_afterAclRevocation_shouldBeBlocked() throws Exception { + Result createResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); + assertThat(createResult.succeeded()).isTrue(); + + produceTestMessage(TEST_TOPIC, "test-key", "test-value"); + + Properties consumerProps = createConsumerProperties(TEST_OAUTH_SUBJECT); + try (KafkaConsumer consumer = new KafkaConsumer<>(consumerProps)) { + consumer.assign(List.of(TEST_PARTITION)); + consumer.seekToBeginning(List.of(TEST_PARTITION)); + ConsumerRecords records = consumer.poll(POLL_TIMEOUT); + assertThat(records.count()).isEqualTo(1); + } + + Result revokeResult = aclService.revokeAclsForTransferProcess(TEST_TRANSFER_PROCESS_ID); + assertThat(revokeResult.succeeded()).isTrue(); + + try (KafkaConsumer consumer = new KafkaConsumer<>(consumerProps)) { + consumer.assign(List.of(TEST_PARTITION)); + assertThatThrownBy(() -> consumer.poll(POLL_TIMEOUT)).isInstanceOf(TopicAuthorizationException.class); + } + } + + @Test + void revokeAclsForTransferProcess_withNonExistentId_shouldSucceed() { + Result result = aclService.revokeAclsForTransferProcess("non-existent-id"); + + assertThat(result.succeeded()).isTrue(); + } + + @Test + void multipleTransferProcesses_shouldTrackAclsIndependently() throws Exception { + String transferProcess1 = "transfer-1"; + String transferProcess2 = "transfer-2"; + String user1 = "user1"; + String user2 = "user2"; + + Result result1 = aclService.createAclsForSubject(user1, TEST_TOPIC, TEST_GROUP_PREFIX, transferProcess1); + Result result2 = aclService.createAclsForSubject(user2, TEST_TOPIC, TEST_GROUP_PREFIX, transferProcess2); + + assertThat(result1.succeeded()).isTrue(); + assertThat(result2.succeeded()).isTrue(); + + Result revokeResult = aclService.revokeAclsForTransferProcess(transferProcess1); + assertThat(revokeResult.succeeded()).isTrue(); + + DescribeAclsResult describeResult = adminClient.describeAcls(AclBindingFilter.ANY); + Collection remainingAcls = describeResult.values().get(); + + boolean user2AclsExist = remainingAcls.stream() + .anyMatch(acl -> acl.entry().principal().equals("User:" + user2)); + + boolean user1AclsExist = remainingAcls.stream() + .anyMatch(acl -> acl.entry().principal().equals("User:" + user1)); + + assertThat(user2AclsExist).isTrue(); + assertThat(user1AclsExist).isFalse(); + } + + @Test + void consumerGroupJoin_withPrefixedGroup_shouldBeAllowed() throws Exception { + Result aclResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); + assertThat(aclResult.succeeded()).isTrue(); + + produceTestMessage(TEST_TOPIC, "test-key", "test-value"); + + // group.id starts with the granted prefix. Joining the coordinator via subscribe() requires READ + // on the GROUP resource, which the fix scopes to the group prefix (not the subject) — so the same + // prefix handed to the consumer in the EDR is the one the broker authorizes. + Properties consumerProps = createConsumerProperties(TEST_OAUTH_SUBJECT, TEST_GROUP_PREFIX + "-consumer-1"); + + try (KafkaConsumer consumer = new KafkaConsumer<>(consumerProps)) { + consumer.subscribe(List.of(TEST_TOPIC)); + + int count = 0; + String value = null; + long deadline = System.currentTimeMillis() + 20_000; + while (count == 0 && System.currentTimeMillis() < deadline) { + ConsumerRecords records = consumer.poll(POLL_TIMEOUT); + count = records.count(); + if (count > 0) { + value = records.iterator().next().value(); + } + } + + assertThat(count).isEqualTo(1); + assertThat(value).isEqualTo("test-value"); + } + } + + @Test + void consumerGroupJoin_withNonPrefixedGroup_shouldBeBlocked() throws Exception { + Result aclResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); + assertThat(aclResult.succeeded()).isTrue(); + + produceTestMessage(TEST_TOPIC, "test-key", "test-value"); + + // group.id outside the granted prefix: the subject has topic READ/DESCRIBE, but the GROUP READ ACL + // does not cover this group, so the coordinator join is denied. Guards against widening the ACL. + Properties consumerProps = createConsumerProperties(TEST_OAUTH_SUBJECT, "other-group"); + + try (KafkaConsumer consumer = new KafkaConsumer<>(consumerProps)) { + consumer.subscribe(List.of(TEST_TOPIC)); + assertThatThrownBy(() -> { + long deadline = System.currentTimeMillis() + 20_000; + while (System.currentTimeMillis() < deadline) { + consumer.poll(POLL_TIMEOUT); + } + }).isInstanceOf(GroupAuthorizationException.class); + } + } + + private Properties createConsumerProperties(String username) { + return createConsumerProperties(username, GROUP_ID); + } + + private Properties createConsumerProperties(String username, String groupId) { + Properties props = new Properties(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaContainer.getBootstrapServers()); + props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName()); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "false"); + + props.put(SaslConfigs.SASL_MECHANISM, PlainSaslServer.PLAIN_MECHANISM); + props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, SecurityProtocol.SASL_PLAINTEXT.name()); + props.put(SaslConfigs.SASL_JAAS_CONFIG, + ("org.apache.kafka.common.security.plain.PlainLoginModule required " + + "username=\"%s\" password=\"%s\";").formatted(username, "password")); + + return props; + } + + private void produceTestMessage(String topic, String key, String value) throws ExecutionException, InterruptedException { + Properties producerProps = new Properties(); + producerProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaContainer.getBootstrapServers()); + producerProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); + producerProps.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, SecurityProtocol.SASL_PLAINTEXT.name()); + producerProps.put(SaslConfigs.SASL_MECHANISM, PlainSaslServer.PLAIN_MECHANISM); + producerProps.put(SaslConfigs.SASL_JAAS_CONFIG, ADMIN_LOGIN_MODULE); + + try (KafkaProducer producer = new KafkaProducer<>(producerProps)) { + ProducerRecord producerRecord = new ProducerRecord<>(topic, key, value); + producer.send(producerRecord).get(); + producer.flush(); + } + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceComponentTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceComponentTest.java new file mode 100644 index 0000000000..c9bc1e2334 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceComponentTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.auth; + +import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.eclipse.edc.http.spi.EdcHttpClient; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class KafkaOauthServiceComponentTest { + + private KafkaOauthServiceImpl oauthService; + private EdcHttpClient mockHttpClient; + + @BeforeEach + void setUp() { + mockHttpClient = mock(EdcHttpClient.class); + oauthService = new KafkaOauthServiceImpl(mockHttpClient, new ObjectMapper()); + } + + @Test + void shouldSuccessfullyRetrieveAccessToken() throws IOException { + OauthCredentials credentials = new OauthCredentials( + "https://example.com/token", + Optional.empty(), + "test-client", + "test-secret" + ); + + Response mockResponse = mock(Response.class); + ResponseBody mockResponseBody = mock(ResponseBody.class); + + when(mockResponse.isSuccessful()).thenReturn(true); + when(mockResponse.code()).thenReturn(200); + when(mockResponse.body()).thenReturn(mockResponseBody); + when(mockResponseBody.string()).thenReturn("{\"access_token\":\"test-access-token\",\"token_type\":\"Bearer\"}"); + + when(mockHttpClient.execute(any(Request.class))) + .thenAnswer(invocation -> { + Request request = invocation.getArgument(0); + + assertThat(request.method()).isEqualTo("POST"); + assertThat(request.url().encodedPath()).isEqualTo("/token"); + assertThat(request.header("Content-Type")).isEqualTo("application/x-www-form-urlencoded"); + + return mockResponse; + }); + + String accessToken = oauthService.getAccessToken(credentials); + + assertThat(accessToken).isEqualTo("test-access-token"); + verify(mockHttpClient, times(1)).execute(any(Request.class)); + } + + @Test + void shouldThrow_WhenResponseHasNoAccessToken() throws IOException { + OauthCredentials credentials = new OauthCredentials( + "https://example.com/token", + Optional.empty(), + "test-client", + "test-secret" + ); + + Response mockResponse = mock(Response.class); + ResponseBody mockResponseBody = mock(ResponseBody.class); + + when(mockResponse.isSuccessful()).thenReturn(true); + when(mockResponse.code()).thenReturn(200); + when(mockResponse.body()).thenReturn(mockResponseBody); + when(mockResponseBody.string()).thenReturn("{\"token_type\":\"Bearer\"}"); + + when(mockHttpClient.execute(any(Request.class))).thenReturn(mockResponse); + + assertThatThrownBy(() -> oauthService.getAccessToken(credentials)) + .isInstanceOf(RuntimeException.class) + .hasMessageContaining("access_token"); + } + + @Test + void shouldHandleTokenRetrievalFailure() throws IOException { + OauthCredentials credentials = new OauthCredentials( + "https://example.com/token", + Optional.empty(), + "test-client", + "test-secret" + ); + + Response mockResponse = mock(Response.class); + + when(mockResponse.isSuccessful()).thenReturn(false); + when(mockResponse.code()).thenReturn(401); + + when(mockHttpClient.execute(any(Request.class))) + .thenAnswer(invocation -> { + Request request = invocation.getArgument(0); + + assertThat(request.method()).isEqualTo("POST"); + assertThat(request.url().encodedPath()).isEqualTo("/token"); + assertThat(request.header("Content-Type")).isEqualTo("application/x-www-form-urlencoded"); + + return mockResponse; + }); + + assertThatThrownBy(() -> oauthService.getAccessToken(credentials)) + .isInstanceOf(RuntimeException.class) + .hasMessageContaining("Oauth2 token endpoint returned HTTP 401"); + verify(mockHttpClient, times(1)).execute(any(Request.class)); + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceImplTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceImplTest.java new file mode 100644 index 0000000000..2e5a62f5b6 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/auth/KafkaOauthServiceImplTest.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.auth; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.eclipse.edc.http.spi.EdcHttpClient; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class KafkaOauthServiceImplTest { + + public static final String ACCESS_TOKEN_KEY = "access_token"; + private static final String TOKEN_URL = "https://token.url"; + private static final String REVOKE_URL = "https://revoke.url"; + private static final String CLIENT_ID = "clientId"; + private static final String CLIENT_SECRET = "clientSecret"; + private static final String TEST_TOKEN = "test-token"; + private static final String IO_ERROR_MESSAGE = "IO error"; + + private EdcHttpClient mockHttpClient; + private ObjectMapper mockObjectMapper; + private KafkaOauthServiceImpl oauthService; + private Response mockResponse; + + @BeforeEach + void setUp() { + mockHttpClient = mock(EdcHttpClient.class); + mockObjectMapper = mock(ObjectMapper.class); + mockResponse = mock(Response.class); + oauthService = new KafkaOauthServiceImpl(mockHttpClient, mockObjectMapper); + } + + @Nested + class RevokeTokenTests { + private OauthCredentials createCredentialsWithRevocationUrl() { + return new OauthCredentials(TOKEN_URL, Optional.of(REVOKE_URL), CLIENT_ID, CLIENT_SECRET); + } + + private OauthCredentials createCredentialsWithoutRevocationUrl() { + return new OauthCredentials(TOKEN_URL, Optional.empty(), CLIENT_ID, CLIENT_SECRET); + } + + @Test + void shouldExecuteSuccessfully_whenResponseIsSuccessful() throws IOException { + when(mockResponse.isSuccessful()).thenReturn(true); + when(mockHttpClient.execute(any(Request.class))).thenReturn(mockResponse); + + oauthService.revokeToken(createCredentialsWithRevocationUrl(), TEST_TOKEN); + + verify(mockHttpClient, times(1)).execute(any(Request.class)); + } + + @Test + void shouldThrowException_whenResponseIsNotSuccessful() throws IOException { + when(mockResponse.isSuccessful()).thenReturn(false); + when(mockResponse.code()).thenReturn(403); + when(mockHttpClient.execute(any(Request.class))).thenReturn(mockResponse); + + RuntimeException exception = assertThrows(RuntimeException.class, + () -> oauthService.revokeToken(createCredentialsWithRevocationUrl(), TEST_TOKEN)); + assertEquals("Revoke endpoint returned HTTP 403", exception.getMessage()); + verify(mockHttpClient, times(1)).execute(any(Request.class)); + } + + @Test + void shouldThrowException_whenIoExceptionOccurs() throws IOException { + when(mockHttpClient.execute(any(Request.class))).thenThrow(new IOException(IO_ERROR_MESSAGE)); + + RuntimeException exception = assertThrows(RuntimeException.class, + () -> oauthService.revokeToken(createCredentialsWithRevocationUrl(), TEST_TOKEN)); + assertEquals("Failed to revoke Oauth2 token", exception.getMessage()); + verify(mockHttpClient, times(1)).execute(any(Request.class)); + } + + @Test + void shouldDoNothing_whenRevocationUrlIsEmpty() throws IOException { + oauthService.revokeToken(createCredentialsWithoutRevocationUrl(), TEST_TOKEN); + + verify(mockHttpClient, never()).execute(any(Request.class)); + } + } + + @Nested + class GetAccessTokenTests { + private OauthCredentials createCredentials() { + return new OauthCredentials(TOKEN_URL, Optional.empty(), CLIENT_ID, CLIENT_SECRET); + } + + @Test + void shouldReturnAccessToken_whenResponseIsSuccessful() throws IOException { + String mockResponseBody = "{\"access_token\": \"test-token\"}"; + ResponseBody mockResponseBodyObj = mock(ResponseBody.class); + JsonNode mockJsonNode = mock(JsonNode.class); + JsonNode mockTokenNode = mock(JsonNode.class); + + when(mockResponse.isSuccessful()).thenReturn(true); + when(mockResponse.body()).thenReturn(mockResponseBodyObj); + when(mockResponseBodyObj.string()).thenReturn(mockResponseBody); + when(mockJsonNode.get(ACCESS_TOKEN_KEY)).thenReturn(mockTokenNode); + when(mockTokenNode.asText()).thenReturn(TEST_TOKEN); + when(mockHttpClient.execute(any(Request.class))).thenReturn(mockResponse); + when(mockObjectMapper.readTree(mockResponseBody)).thenReturn(mockJsonNode); + + String accessToken = oauthService.getAccessToken(createCredentials()); + + assertEquals(TEST_TOKEN, accessToken); + verify(mockHttpClient, times(1)).execute(any(Request.class)); + } + + @Test + void shouldThrowException_whenResponseIsNotSuccessful() throws IOException { + when(mockResponse.isSuccessful()).thenReturn(false); + when(mockResponse.code()).thenReturn(401); + when(mockHttpClient.execute(any(Request.class))).thenReturn(mockResponse); + + RuntimeException exception = assertThrows(RuntimeException.class, + () -> oauthService.getAccessToken(createCredentials())); + assertEquals("Oauth2 token endpoint returned HTTP 401", exception.getMessage()); + verify(mockHttpClient, times(1)).execute(any(Request.class)); + } + + @Test + void shouldThrowException_whenIoExceptionOccurs() throws IOException { + when(mockHttpClient.execute(any(Request.class))).thenThrow(new IOException(IO_ERROR_MESSAGE)); + + RuntimeException exception = assertThrows(RuntimeException.class, + () -> oauthService.getAccessToken(createCredentials())); + assertEquals("Failed to fetch Oauth2 token", exception.getMessage()); + verify(mockHttpClient, times(1)).execute(any(Request.class)); + } + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/flow/KafkaEndpointDataReferenceServiceTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/flow/KafkaEndpointDataReferenceServiceTest.java new file mode 100644 index 0000000000..898ff9b649 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/flow/KafkaEndpointDataReferenceServiceTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.flow; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.edc.connector.dataplane.spi.DataFlow; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.dataplane.kafka.acl.KafkaAclService; +import org.junit.jupiter.api.Test; + +import java.util.Base64; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.GROUP_PREFIX; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.KAFKA_TYPE; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOKEN; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOPIC; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +class KafkaEndpointDataReferenceServiceTest { + + private static final String FLOW_ID = "flow-1"; + private static final String GROUP = "group-prefix"; + + private final KafkaAclService aclService = mock(); + private final KafkaEndpointDataReferenceService service = + new KafkaEndpointDataReferenceService(aclService, mock(Monitor.class), new ObjectMapper()); + + @Test + void createEndpointDataReference_createsAcls_andReturnsEdr() { + var edr = edr(jwtWithSub("kafka-subject"), "test-topic", GROUP); + var dataFlow = dataFlow(edr); + when(aclService.createAclsForSubject(any(), any(), any(), any())).thenReturn(Result.success()); + + var result = service.createEndpointDataReference(dataFlow); + + assertThat(result.succeeded()).isTrue(); + assertThat(result.getContent()).isSameAs(edr); + verify(aclService).createAclsForSubject("kafka-subject", "test-topic", GROUP, FLOW_ID); + } + + @Test + void createEndpointDataReference_fails_whenNoActualSource() { + var dataFlow = mock(DataFlow.class); + when(dataFlow.getId()).thenReturn(FLOW_ID); + when(dataFlow.getActualSource()).thenReturn(null); + + assertThat(service.createEndpointDataReference(dataFlow).failed()).isTrue(); + } + + @Test + void createEndpointDataReference_fails_whenAclCreationFails() { + var dataFlow = dataFlow(edr(jwtWithSub("kafka-subject"), "test-topic", GROUP)); + when(aclService.createAclsForSubject(any(), any(), any(), any())).thenReturn(Result.failure("broker error")); + + assertThat(service.createEndpointDataReference(dataFlow).failed()).isTrue(); + } + + @Test + void createEndpointDataReference_returnsEdr_whenAclManagementDisabled() { + var noAcl = new KafkaEndpointDataReferenceService(null, mock(Monitor.class), new ObjectMapper()); + var edr = edr("any-token", "test-topic", GROUP); + + var result = noAcl.createEndpointDataReference(dataFlow(edr)); + + assertThat(result.succeeded()).isTrue(); + assertThat(result.getContent()).isSameAs(edr); + verifyNoInteractions(aclService); + } + + @Test + void revoke_revokesAcls_onSuspendOrTerminate() { + when(aclService.revokeAclsForTransferProcess(FLOW_ID)).thenReturn(Result.success()); + + var result = service.revokeEndpointDataReference(FLOW_ID, "suspended"); + + assertThat(result.succeeded()).isTrue(); + verify(aclService).revokeAclsForTransferProcess(FLOW_ID); + } + + @Test + void revoke_fails_whenAclRevocationFails() { + when(aclService.revokeAclsForTransferProcess(FLOW_ID)).thenReturn(Result.failure("broker error")); + + assertThat(service.revokeEndpointDataReference(FLOW_ID, "terminated").failed()).isTrue(); + } + + @Test + void revoke_isNoOp_whenAclManagementDisabled() { + var noAcl = new KafkaEndpointDataReferenceService(null, mock(Monitor.class), new ObjectMapper()); + + var result = noAcl.revokeEndpointDataReference(FLOW_ID, "suspended"); + + assertThat(result.succeeded()).isTrue(); + verifyNoInteractions(aclService); + } + + private static DataFlow dataFlow(DataAddress actualSource) { + var dataFlow = mock(DataFlow.class); + when(dataFlow.getId()).thenReturn(FLOW_ID); + when(dataFlow.getActualSource()).thenReturn(actualSource); + return dataFlow; + } + + private static DataAddress edr(String token, String topic, String groupPrefix) { + return DataAddress.Builder.newInstance() + .type(KAFKA_TYPE) + .property(TOKEN, token) + .property(TOPIC, topic) + .property(GROUP_PREFIX, groupPrefix) + .build(); + } + + private static String jwtWithSub(String sub) { + var enc = Base64.getUrlEncoder().withoutPadding(); + var header = enc.encodeToString("{\"alg\":\"none\"}".getBytes()); + var payload = enc.encodeToString(("{\"sub\":\"" + sub + "\"}").getBytes()); + var sig = enc.encodeToString("sig".getBytes()); + return header + "." + payload + "." + sig; + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaDeprovisionerTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaDeprovisionerTest.java new file mode 100644 index 0000000000..2fd20d9e72 --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaDeprovisionerTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.provision; + +import org.eclipse.edc.connector.dataplane.spi.provision.DeprovisionedResource; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.dataplane.kafka.acl.KafkaAclService; +import org.eclipse.tractusx.edc.dataplane.kafka.auth.KafkaOauthService; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.KAFKA_TYPE; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_ID; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_SECRET_KEY; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_TOKEN_URL; +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.KAFKA_RESOURCE_TYPE; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class KafkaDeprovisionerTest { + + private static final String FLOW_ID = "flow-1"; + private static final String SECRET_KEY = "client-secret-key"; + private static final String TOKEN_VALUE = "minted-token"; + + private final Vault vault = mock(); + private final KafkaOauthService oauthService = mock(); + private final KafkaAclService aclService = mock(); + private final KafkaDeprovisioner deprovisioner = new KafkaDeprovisioner(vault, oauthService, aclService, mock(Monitor.class)); + + @Test + void deprovision_revokesAcls_token_andDeletesVaultSecret() throws Exception { + when(aclService.revokeAclsForTransferProcess(FLOW_ID)).thenReturn(Result.success()); + when(vault.resolveSecret(FLOW_ID)).thenReturn(TOKEN_VALUE); + when(vault.resolveSecret(SECRET_KEY)).thenReturn("secret-value"); + + StatusResult result = deprovisioner.deprovision(resource()).get(); + + assertThat(result.succeeded()).isTrue(); + verify(aclService).revokeAclsForTransferProcess(FLOW_ID); + verify(oauthService).revokeToken(any(), eq(TOKEN_VALUE)); + verify(vault).deleteSecret(FLOW_ID); + } + + @Test + void deprovision_isIdempotent_whenTokenAlreadyGone() throws Exception { + when(aclService.revokeAclsForTransferProcess(FLOW_ID)).thenReturn(Result.success()); + when(vault.resolveSecret(FLOW_ID)).thenReturn(null); + + StatusResult result = deprovisioner.deprovision(resource()).get(); + + assertThat(result.succeeded()).isTrue(); + verify(oauthService, never()).revokeToken(any(), any()); + verify(vault, never()).deleteSecret(any()); + } + + @Test + void deprovision_revokesToken_whenAclManagementDisabled() throws Exception { + var noAcl = new KafkaDeprovisioner(vault, oauthService, null, mock(Monitor.class)); + when(vault.resolveSecret(FLOW_ID)).thenReturn(TOKEN_VALUE); + when(vault.resolveSecret(SECRET_KEY)).thenReturn("secret-value"); + + StatusResult result = noAcl.deprovision(resource()).get(); + + assertThat(result.succeeded()).isTrue(); + verify(oauthService).revokeToken(any(), eq(TOKEN_VALUE)); + verify(vault).deleteSecret(FLOW_ID); + } + + @Test + void deprovision_fails_whenAclRevocationFails() throws Exception { + when(aclService.revokeAclsForTransferProcess(FLOW_ID)).thenReturn(Result.failure("broker error")); + + StatusResult result = deprovisioner.deprovision(resource()).get(); + + assertThat(result.failed()).isTrue(); + verify(oauthService, never()).revokeToken(any(), any()); + } + + @Test + void deprovision_fails_whenClientSecretMissing() throws Exception { + when(aclService.revokeAclsForTransferProcess(FLOW_ID)).thenReturn(Result.success()); + when(vault.resolveSecret(FLOW_ID)).thenReturn(TOKEN_VALUE); + when(vault.resolveSecret(SECRET_KEY)).thenReturn(null); + + StatusResult result = deprovisioner.deprovision(resource()).get(); + + assertThat(result.failed()).isTrue(); + } + + private ProvisionResource resource() { + var source = DataAddress.Builder.newInstance() + .type(KAFKA_TYPE) + .property(OAUTH_TOKEN_URL, "http://localhost:8080/token") + .property(OAUTH_CLIENT_ID, "client-id") + .property(OAUTH_CLIENT_SECRET_KEY, SECRET_KEY) + .build(); + return ProvisionResource.Builder.newInstance() + .id("resource-1") + .flowId(FLOW_ID) + .type(KAFKA_RESOURCE_TYPE) + .dataAddress(source) + .build(); + } +} diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisionerTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisionerTest.java new file mode 100644 index 0000000000..03db19c00c --- /dev/null +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/provision/KafkaProvisionerTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.provision; + +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionResource; +import org.eclipse.edc.connector.dataplane.spi.provision.ProvisionedResource; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.dataplane.kafka.auth.KafkaOauthService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.BOOTSTRAP_SERVERS; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.GROUP_PREFIX; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.KAFKA_TYPE; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.MECHANISM; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_ID; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_SECRET_KEY; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_TOKEN_URL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.PROTOCOL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOKEN; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOPIC; +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.CONSUMER_GROUP_PREFIX_PROPERTY; +import static org.eclipse.tractusx.edc.dataplane.kafka.provision.KafkaProvisionConstants.KAFKA_RESOURCE_TYPE; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class KafkaProvisionerTest { + + private static final String FLOW_ID = "flow-1"; + private static final String SECRET_KEY = "client-secret-key"; + private static final String TOKEN_VALUE = "access-token"; + private static final String DATA_ADDRESS_GROUP_PREFIX = "provider-group-prefix"; + private static final String CONSUMER_BPN = "consumer-bpn"; + + private final Vault vault = mock(); + private final KafkaOauthService oauthService = mock(); + private KafkaProvisioner provisioner; + + @BeforeEach + void setUp() { + provisioner = new KafkaProvisioner(vault, oauthService, mock(Monitor.class)); + when(vault.resolveSecret(SECRET_KEY)).thenReturn("secret-value"); + when(oauthService.getAccessToken(any())).thenReturn(TOKEN_VALUE); + } + + @Test + void provision_mintsToken_andBuildsEdr() throws Exception { + StatusResult result = provisioner.provision(resource(DATA_ADDRESS_GROUP_PREFIX, CONSUMER_BPN)).get(); + + assertThat(result.succeeded()).isTrue(); + DataAddress edr = result.getContent().getDataAddress(); + assertThat(edr.getType()).isEqualTo(KAFKA_TYPE); + assertThat(edr.getStringProperty(TOPIC)).isEqualTo("test-topic"); + assertThat(edr.getStringProperty(TOKEN)).isEqualTo(TOKEN_VALUE); + // the kafka.group.prefix property is honored over the consumer BPN fallback + assertThat(edr.getStringProperty(GROUP_PREFIX)).isEqualTo(DATA_ADDRESS_GROUP_PREFIX); + + verify(vault).storeSecret(eq(FLOW_ID), eq(TOKEN_VALUE)); + } + + @Test + void provision_fallsBackToConsumerBpn_whenGroupPrefixAbsent() throws Exception { + StatusResult result = provisioner.provision(resource(null, CONSUMER_BPN)).get(); + + assertThat(result.succeeded()).isTrue(); + assertThat(result.getContent().getDataAddress().getStringProperty(GROUP_PREFIX)).isEqualTo(CONSUMER_BPN); + } + + @Test + void provision_fails_whenGroupPrefixUnresolvable() throws Exception { + StatusResult result = provisioner.provision(resource(null, null)).get(); + + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureDetail()).contains("consumer-group prefix"); + } + + private ProvisionResource resource(String groupPrefix, String consumerBpn) { + var builder = DataAddress.Builder.newInstance() + .type(KAFKA_TYPE) + .property(TOPIC, "test-topic") + .property(BOOTSTRAP_SERVERS, "localhost:9092") + .property(PROTOCOL, "SASL_PLAINTEXT") + .property(MECHANISM, "OAUTHBEARER") + .property(OAUTH_TOKEN_URL, "http://localhost:8080/token") + .property(OAUTH_CLIENT_ID, "client-id") + .property(OAUTH_CLIENT_SECRET_KEY, SECRET_KEY); + if (groupPrefix != null) { + builder.property(GROUP_PREFIX, groupPrefix); + } + var resourceBuilder = ProvisionResource.Builder.newInstance() + .id("resource-1") + .flowId(FLOW_ID) + .type(KAFKA_RESOURCE_TYPE) + .dataAddress(builder.build()); + if (consumerBpn != null) { + resourceBuilder.property(CONSUMER_GROUP_PREFIX_PROPERTY, consumerBpn); + } + return resourceBuilder.build(); + } +} diff --git a/edc-extensions/dataplane/kafka/validator-data-address-kafka/build.gradle.kts b/edc-extensions/dataplane/kafka/validator-data-address-kafka/build.gradle.kts new file mode 100644 index 0000000000..216812a98c --- /dev/null +++ b/edc-extensions/dataplane/kafka/validator-data-address-kafka/build.gradle.kts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + `java-library` +} + +dependencies { + implementation(libs.edc.spi.core) + implementation(libs.edc.lib.validator) + implementation(project(":edc-extensions:dataplane:kafka:data-address-kafka")) + + testImplementation(libs.edc.junit) +} diff --git a/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidator.java b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidator.java new file mode 100644 index 0000000000..b0950b6796 --- /dev/null +++ b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidator.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.validator; + +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.validator.spi.ValidationResult; +import org.eclipse.edc.validator.spi.Validator; +import org.eclipse.edc.validator.spi.Violation; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; + +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.BOOTSTRAP_SERVERS; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.MECHANISM; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_ID; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_SECRET_KEY; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_TOKEN_URL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.PROTOCOL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOPIC; + +public class KafkaBrokerDataAddressValidator implements Validator { + + public KafkaBrokerDataAddressValidator() { + } + + @Override + public ValidationResult validate(final DataAddress input) { + List violations = Stream.of( + TOPIC, + BOOTSTRAP_SERVERS, + MECHANISM, + PROTOCOL, + OAUTH_TOKEN_URL, + OAUTH_CLIENT_ID, + OAUTH_CLIENT_SECRET_KEY + ).map((final String it) -> { + String value = input.getStringProperty(it); + return value != null && !value.isBlank() ? null : Violation.violation("'%s' is a mandatory attribute".formatted(it), it, value); + }).filter(Objects::nonNull).toList(); + return violations.isEmpty() ? ValidationResult.success() : ValidationResult.failure(violations); + } +} diff --git a/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorExtension.java b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorExtension.java new file mode 100644 index 0000000000..8fbd27207e --- /dev/null +++ b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorExtension.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.validator; + +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.validator.spi.DataAddressValidatorRegistry; + +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.KAFKA_TYPE; + +@Extension(value = KafkaBrokerDataAddressValidatorExtension.NAME) +public class KafkaBrokerDataAddressValidatorExtension implements ServiceExtension { + public static final String NAME = "DataAddress KafkaBroker Validator"; + + @Inject + private DataAddressValidatorRegistry dataAddressValidatorRegistry; + + public KafkaBrokerDataAddressValidatorExtension() { + } + + @Override + public void initialize(final ServiceExtensionContext context) { + var validator = new KafkaBrokerDataAddressValidator(); + this.dataAddressValidatorRegistry.registerSourceValidator(KAFKA_TYPE, validator); + this.dataAddressValidatorRegistry.registerDestinationValidator(KAFKA_TYPE, validator); + } +} diff --git a/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..bb1387e57f --- /dev/null +++ b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.tractusx.edc.dataplane.kafka.validator.KafkaBrokerDataAddressValidatorExtension diff --git a/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorExtensionTest.java b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorExtensionTest.java new file mode 100644 index 0000000000..5ff04c9b22 --- /dev/null +++ b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorExtensionTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.validator; + +import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.validator.spi.DataAddressValidatorRegistry; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +@ExtendWith(DependencyInjectionExtension.class) +class KafkaBrokerDataAddressValidatorExtensionTest { + + private final DataAddressValidatorRegistry dataAddressValidatorRegistry = mock(); + + @BeforeEach + void setUp(final ServiceExtensionContext context) { + context.registerService(DataAddressValidatorRegistry.class, dataAddressValidatorRegistry); + } + + @Test + void initialize_shouldRegisterValidatorsWithKafkaType(final KafkaBrokerDataAddressValidatorExtension extension, final ServiceExtensionContext context) { + extension.initialize(context); + + verify(dataAddressValidatorRegistry, times(1)) + .registerSourceValidator(anyString(), any(KafkaBrokerDataAddressValidator.class)); + verify(dataAddressValidatorRegistry, times(1)) + .registerDestinationValidator(anyString(), any(KafkaBrokerDataAddressValidator.class)); + } +} diff --git a/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorTest.java b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorTest.java new file mode 100644 index 0000000000..6baa96ef06 --- /dev/null +++ b/edc-extensions/dataplane/kafka/validator-data-address-kafka/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/validator/KafkaBrokerDataAddressValidatorTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.dataplane.kafka.validator; + +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.validator.spi.ValidationFailure; +import org.eclipse.edc.validator.spi.Violation; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.BOOTSTRAP_SERVERS; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.MECHANISM; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_ID; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_CLIENT_SECRET_KEY; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.OAUTH_TOKEN_URL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.PROTOCOL; +import static org.eclipse.tractusx.edc.dataplane.kafka.dataaddress.KafkaBrokerDataAddressSchema.TOPIC; + +class KafkaBrokerDataAddressValidatorTest { + + private final KafkaBrokerDataAddressValidator validator = new KafkaBrokerDataAddressValidator(); + + @Test + void shouldPass_whenDataAddressIsValid() { + var dataAddress = DataAddress.Builder.newInstance() + .type("Kafka") + .property(TOPIC, "topic.name") + .property(BOOTSTRAP_SERVERS, "any:98123") + .property(MECHANISM, "OAUTHBEARER") + .property(PROTOCOL, "SASL_PLAINTEXT") + .property(OAUTH_TOKEN_URL, "http://keycloak/token") + .property(OAUTH_CLIENT_ID, "client-id") + .property(OAUTH_CLIENT_SECRET_KEY, "clientSecretKey") + .build(); + + var result = validator.validate(dataAddress); + + assertThat(result).isSucceeded(); + } + + @Test + void shouldFail_whenRequiredFieldsAreMissing() { + var dataAddress = DataAddress.Builder.newInstance() + .type("Kafka") + .build(); + + var result = validator.validate(dataAddress); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations) + .satisfies(violations -> assertThat(violations).extracting(Violation::path) + .containsExactlyInAnyOrder(TOPIC, BOOTSTRAP_SERVERS, MECHANISM, PROTOCOL, OAUTH_TOKEN_URL, + OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET_KEY)); + } +} diff --git a/edc-tests/e2e-fixtures/build.gradle.kts b/edc-tests/e2e-fixtures/build.gradle.kts index 7c3b110d21..17b6d2f69c 100644 --- a/edc-tests/e2e-fixtures/build.gradle.kts +++ b/edc-tests/e2e-fixtures/build.gradle.kts @@ -63,7 +63,9 @@ dependencies { testFixturesApi(libs.wiremock) testFixturesApi(libs.postgres) testFixturesApi(libs.restAssured) + testFixturesApi(libs.kafka.clients) testFixturesApi(libs.testcontainers.junit) + testFixturesApi(libs.testcontainers.kafka) testFixturesApi(libs.testcontainers.minio) testFixturesApi(libs.testcontainers.localstack) testFixturesApi(libs.testcontainers.postgres) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/kafka/KafkaExtension.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/kafka/KafkaExtension.java new file mode 100644 index 0000000000..225e1454d2 --- /dev/null +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/kafka/KafkaExtension.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.kafka; + +import org.apache.kafka.clients.admin.Admin; +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.testcontainers.kafka.KafkaContainer; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +public class KafkaExtension implements BeforeAllCallback, AfterAllCallback { + + private static final String IMAGE = "apache/kafka-native:4.0.0"; + + // apache/kafka-native occasionally exits during boot under CI resource pressure; retry the + // container start a few times instead of failing the whole test class in @BeforeAll. + private final KafkaContainer kafkaContainer = new KafkaContainer(IMAGE) + .withStartupAttempts(3); + + @Override + public void beforeAll(ExtensionContext context) { + kafkaContainer.start(); + } + + @Override + public void afterAll(ExtensionContext context) { + kafkaContainer.stop(); + } + + public String getBootstrapServers() { + return kafkaContainer.getBootstrapServers(); + } + + public void createTopic(String topic) { + var config = Map.of(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, getBootstrapServers()); + try (var admin = Admin.create(config)) { + admin.createTopics(List.of(new NewTopic(topic, 1, (short) 1))).all().get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } + + public void produce(String topic, String key, String value) { + var props = new Properties(); + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, getBootstrapServers()); + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + try (var producer = new KafkaProducer(props)) { + try { + producer.send(new ProducerRecord<>(topic, key, value)).get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } + } + + public List> consume(String topic, Duration timeout) { + return consume(getBootstrapServers(), topic, timeout); + } + + /** + * Consumes from the given topic using the supplied bootstrap servers — e.g. the broker coordinates + * carried by an EDR — so a test can verify the consumer uses the connection details it was handed. + */ + public List> consume(String bootstrapServers, String topic, Duration timeout) { + var props = new Properties(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-" + UUID.randomUUID()); + props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + var collected = new ArrayList>(); + try (var consumer = new KafkaConsumer(props)) { + consumer.subscribe(Collections.singletonList(topic)); + ConsumerRecords records = consumer.poll(timeout); + records.forEach(collected::add); + } + return collected; + } +} diff --git a/edc-tests/e2e/kafka-transfer-tests/build.gradle.kts b/edc-tests/e2e/kafka-transfer-tests/build.gradle.kts new file mode 100644 index 0000000000..c872468a35 --- /dev/null +++ b/edc-tests/e2e/kafka-transfer-tests/build.gradle.kts @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + `java-library` + `java-test-fixtures` +} + +dependencies { + testImplementation(testFixtures(project(":edc-tests:e2e-fixtures"))) + + testImplementation(libs.edc.junit) + testImplementation(libs.restAssured) + testImplementation(libs.wiremock) + testImplementation(libs.testcontainers.junit) + testImplementation(libs.testcontainers.kafka) + testImplementation(libs.kafka.clients) + + testCompileOnly(project(":edc-tests:runtime:runtime-postgresql")) +} + +edcBuild { + publish.set(false) +} diff --git a/edc-tests/e2e/kafka-transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/KafkaPullEndToEndTest.java b/edc-tests/e2e/kafka-transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/KafkaPullEndToEndTest.java new file mode 100644 index 0000000000..9bbd7bbd84 --- /dev/null +++ b/edc-tests/e2e/kafka-transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/KafkaPullEndToEndTest.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.transfer; + +import com.github.tomakehurst.wiremock.junit5.WireMockExtension; +import jakarta.json.Json; +import jakarta.json.JsonObject; +import org.eclipse.edc.jsonld.spi.JsonLd; +import org.eclipse.edc.junit.annotations.EndToEndTest; +import org.eclipse.edc.junit.extensions.RuntimeExtension; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.tractusx.edc.tests.kafka.KafkaExtension; +import org.eclipse.tractusx.edc.tests.participant.TransferParticipant; +import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; +import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates.STARTED; +import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates.TERMINATED; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.DSP_2025_PATH; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; +import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; +import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; + +/** + * End-to-end test for the {@code KafkaBroker-PULL} transfer type. Runs a real Kafka broker via + * Testcontainers and a WireMock-backed OAuth2 token endpoint. + */ +@EndToEndTest +public class KafkaPullEndToEndTest { + + private static final String TOPIC = "test-topic"; + private static final String CLIENT_ID = "kafka-client-id"; + private static final String CLIENT_SECRET_KEY = "kafka-client-secret"; + private static final String CLIENT_SECRET_VALUE = "kafka-client-secret-value"; + private static final String ACCESS_TOKEN = "test-access-token"; + + private static final TransferParticipant CONSUMER = TransferParticipant.Builder.newInstance() + .name(CONSUMER_NAME) + .id(CONSUMER_DID) + .bpn(CONSUMER_BPN) + .protocol(DSP_2025, DSP_2025_PATH) + .build(); + + private static final TransferParticipant PROVIDER = TransferParticipant.Builder.newInstance() + .name(PROVIDER_NAME) + .id(PROVIDER_DID) + .bpn(PROVIDER_BPN) + .protocol(DSP_2025, DSP_2025_PATH) + .build(); + + @RegisterExtension + @Order(0) + private static final PostgresExtension POSTGRES = new PostgresExtension(PROVIDER.getName(), CONSUMER.getName()); + + @RegisterExtension + private static final RuntimeExtension PROVIDER_RUNTIME = pgRuntime(PROVIDER, POSTGRES, PROVIDER::getConfig); + + @RegisterExtension + private static final RuntimeExtension CONSUMER_RUNTIME = pgRuntime(CONSUMER, POSTGRES, CONSUMER::getConfig); + + @RegisterExtension + private static final KafkaExtension KAFKA = new KafkaExtension(); + + @RegisterExtension + private static final WireMockExtension OAUTH = WireMockExtension.newInstance() + .options(wireMockConfig().dynamicPort()) + .build(); + + @BeforeAll + static void beforeAll() { + CONSUMER.setJsonLd(CONSUMER_RUNTIME.getService(JsonLd.class)); + } + + @BeforeEach + void beforeEach() { + // the provider's Kafka data plane mints (and revokes) the consumer token against this OAuth2 endpoint + OAUTH.stubFor(post(urlEqualTo("/token")) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("{\"access_token\":\"" + ACCESS_TOKEN + "\",\"expires_in\":3600}"))); + OAUTH.stubFor(post(urlEqualTo("/revoke")) + .willReturn(aResponse().withStatus(200))); + PROVIDER_RUNTIME.getService(Vault.class).storeSecret(CLIENT_SECRET_KEY, CLIENT_SECRET_VALUE); + } + + @Test + void kafkaPullTransfer_consumerReceivesMessages() { + KAFKA.createTopic(TOPIC); + KAFKA.produce(TOPIC, "k1", "hello"); + KAFKA.produce(TOPIC, "k2", "world"); + + var transferProcessId = startKafkaPullTransfer("kafka-test-asset", "def-1", kafkaSourceAddress("kafka-transfer-test", true)); + CONSUMER.waitForTransferProcess(transferProcessId, STARTED); + + // the consumer receives an EDR carrying the broker connection details and the minted token + var edr = CONSUMER.edrs().waitForEdr(transferProcessId); + assertThat(edr.getString("kafka.bootstrap.servers")).isEqualTo(KAFKA.getBootstrapServers()); + assertThat(edr.getString("topic")).isEqualTo(TOPIC); + assertThat(edr.getString("kafka.security.protocol")).isEqualTo("SASL_PLAINTEXT"); + assertThat(edr.getString("kafka.sasl.mechanism")).isEqualTo("OAUTHBEARER"); + assertThat(edr.getString("kafka.group.prefix")).isEqualTo(CONSUMER.getBpn()); + assertThat(edr.getString("token")).isEqualTo(ACCESS_TOKEN); + + // consuming via the broker coordinates and topic taken from the EDR returns the published messages + var consumed = KAFKA.consume(edr.getString("kafka.bootstrap.servers"), edr.getString("topic"), Duration.ofSeconds(10)); + assertThat(consumed).isNotEmpty(); + + // the data plane minted the access token via the OAuth2 client-credentials flow + OAUTH.verify(postRequestedFor(urlEqualTo("/token"))); + } + + @Test + void kafkaPullTransfer_withoutGroupPrefix_provisionsViaParticipantFallback() { + // the asset omits kafka.group.prefix, so the data plane must fall back to the consumer participant id + var transferProcessId = startKafkaPullTransfer("kafka-fallback-asset", "def-2", kafkaSourceAddress("kafka-fallback-test", false)); + CONSUMER.waitForTransferProcess(transferProcessId, STARTED); + + // provisioning still succeeds and the EDR carries a (non-blank) group prefix from the participant-id fallback + var edr = CONSUMER.edrs().waitForEdr(transferProcessId); + assertThat(edr.getString("kafka.group.prefix")).isNotBlank(); + OAUTH.verify(postRequestedFor(urlEqualTo("/token"))); + } + + @Test + void kafkaPullTransfer_terminationRevokesToken() { + var transferProcessId = startKafkaPullTransfer("kafka-terminate-asset", "def-3", kafkaSourceAddress("kafka-terminate-test", true)); + CONSUMER.waitForTransferProcess(transferProcessId, STARTED); + + // a token was minted (and stored under the flow id) while the transfer was active + OAUTH.verify(postRequestedFor(urlEqualTo("/token"))); + + // terminating the transfer deprovisions the Kafka flow, which revokes the OAuth2 token + CONSUMER.terminateTransfer(transferProcessId); + CONSUMER.waitForTransferProcess(transferProcessId, TERMINATED); + + await().atMost(ASYNC_TIMEOUT).untilAsserted(() -> + OAUTH.verify(postRequestedFor(urlEqualTo("/revoke")))); + } + + /** + * Registers the Kafka asset/policy/contract on the provider and starts a {@code KafkaBroker-PULL} + * transfer from the consumer, returning the transfer-process id. + */ + private String startKafkaPullTransfer(String assetId, String contractDefinitionId, Map dataAddress) { + PROVIDER.createAsset(assetId, Map.of(), dataAddress); + var policyId = PROVIDER.createPolicyDefinition(bpnPolicy(CONSUMER.getBpn())); + PROVIDER.createContractDefinition(assetId, contractDefinitionId, policyId, policyId); + + return CONSUMER.requestAssetFrom(assetId, PROVIDER) + .withTransferType("KafkaBroker-PULL") + .withDestination(kafkaPullDestination()) + .execute(); + } + + /** + * Builds a {@code KafkaBroker} source {@link Map} data address. When {@code withGroupPrefix} is + * {@code false} the {@code kafka.group.prefix} property is omitted to exercise the + * participant-id fallback. + */ + private Map kafkaSourceAddress(String name, boolean withGroupPrefix) { + var dataAddress = new HashMap(); + dataAddress.put("name", name); + dataAddress.put(TYPE, "DataAddress"); + dataAddress.put("type", "KafkaBroker"); + dataAddress.put("topic", TOPIC); + dataAddress.put("kafka.bootstrap.servers", KAFKA.getBootstrapServers()); + dataAddress.put("kafka.security.protocol", "SASL_PLAINTEXT"); + dataAddress.put("kafka.sasl.mechanism", "OAUTHBEARER"); + dataAddress.put("kafka.poll.duration", "PT1S"); + dataAddress.put("tokenUrl", OAUTH.baseUrl() + "/token"); + dataAddress.put("revokeUrl", OAUTH.baseUrl() + "/revoke"); + dataAddress.put("clientId", CLIENT_ID); + dataAddress.put("clientSecretKey", CLIENT_SECRET_KEY); + if (withGroupPrefix) { + dataAddress.put("kafka.group.prefix", CONSUMER.getBpn()); + } + return dataAddress; + } + + private JsonObject kafkaPullDestination() { + return Json.createObjectBuilder() + .add(TYPE, EDC_NAMESPACE + "DataAddress") + .add(EDC_NAMESPACE + "type", "HttpData") + .add(EDC_NAMESPACE + "baseUrl", "http://placeholder") + .build(); + } +} diff --git a/edc-tests/runtime/runtime-postgresql/build.gradle.kts b/edc-tests/runtime/runtime-postgresql/build.gradle.kts index 556bff33fb..bc85e02664 100644 --- a/edc-tests/runtime/runtime-postgresql/build.gradle.kts +++ b/edc-tests/runtime/runtime-postgresql/build.gradle.kts @@ -35,6 +35,10 @@ dependencies { exclude("org.eclipse.edc", "vault-hashicorp") } implementation(project(":edc-extensions:single-participant-vault")) + + // Kafka streaming is opt-in and not part of the base runtimes, so the e2e Kafka test needs it wired in here + implementation(project(":edc-extensions:dataplane:kafka:kafka-broker-extension")) + implementation(project(":edc-extensions:dataplane:kafka:validator-data-address-kafka")) } application { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7c4ae71764..a0a55910fa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,6 +16,7 @@ flyway = "12.11.0" jackson = "2.22.1" jakarta-json = "2.1.3" junit = "6.1.2" +kafka = "3.9.1" nimbus = "10.9.1" okhttp = "5.4.0" opentelemetry = "2.29.0" @@ -224,6 +225,7 @@ flyway-database-postgres = { module = "org.flywaydb:flyway-database-postgresql", jacksonJsonP = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp", version.ref = "jackson" } jakarta-rsApi = { module = "jakarta.ws.rs:jakarta.ws.rs-api", version.ref = "rsApi" } jakartaJson = { module = "jakarta.json:jakarta.json-api", version.ref = "jakarta-json" } +kafka-clients = { module = "org.apache.kafka:kafka-clients", version.ref = "kafka" } nimbus-jwt = { module = "com.nimbusds:nimbus-jose-jwt", version.ref = "nimbus" } okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } opentelemetry-javaagent = { module = "io.opentelemetry.javaagent:opentelemetry-javaagent", version.ref = "opentelemetry" } @@ -231,6 +233,7 @@ opentelemetry-instrumentation-annotations = { module = "io.opentelemetry.instrum postgres = { module = "org.postgresql:postgresql", version.ref = "postgres" } restAssured = { module = "io.rest-assured:rest-assured", version.ref = "restAssured" } testcontainers-junit = { module = "org.testcontainers:testcontainers-junit-jupiter", version.ref = "testcontainers" } +testcontainers-kafka = { module = "org.testcontainers:testcontainers-kafka", version.ref = "testcontainers" } testcontainers-keycloak = { module = "com.github.dasniko:testcontainers-keycloak", version.ref = "testcontainers-keycloak" } testcontainers-minio = { module = "org.testcontainers:testcontainers-minio", version.ref = "testcontainers" } testcontainers-localstack = { module = "org.testcontainers:testcontainers-localstack", version.ref = "testcontainers" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 226c371f52..62d0178c7c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -116,6 +116,9 @@ include(":edc-extensions:dataplane:dataplane-token-refresh:token-refresh-api") include(":edc-extensions:dataplane:dataplane-proxy:dataplane-public-api-v2") include(":edc-extensions:dataplane:dataflow:dataflow-api") include(":edc-extensions:dataplane:dataflow:dataflow-service") +include(":edc-extensions:dataplane:kafka:data-address-kafka") +include(":edc-extensions:dataplane:kafka:validator-data-address-kafka") +include(":edc-extensions:dataplane:kafka:kafka-broker-extension") include(":edc-extensions:non-finite-provider-push:non-finite-provider-push-spi") include(":edc-extensions:non-finite-provider-push:non-finite-provider-push-core") @@ -135,6 +138,7 @@ include(":edc-tests:e2e:cloud-transfer-tests") include(":edc-tests:e2e:edc-dataplane-tokenrefresh-tests") include(":edc-tests:e2e:edr-api-tests") include(":edc-tests:e2e:end2end-transfer-cloud") +include(":edc-tests:e2e:kafka-transfer-tests") include(":edc-tests:e2e:management-tests") include(":edc-tests:e2e:dcp-tests") include(":edc-tests:e2e:policy-tests") From 93623a268ed13596f7d24f5e6999e18fe4e107a5 Mon Sep 17 00:00:00 2001 From: Ronja Quensel <72978761+ronjaquensel@users.noreply.github.com> Date: Thu, 30 Jul 2026 16:25:55 +0200 Subject: [PATCH 220/259] feat: JSON-schema-based policy validation (#2960) * chore: add schema files * feat: implement schema-based validator * test(wip): fix test input * test: fix test input * chore: duplicate helper class * test: update test input for schema validator test * test: refactor policy creation * test: json schema resolution strategy * test: update validator unit test * test: fix bpn event e2e tests * test: fix catalog e2e tests * test: fix dcp e2e tests * test: fix discovery e2e tests * test: fix edr api e2e tests * test: fix management e2e tests * test: fix cloud transfer e2e tests * test: fix cdcp test runtime * test: fix policy monitor e2e tests * test: fix transfer e2e tests * chore: checkstyle * test: fix test input for v4 policy e2e test * chore: PR remarks * test: remove JSON schema unit tests * test: combine policy e2e tests & test inputs * chore: restore license header * chore: PR remarks * fix: Kafka test compilation * fix: schema directory structure --- edc-extensions/cx-policy/build.gradle.kts | 4 + .../edc/policy/cx/CxPolicyExtension.java | 6 + ...CxJsonSchemaPolicyDefinitionValidator.java | 52 +++ .../CxJsonSchemaPolicyValidator.java | 76 ++++ .../affiliates-bpnl-constraint-schema.json | 40 ++ .../affiliates-region-constraint-schema.json | 83 ++++ ...iness-partner-group-constraint-schema.json | 41 ++ ...ness-partner-number-constraint-schema.json | 42 ++ ...nformation-measures-constraint-schema.json | 35 ++ ...information-sharing-constraint-schema.json | 47 +++ .../contract-reference-constraint-schema.json | 39 ++ ...ontract-termination-constraint-schema.json | 43 ++ .../data-frequency-constraint-schema.json | 43 ++ ...ovisioning-end-date-constraint-schema.json | 35 ++ ...g-end-duration-days-constraint-schema.json | 35 ++ ...data-usage-end-date-constraint-schema.json | 35 ++ ...sage-end-definition-constraint-schema.json | 35 ++ ...e-end-duration-days-constraint-schema.json | 35 ++ .../exclusive-usage-constraint-schema.json | 35 ++ ...framework-agreement-constraint-schema.json | 35 ++ ...risdiction-location-constraint-schema.json | 34 ++ ...-location-reference-constraint-schema.json | 43 ++ .../liability-constraint-schema.json | 43 ++ .../membership-constraint-schema.json | 31 ++ .../precedence-constraint-schema.json | 43 ++ .../schema/atomic-constraint-schemas.json | 174 ++++++++ .../cx-policy/schema/context-schema.json | 28 ++ .../cx-policy/schema/policy-schema.json | 300 ++++++++++++++ .../usage-purpose-constraint-schema.json | 237 +++++++++++ .../usage-restriction-constraint-schema.json | 65 +++ .../version-changes-constraint-schema.json | 43 ++ .../cx-policy/warranty-constraint-schema.json | 49 +++ ...warranty-definition-constraint-schema.json | 35 ++ .../warranty-duration-constraint-schema.json | 35 ++ .../jsonschema/dspace/contract-schema.json | 374 ++++++++++++++++++ ...onSchemaPolicyDefinitionValidatorTest.java | 98 +++++ .../tests/helpers/PolicyHelperFunctions.java | 367 ++++++----------- .../tests/transfer/ConsumerPullBaseTest.java | 5 +- .../tests/transfer/ProviderPushBaseTest.java | 36 +- .../e2e/bpn-event-tests/build.gradle.kts | 7 + edc-tests/e2e/catalog-tests/build.gradle.kts | 7 + .../edc/tests/catalog/CatalogTest.java | 44 +-- .../edc/tests/catalog/CatalogTestDspV08.java | 34 +- edc-tests/e2e/dcp-tests/build.gradle.kts | 7 + .../transfer/AbstractDcpConsumerPullTest.java | 8 +- .../tests/transfer/CredentialSpoofTest.java | 3 +- .../e2e/discovery-tests/build.gradle.kts | 7 + edc-tests/e2e/edr-api-tests/build.gradle.kts | 7 + .../edc/tests/edrv2/NegotiateEdrTest.java | 7 +- .../end2end-transfer-cloud/build.gradle.kts | 7 + .../transfer/AzureToAzureEndToEndTest.java | 7 +- .../tests/transfer/S3ToS3EndToEndTest.java | 5 +- .../e2e/kafka-transfer-tests/build.gradle.kts | 7 + .../tests/transfer/KafkaPullEndToEndTest.java | 3 +- .../e2e/management-tests/build.gradle.kts | 7 + edc-tests/e2e/policy-tests/build.gradle.kts | 7 + .../policy/PolicyDefinitionEndToEndTest.java | 216 +++++----- edc-tests/e2e/transfer-tests/build.gradle.kts | 7 + .../tests/transfer/RetireAgreementTest.java | 8 +- .../TransferWithTokenRefreshTest.java | 5 +- .../runtime-memory-dcp-ih/build.gradle.kts | 6 - gradle/libs.versions.toml | 4 + 62 files changed, 2811 insertions(+), 445 deletions(-) create mode 100644 edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/validator/jsonschema/CxJsonSchemaPolicyDefinitionValidator.java create mode 100644 edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/validator/jsonschema/CxJsonSchemaPolicyValidator.java create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/affiliates-bpnl-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/affiliates-region-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/business-partner-group-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/business-partner-number-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/confidential-information-measures-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/confidential-information-sharing-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/contract-reference-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/contract-termination-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-frequency-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-provisioning-end-date-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-provisioning-end-duration-days-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-date-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-definition-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-duration-days-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/exclusive-usage-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/framework-agreement-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/jurisdiction-location-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/jurisdiction-location-reference-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/liability-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/membership-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/precedence-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/atomic-constraint-schemas.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/context-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/policy-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/usage-purpose-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/usage-restriction-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/version-changes-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-definition-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-duration-constraint-schema.json create mode 100644 edc-extensions/cx-policy/src/main/resources/jsonschema/dspace/contract-schema.json create mode 100644 edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/validator/CxJsonSchemaPolicyDefinitionValidatorTest.java diff --git a/edc-extensions/cx-policy/build.gradle.kts b/edc-extensions/cx-policy/build.gradle.kts index f33e2fd7a8..6ab12b7703 100644 --- a/edc-extensions/cx-policy/build.gradle.kts +++ b/edc-extensions/cx-policy/build.gradle.kts @@ -34,8 +34,12 @@ dependencies { implementation(libs.edc.spi.decentralized.claims) implementation(libs.edc.spi.policyengine) implementation(libs.edc.spi.vc) + implementation(libs.edc.lib.jsonld) implementation(libs.jakartaJson) implementation(libs.edc.spi.jsonld) + implementation(libs.jsonschema) + compileOnly(libs.edc.api.management.validator.jsonschema) + testImplementation(libs.jacksonJsonP) testImplementation(libs.titaniumJsonLd) diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/CxPolicyExtension.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/CxPolicyExtension.java index e3f6badc91..78df8dae8f 100644 --- a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/CxPolicyExtension.java +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/CxPolicyExtension.java @@ -61,6 +61,7 @@ import org.eclipse.tractusx.edc.policy.cx.usage.UsagePurposeConstraintFunction; import org.eclipse.tractusx.edc.policy.cx.usage.UsageRestrictionConstraintFunction; import org.eclipse.tractusx.edc.policy.cx.validator.CxPolicyDefinitionValidator; +import org.eclipse.tractusx.edc.policy.cx.validator.jsonschema.CxJsonSchemaPolicyDefinitionValidator; import org.eclipse.tractusx.edc.policy.cx.versionchange.VersionChangesConstraintFunction; import org.eclipse.tractusx.edc.policy.cx.warranty.WarrantyConstraintFunction; import org.eclipse.tractusx.edc.policy.cx.warranty.WarrantyDefinitionConstraintFunction; @@ -71,7 +72,9 @@ import java.util.Set; import java.util.stream.Stream; +import static org.eclipse.edc.connector.api.management.schema.ManagementApiSchemaValidatorExtension.V_4_PREFIX; import static org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE; +import static org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE_TERM; import static org.eclipse.edc.connector.policy.monitor.spi.PolicyMonitorContext.POLICY_MONITOR_SCOPE; import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; @@ -120,6 +123,8 @@ public class CxPolicyExtension implements ServiceExtension { private static final Set RULE_SCOPES = Set.of(CATALOG_REQUEST_SCOPE, NEGOTIATION_REQUEST_SCOPE, TRANSFER_PROCESS_REQUEST_SCOPE, CATALOG_SCOPE, NEGOTIATION_SCOPE, TRANSFER_PROCESS_SCOPE); + private static final String V4_POLICY_DEFINITION_TYPE = V_4_PREFIX + EDC_POLICY_DEFINITION_TYPE_TERM; + private static String withCxPolicyNsPrefix(String name) { return CX_POLICY_2025_09_NS + name; } @@ -374,6 +379,7 @@ public String name() { @Override public void prepare() { validatorRegistry.register(EDC_POLICY_DEFINITION_TYPE, CxPolicyDefinitionValidator.instance()); + validatorRegistry.register(V4_POLICY_DEFINITION_TYPE, new CxJsonSchemaPolicyDefinitionValidator()); } @Override diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/validator/jsonschema/CxJsonSchemaPolicyDefinitionValidator.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/validator/jsonschema/CxJsonSchemaPolicyDefinitionValidator.java new file mode 100644 index 0000000000..3c1258425d --- /dev/null +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/validator/jsonschema/CxJsonSchemaPolicyDefinitionValidator.java @@ -0,0 +1,52 @@ +/******************************************************************************** + * Copyright (c) 2026 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.policy.cx.validator.jsonschema; + +import jakarta.json.JsonObject; +import org.eclipse.edc.validator.spi.ValidationResult; +import org.eclipse.edc.validator.spi.Validator; + +import static org.eclipse.edc.validator.spi.ValidationResult.failure; +import static org.eclipse.edc.validator.spi.Violation.violation; + +public class CxJsonSchemaPolicyDefinitionValidator implements Validator { + + private static final String POLICY_ATTRIBUTE_NAME = "policy"; + + private final CxJsonSchemaPolicyValidator policyValidator; + + public CxJsonSchemaPolicyDefinitionValidator() { + this.policyValidator = new CxJsonSchemaPolicyValidator(); + } + + @Override + public ValidationResult validate(JsonObject input) { + if (!input.containsKey(POLICY_ATTRIBUTE_NAME)) { + return failure(violation("Attribute '%s' is missing from PolicyDefinition.".formatted(POLICY_ATTRIBUTE_NAME), POLICY_ATTRIBUTE_NAME)); + } + + var policy = input.get(POLICY_ATTRIBUTE_NAME); + if (!(policy instanceof JsonObject)) { + return failure(violation("Attribute '%s' is not a valid JSON object.".formatted(POLICY_ATTRIBUTE_NAME), POLICY_ATTRIBUTE_NAME)); + } + + return policyValidator.validate((JsonObject) policy); + } +} diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/validator/jsonschema/CxJsonSchemaPolicyValidator.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/validator/jsonschema/CxJsonSchemaPolicyValidator.java new file mode 100644 index 0000000000..10d0073480 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/validator/jsonschema/CxJsonSchemaPolicyValidator.java @@ -0,0 +1,76 @@ +/******************************************************************************** + * Copyright (c) 2026 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.policy.cx.validator.jsonschema; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.networknt.schema.Schema; +import com.networknt.schema.SchemaLocation; +import com.networknt.schema.SchemaRegistry; +import com.networknt.schema.dialect.Dialects; +import com.networknt.schema.resource.IriResourceLoader; +import jakarta.json.JsonObject; +import org.eclipse.edc.jsonld.util.JacksonJsonLd; +import org.eclipse.edc.validator.spi.ValidationResult; +import org.eclipse.edc.validator.spi.Validator; +import org.eclipse.edc.validator.spi.Violation; + +import java.util.Map; + +public class CxJsonSchemaPolicyValidator implements Validator { + private static final String CX_POLICY_SCHEMA_PREFIX = "https://w3id.org/catenax/2025/9/policy"; + private static final String CX_POLICY_SCHEMA_LOCATION = "classpath:jsonschema/cx-policy"; + + private static final String DSPACE_2025_SCHEMA_PREFIX = "https://w3id.org/dspace/2025/1/negotiation"; + private static final String DSPACE_2025_SCHEMA_LOCATION = "classpath:jsonschema/dspace"; + + private static final String CX_POLICY_SCHEMA = CX_POLICY_SCHEMA_PREFIX + "/schema/policy-schema.json"; + + private final ObjectMapper objectMapper; + private final Schema schemaValidator; + + private static final Map PREFIX_MAPPINGS = Map.of( + CX_POLICY_SCHEMA_PREFIX, CX_POLICY_SCHEMA_LOCATION, + DSPACE_2025_SCHEMA_PREFIX, DSPACE_2025_SCHEMA_LOCATION + ); + + public CxJsonSchemaPolicyValidator() { + this.objectMapper = JacksonJsonLd.createObjectMapper(); + var schemaRegistry = SchemaRegistry.withDialect(Dialects.getDraft201909(), builder -> builder + .schemaIdResolvers(schemaIdResolvers -> PREFIX_MAPPINGS.forEach(schemaIdResolvers::mapPrefix)) + .resourceLoaders(resourceLoaders -> resourceLoaders.add(IriResourceLoader.getInstance()))); + this.schemaValidator = schemaRegistry.getSchema(SchemaLocation.of(CX_POLICY_SCHEMA)); + } + + @Override + public ValidationResult validate(JsonObject input) { + var node = objectMapper.convertValue(input, JsonNode.class); + var response = schemaValidator.validate(node); + if (response.isEmpty()) { + return ValidationResult.success(); + } + + var violations = response.stream() + .map(error -> Violation.violation(error.getMessage(), error.getInstanceLocation().toString())) + .toList(); + + return ValidationResult.failure(violations); + } +} diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/affiliates-bpnl-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/affiliates-bpnl-constraint-schema.json new file mode 100644 index 0000000000..e00d4383e4 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/affiliates-bpnl-constraint-schema.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "AffiliatesBpnlConstraint", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/AffiliatesBpnlConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/affiliates-bpnl-constraint-schema.json", + "definitions": { + "AffiliatesBpnlConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "AffiliatesBpnl" + }, + "operator": { + "type": "string", + "const": "isAnyOf" + }, + "rightOperand": { + "type":"array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/BpnlRightOperand" + } + } + }, + "additionalProperties": false + }, + "BpnlRightOperand": { + "type": "string", + "pattern": "^BPNL[0-9A-Z]{12}$", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by the Affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing') specified herein, provided that the Data Consumer ensures that such companies and/or its its Affiliated Companies comply with the terms of the Agreement concluded via the Registered Connector (RC).\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use by the companies specified herein ('Sublicensing'), unless the Parties have otherwise agreed on a right to sublicense the Data (either in full or with respect to individual affiliated companies) in the referenced contract ('cx-policy:ContractReference') or have agreed to this separately.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/affiliates-region-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/affiliates-region-constraint-schema.json new file mode 100644 index 0000000000..07cb47eaf5 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/affiliates-region-constraint-schema.json @@ -0,0 +1,83 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "AffiliatesRegionConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/AffiliatesRegionConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/affiliates-region-constraint-schema.json", + "definitions": { + "AffiliatesRegionConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "AffiliatesRegion" + }, + "operator": { + "type": "string", + "const": "isAnyOf" + }, + "rightOperand": { + "type":"array", + "minItems": 1, + "items": { + "anyOf": [ + {"$ref": "#/definitions/RegionAllRightOperand"}, + {"$ref": "#/definitions/RegionEuropeRightOperand"}, + {"$ref": "#/definitions/RegionNorthAmericaRightOperand"}, + {"$ref": "#/definitions/RegionSouthAmericaRightOperand"}, + {"$ref": "#/definitions/RegionAfricaRightOperand"}, + {"$ref": "#/definitions/RegionAsiaRightOperand"}, + {"$ref": "#/definitions/RegionOceaniaRightOperand"}, + {"$ref": "#/definitions/RegionAntarcticaRightOperand"} + ] + } + } + }, + "additionalProperties": false + }, + "RegionAllRightOperand": { + "type": "string", + "const": "cx.region.all:1", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing'), provided that the Data Consumer ensures that its Affiliated Companies comply with the terms of this Agreement concluded via the Registered Connector (RC).\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use to its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies'), unless the Parties have otherwise agreed on a right of sublicensing in the referenced contract (cx-policy:ContractReference).\"}" + }, + "RegionEuropeRightOperand": { + "type": "string", + "const": "cx.region.europe:1", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing'), provided that the Data Consumer ensures that its Affiliated Companies comply with the terms of this Agreement concluded via the Registered Connector (RC). The registered offices of the relevant Affiliated Companies must be located in Europe.\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') that are domiciled in Europe, unless the Parties have otherwise agreed on a right of sublicensing (either in full or with respect to individual Affiliated Companies) in the referenced bilateral contract ('cx-policy:ContractReference') or have agreed to this separately.\"}" + }, + "RegionNorthAmericaRightOperand": { + "type": "string", + "const": "cx.region.northAmerica:1", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing'), provided that the Data Consumer ensures that its Affiliated Companies comply with the terms of this Agreement concluded via the Registered Connector (RC). The registered offices of the relevant Affiliated Companies must be located in North America.\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') that are domiciled in North America, unless the Parties have otherwise agreed on a right of sublicensing (either in full or with respect to individual Affiliated Companies) in the referenced bilateral contract ('cx-policy:ContractReference') or have agreed to this separately.\"}" + }, + "RegionSouthAmericaRightOperand": { + "type": "string", + "const": "cx.region.southAmerica:1", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing'), provided that the Data Consumer ensures that its Affiliated Companies comply with the terms of this Agreement concluded via the Registered Connector (RC). The registered offices of the relevant Affiliated Companies must be located in South America.\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') that are domiciled in South America, unless the Parties have otherwise agreed on a right of sublicensing (either in full or with respect to individual Affiliated Companies) in the referenced bilateral contract ('cx-policy:ContractReference') or have agreed to this separately.\"}" + }, + "RegionAfricaRightOperand": { + "type": "string", + "const": "cx.region.africa:1", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing'), provided that the Data Consumer ensures that its Affiliated Companies comply with the terms of this Agreement concluded via the Registered Connector (RC). The registered offices of the relevant Affiliated Companies must be located in Africa.\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') that are domiciled in Africa, unless the Parties have otherwise agreed on a right of sublicensing (either in full or with respect to individual Affiliated Companies) in the referenced bilateral contract ('cx-policy:ContractReference') or have agreed to this separately.\"}" + }, + "RegionAsiaRightOperand": { + "type": "string", + "const": "cx.region.asia:1", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing'), provided that the Data Consumer ensures that its Affiliated Companies comply with the terms of this Agreement concluded via the Registered Connector (RC). The registered offices of the relevant Affiliated Companies must be located in Asia.\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') that are domiciled in Asia, unless the Parties have otherwise agreed on a right of sublicensing (either in full or with respect to individual Affiliated Companies) in the referenced bilateral contract ('cx-policy:ContractReference') or have agreed to this separately.\"}" + }, + "RegionOceaniaRightOperand": { + "type": "string", + "const": "cx.region.oceania:1", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing'), provided that the Data Consumer ensures that its Affiliated Companies comply with the terms of this Agreement concluded via the Registered Connector (RC). The registered offices of the relevant Affiliated Companies must be located in Oceania.\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') that are domiciled in Oceania, unless the Parties have otherwise agreed on a right of sublicensing (either in full or with respect to individual Affiliated Companies) in the referenced bilateral contract ('cx-policy:ContractReference') or have agreed to this separately.\"}" + }, + "RegionAntarcticaRightOperand": { + "type": "string", + "const": "cx.region.antarctica:1", + "$comment": "{\"permission\":\"The Data Provider permits the Data Consumer to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') ('Sublicensing'), provided that the Data Consumer ensures that its Affiliated Companies comply with the terms of this Agreement concluded via the Registered Connector (RC). The registered offices of the relevant Affiliated Companies must be located in Antarctica.\",\"prohibition\":\"The Data Consumer is not entitled to make the Data available for use by its affiliated companies within the meaning of Section 15 German Stock Corporation Act ('Affiliated Companies') that are domiciled in Antarctica, unless the Parties have otherwise agreed on a right of sublicensing (either in full or with respect to individual Affiliated Companies) in the referenced bilateral contract ('cx-policy:ContractReference') or have agreed to this separately.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/business-partner-group-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/business-partner-group-constraint-schema.json new file mode 100644 index 0000000000..9ea879b34a --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/business-partner-group-constraint-schema.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "BusinessPartnerGroupConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/BusinessPartnerGroupConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/business-partner-group-constraint-schema.json", + "definitions": { + "BusinessPartnerGroupConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "BusinessPartnerGroup" + }, + "operator": { + "type": "string", + "enum": [ + "isAnyOf", + "isNoneOf" + ] + }, + "rightOperand": { + "type":"array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/BusinessPartnerGroupRightOperand" + } + } + }, + "additionalProperties": false + }, + "BusinessPartnerGroupRightOperand": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/business-partner-number-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/business-partner-number-constraint-schema.json new file mode 100644 index 0000000000..b4ae7a64a2 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/business-partner-number-constraint-schema.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "BusinessPartnerNumberConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/BusinessPartnerNumberConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/business-partner-number-constraint-schema.json", + "definitions": { + "BusinessPartnerNumberConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "BusinessPartnerNumber" + }, + "operator": { + "type": "string", + "enum": [ + "isAnyOf", + "isNoneOf" + ] + }, + "rightOperand": { + "type":"array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/BusinessPartnerNumberRightOperand" + } + } + }, + "additionalProperties": false + }, + "BusinessPartnerNumberRightOperand": { + "type": "string", + "pattern": "^BPNL[0-9A-Z]{12}$" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/confidential-information-measures-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/confidential-information-measures-constraint-schema.json new file mode 100644 index 0000000000..3810d0d24c --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/confidential-information-measures-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "ConfidentialInformationMeasuresConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ConfidentialInformationMeasuresConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/confidential-information-measures-constraint-schema.json", + "definitions": { + "ConfidentialInformationMeasuresConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "ConfidentialInformationMeasures" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/ConfidentialityMeasuresRightOperand" + } + }, + "additionalProperties": false + }, + "ConfidentialityMeasuresRightOperand": { + "type": "string", + "const": "cx.confidentiality.measures:1", + "$comment": "{\"permission\":\"The Data Consumer is obliged to take all appropriate technical and organisational measures to protect the Confidential Information of the Data Provider, in order to prevent unauthorised disclosure to third parties. The Data Consumer is also obliged to inform the Data Provider without undue delay about any unauthorised disclosure of Confidential Information.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/confidential-information-sharing-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/confidential-information-sharing-constraint-schema.json new file mode 100644 index 0000000000..491bf5e159 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/confidential-information-sharing-constraint-schema.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "ConfidentialInformationSharingConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ConfidentialInformationSharingConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/confidential-information-sharing-constraint-schema.json", + "definitions": { + "ConfidentialInformationSharingConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "ConfidentialInformationSharing" + }, + "operator": { + "type": "string", + "const": "isAnyOf" + }, + "rightOperand": { + "type": "array", + "minItems": 1, + "items": { + "anyOf": [ + {"$ref": "#/definitions/SharingAffiliatesRightOperand"}, + {"$ref": "#/definitions/SharingManagedLegalEntityRightOperand"} + ] + } + } + }, + "additionalProperties": false + }, + "SharingAffiliatesRightOperand": { + "type": "string", + "const": "cx.sharing.affiliates:1", + "$comment": "{\"permission\":\"The Data Consumer may only disclose Confidential Information to Affiliated Companies if and to the extent that the Data Provider has expressly permitted such disclosure in accordance with the Data Exchange Governance or the cx-policy:affiliates.*. The Data Consumer may only disclose Confidential Information to Affiliated Companies to the extent that the Affiliated Companies and their employees are bound to Confidentiality Obligations at least equivalent to those set forth in this Agreement. Furthermore, access to and use of the relevant Data must be restricted to those employees of the Affiliated Company who require the Data in order to exercise the agreed usage rights ('need to know').\"}" + }, + "SharingManagedLegalEntityRightOperand": { + "type": "string", + "const": "cx.sharing.managedLegalEntity:1", + "$comment": "{\"permission\":\"The Data Consumer may only disclose Confidential Information to those companies for which the Data Consumer acts in an 'is managed by' relationship (within the meaning of the Catena-X Standard 'CX-0074') if and to the extent those companies are expressly listed in cx-policy:managedLegalEntity.*. The Data Consumer may only disclose Confidential Information to those Companies to the extent that those Companies and their employees are bound to Confidentiality Obligations at least equivalent to those set forth in this Agreement. Furthermore, access to and use of the relevant Data must be restricted to those employees of the Company who require the Data in order to exercise the agreed usage rights ('need to know').\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/contract-reference-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/contract-reference-constraint-schema.json new file mode 100644 index 0000000000..3179c1f733 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/contract-reference-constraint-schema.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "ContractReferenceConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ContractReferenceConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/contract-reference-constraint-schema.json", + "definitions": { + "ContractReferenceConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "ContractReference" + }, + "operator": { + "type": "string", + "const": "isAllOf" + }, + "rightOperand": { + "type":"array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/ContractReferenceRightOperand" + } + } + }, + "additionalProperties": false + }, + "ContractReferenceRightOperand": { + "type": "string", + "$comment": "{\"permission\":\"Data Provider and Data Consumer are free to reference an existing, individual contract as a basis of the Agreement concluded via the Registered Connector (RC). This can be a framework agreement or a very specific contract. The rightOperand value for this constraint can be a free to choose reference under which both parties are able to identify their contract. The reference does not have to have a version number.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/contract-termination-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/contract-termination-constraint-schema.json new file mode 100644 index 0000000000..4bcfc40078 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/contract-termination-constraint-schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "ContractTerminationConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ContractTerminationConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/contract-termination-constraint-schema.json", + "definitions": { + "ContractTerminationConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "ContractTermination" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "oneOf": [ + {"$ref": "#/definitions/DataDeletionRightOperand"}, + {"$ref": "#/definitions/DataKeepingRightOperand"} + ] + } + }, + "additionalProperties": false + }, + "DataDeletionRightOperand": { + "type": "string", + "const": "cx.data.deletion:1", + "$comment": "{\"permission\":\"Upon expiry of the period of use (in accordance with cx-policy:DataUsageEnd) as well as in the event of termination, the Data Consumer shall be obliged to delete the Data (including all copies in backup systems that can be deleted with reasonable effort) from all systems and storage media and, upon request, confirm this to the Data Provider in text form. The foregoing obligation shall apply accordingly to the extent that the Data Consumer is permitted to provide the data to Affiliated Companies (in accordance with cx-policy:affiliates.*) or to companies for which the Data Consumer acts in an 'is managed by' relationship (within the meaning of the Catena-X Standard CX-0076) (in accordance with cx-policy:contractingCompany.*). The Data Consumer is entitled to make and retain a copy of the Data for as long as necessary to safeguard legitimate interests vis-à-vis the Data Provider - particularly for the purpose of demonstrating breaches of contractual obligations arising from the provision of the Data.\"}" + }, + "DataKeepingRightOperand": { + "type": "string", + "const": "cx.data.keeping:1", + "$comment": "{\"permission\":\"Upon expiry of the period of use (in accordance with cx-policy:dataUsageEnd) as well as in the event of termination, the Data Consumer shall not be obliged to delete the Data (including all copies in backup systems that can be deleted with reasonable effort) from all systems and storage media. The foregoing shall apply accordingly to the extent that the Data Consumer is permitted to provide the Data to Affiliated Companies (in accordance with leftOperand cx-policy:affiliates.*) or to companies for which the Data Consumer acts in an 'is managed by' relationship (within the meaning of the Catena-X Standard CX-0076) (in accordance with cx-policy:contractingCompany.*). In such case, the Data Consumer shall be entitled to continue using the Data exclusively within the scope of the purpose limitation and other conditions of the contract. The Data Consumer shall take all necessary measures to protect the Data against unauthorised access by third parties.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-frequency-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-frequency-constraint-schema.json new file mode 100644 index 0000000000..1a6566a6e2 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-frequency-constraint-schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "DataFrequencyConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/DataFrequencyConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/data-frequency-constraint-schema.json", + "definitions": { + "DataFrequencyConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "DataFrequency" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "oneOf": [ + {"$ref": "#/definitions/DataFrequencyOnceRightOperand"}, + {"$ref": "#/definitions/DataFrequencyUnlimitedRightOperand"} + ] + } + }, + "additionalProperties": false + }, + "DataFrequencyOnceRightOperand": { + "type": "string", + "const": "cx.dataFrequency.once:1", + "$comment": "{\"permission\":\"This Agreement concluded via the Registered Connector (RC). applies both to a one-time, time-limited data exchange as well as to sequential data exchanges under similar conditions, potentially also in varying quantities (Data as a Service).\"}" + }, + "DataFrequencyUnlimitedRightOperand": { + "type": "string", + "const": "cx.dataFrequency.unlimited:1", + "$comment": "{\"permission\":\"This Agreement concluded via the Registered Connector (RC). applies to the multiple or repeated exchange of similar Data at different times and in different quantities within the scope of the selected Use Case.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-provisioning-end-date-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-provisioning-end-date-constraint-schema.json new file mode 100644 index 0000000000..25bb6d320e --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-provisioning-end-date-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "DataProvisioningEndDateConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/DataProvisioningEndDateConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/data-provisioning-end-date-constraint-schema.json", + "definitions": { + "DataProvisioningEndDateConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "DataProvisioningEndDate" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/DataProvisioningEndDateRightOperand" + } + }, + "additionalProperties": false + }, + "DataProvisioningEndDateRightOperand": { + "type": "string", + "pattern": "^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2}))$", + "$comment": "{\"obligation\":\"The Data Provider shall make the Data available for a limited period until the end date specified herein, commencing from the second the Agreement is concluded via the Registered Connector (RC).\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-provisioning-end-duration-days-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-provisioning-end-duration-days-constraint-schema.json new file mode 100644 index 0000000000..ea53f046c8 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-provisioning-end-duration-days-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "DataProvisioningEndDurationDaysConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/DataProvisioningEndDurationDaysConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/data-provisioning-end-duration-days-constraint-schema.json", + "definitions": { + "DataProvisioningEndDurationDaysConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "DataProvisioningEndDurationDays" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/DataProvisioningEndDurationDaysRightOperand" + } + }, + "additionalProperties": false + }, + "DataProvisioningEndDurationDaysRightOperand": { + "type": "string", + "pattern": "^[1-9][0-9]*$", + "$comment": "{\"obligation\":\"The Data Provider shall make the Data available for the period specified herein in days, commencing from the second the Agreement is concluded via the Registered Connector (RC).\"}" + } + } +} diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-date-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-date-constraint-schema.json new file mode 100644 index 0000000000..8b6d03419d --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-date-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "DataUsageEndDateConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/DataUsageEndDateConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/data-usage-end-date-constraint-schema.json", + "definitions": { + "DataUsageEndDateConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "DataUsageEndDate" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/DataUsageEndDateRightOperand" + } + }, + "additionalProperties": false + }, + "DataUsageEndDateRightOperand": { + "type": "string", + "pattern": "^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2}))$", + "$comment": "{\"permission\":\"The Data Provider shall make the Data available with a usage period permitted until the end date specified herein, in accordance with the usage conditions specified in cx-policy:UsagePurpose, commencing from the second the Agreement is concluded via the Registered Connector (RC). Upon expiry of the usage period, the Data Consumer shall no longer be entitled to use the Data and shall delete the Data in order to prevent any further Use, unless the Data Consumer has received the same Data under another still valid contract. The Agreement shall terminate upon expiry of the usage period of the Data without the need for a separate notice of termination.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-definition-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-definition-constraint-schema.json new file mode 100644 index 0000000000..1545c154da --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-definition-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "DataUsageEndDefinitionConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/DataUsageEndDefinitionConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/data-usage-end-definition-constraint-schema.json", + "definitions": { + "DataUsageEndDefinitionConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "DataUsageEndDefinition" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/DataUsageEndDefinitionRightOperand" + } + }, + "additionalProperties": false + }, + "DataUsageEndDefinitionRightOperand": { + "type": "string", + "const": "cx.dataUsageEnd.unlimited:1", + "$comment": "{\"permission\":\"The Data Provider shall make the Data available for an unlimited period of use in accordance with the usage conditions specified in cx-policy:UsagePurpose, commencing from the second the Agreement is concluded via the Registered Connector (RC).\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-duration-days-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-duration-days-constraint-schema.json new file mode 100644 index 0000000000..ab640c74c5 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/data-usage-end-duration-days-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "DataUsageEndDurationDaysConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/DataUsageEndDurationDaysConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/data-usage-end-duration-days-constraint-schema.json", + "definitions": { + "DataUsageEndDurationDaysConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "DataUsageEndDurationDays" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/DataUsageEndDurationDaysRightOperand" + } + }, + "additionalProperties": false + }, + "DataUsageEndDurationDaysRightOperand": { + "type": "string", + "pattern": "^[1-9][0-9]*$", + "$comment": "{\"permission\":\"The Data Provider shall make the Data available for the usage period specified herein, measured in days, in accordance with the usage conditions set out in cx-policy:UsagePurpose, commencing from the moment of concluding the Agreement via the Registered Connector (RC). Upon expiry of the permitted usage period, the Data Consumer shall no longer be entitled to use the Data, and shall delete the Data from all systems and storage media in order to prevent any further use, unless the Data Consumer has received the same Data under another valid contract. The Agreement shall terminate automatically upon expiry of the usage period for the Data, without the need for a separate notice of termination.\"}" + } + } +} diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/exclusive-usage-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/exclusive-usage-constraint-schema.json new file mode 100644 index 0000000000..f4d10953f5 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/exclusive-usage-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "ExclusiveUsageConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ExclusiveUsageConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/exclusive-usage-constraint-schema.json", + "definitions": { + "ExclusiveUsageConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "ExclusiveUsage" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/ExclusiveUsageDataConsumerRightOperand" + } + }, + "additionalProperties": false + }, + "ExclusiveUsageDataConsumerRightOperand": { + "type": "string", + "const": "cx.exclusiveUsage.dataConsumer:1", + "$comment": "{\"permission\":\"The Data Consumer has the exclusive right to use the Data within the scope of the agreed purposes (cx-policy:UsagePurpose). The Data Provider’s right to use the Data it has provided for its own internal purposes remains unaffected.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/framework-agreement-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/framework-agreement-constraint-schema.json new file mode 100644 index 0000000000..573db61734 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/framework-agreement-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "FrameworkAgreementConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/FrameworkAgreementConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/framework-agreement-constraint-schema.json", + "definitions": { + "FrameworkAgreementConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "FrameworkAgreement" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/DataExchangeGovernanceRightOperand" + } + }, + "additionalProperties": false + }, + "DataExchangeGovernanceRightOperand": { + "type": "string", + "const": "DataExchangeGovernance:1.0", + "$comment": "{\"permission\":\"Data Provider and Data Consumer agree to the Data Exchange Governance published by the Catena-X Automotive Network e.V. (Association) as basis for this Agreement concluded via the Registered Connector (RC). The Data Exchange Governance can be found here: https://catenax-ev.github.io/docs/regulatory-framework/20000ft/data-exchange-governance after CX-Saturn has been released. The subject matter of the Agreement concluded via the RC is the provision of the Data for a limited period of one (1) year (unless otherwise agreed in [dataProvisioningEndDate](https://w3id.org/catenax/2025/9/policy/data-provisioning-end-date-constraint-schema.json) or [dataProvisioningEndDurationDays](https://w3id.org/catenax/2025/9/policy/data-provisioning-end-duration-days-constraint-schema.json)and granting a right to use the Data for a period of one (1) year (unless agreed otherwise in [dataUsageEndDate](https://w3id.org/catenax/2025/9/policy/data-usage-end-date-constraint-schema.json) or [dataUsageEndDurationDays](https://w3id.org/catenax/2025/9/policy/data-usage-end-duration-days-constraint-schema.json) or open-ended [DataUsageEndUnlimited](https://w3id.org/catenax/2025/9/policy/data-usage-end-definition-constraint-schema.json)). The provision of the Data shall be effected via the API specified by the dataset attribute dct:type. The Agreement concluded via the RC covers only the exchange of Data effected on the basis of the API version (as specified in the dataset attribute base-URL), the Asset-Version (dataset attribute cx-common:version), and the Aspect Model Version as applicable at the time of concluding the Agreement. Unless agreed otherwise in [VersionChanges](https://w3id.org/catenax/2025/9/policy/version-changes-constraint-schema.json), the Agreement concluded via the RC must be renegotiated in the event of any change to at least one of these versions. Unless otherwise agreed between the Parties within the Agreement concluded via the RC (in accordance with [UsagePurpose](https://w3id.org/catenax/2025/9/policy/usage-purpose-constraint-schema.json), the Data Provider grants the Data Consumer a non-exclusive right, limited in time to the duration of this contract (in accordance with [dataUsageEndDate](https://w3id.org/catenax/2025/9/policy/data-usage-end-date-constraint-schema.json) or [dataUsageEndDurationDays](https://w3id.org/catenax/2025/9/policy/data-usage-end-duration-days-constraint-schema.json) or open-ended [DataUsageEndUnlimited](https://w3id.org/catenax/2025/9/policy/data-usage-end-definition-constraint-schema.json)), to use the Data in accordance with the Contractual Usage Purposes (in accordance with [Usage Purpose](https://w3id.org/catenax/2025/9/policy/usage-purpose-constraint-schema.json)).\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/jurisdiction-location-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/jurisdiction-location-constraint-schema.json new file mode 100644 index 0000000000..33db191be5 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/jurisdiction-location-constraint-schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "JurisdictionLocationConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/JurisdictionLocationConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/jurisdiction-location-constraint-schema.json", + "definitions": { + "JurisdictionLocationConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "JurisdictionLocation" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/LocationStringRightOperand" + } + }, + "additionalProperties": false + }, + "LocationStringRightOperand": { + "type": "string", + "$comment": "{\"permission\":\"The exclusive venue for all disputes arising from the Agreement concluded via the Registered Connector (RC) shall be at the competent court at the location specified herein.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/jurisdiction-location-reference-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/jurisdiction-location-reference-constraint-schema.json new file mode 100644 index 0000000000..00dfe5580e --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/jurisdiction-location-reference-constraint-schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "JurisdictionLocationReferenceConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/JurisdictionLocationReferenceConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/jurisdiction-location-reference-constraint-schema.json", + "definitions": { + "JurisdictionLocationReferenceConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "JurisdictionLocationReference" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "oneOf": [ + {"$ref": "#/definitions/LocationDataConsumerRightOperand"}, + {"$ref": "#/definitions/LocationContractReferenceRightOperand"} + ] + } + }, + "additionalProperties": false + }, + "LocationDataConsumerRightOperand": { + "type": "string", + "const": "cx.location.dataConsumer:1", + "$comment": "{\"permission\":\"The exclusive venue for all disputes arising from the contract concluded via the Registered Connector (RC) shall be at the competent court at the registered office of the Data Consumer.\"}" + }, + "LocationContractReferenceRightOperand": { + "type": "string", + "const": "cx.location.contractReference:1", + "$comment": "{\"permission\":\"The exclusive venue for all disputes arising from the Agreement concluded via the Registered Connector (RC) shall correspond to the venue specified in the referenced contract (as referenced in cx-policy:ContractReference).\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/liability-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/liability-constraint-schema.json new file mode 100644 index 0000000000..2bb19c540a --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/liability-constraint-schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "LiabilityConstraintConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/LiabilityConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/liability-constraint-schema.json", + "definitions": { + "LiabilityConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "Liability" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "oneOf": [ + {"$ref": "#/definitions/GrossNegligenceRightOperand"}, + {"$ref": "#/definitions/SlightNegligenceRightOperand"} + ] + } + }, + "additionalProperties": false + }, + "GrossNegligenceRightOperand": { + "type": "string", + "const": "cx.grossNegligence:1", + "$comment": "{\"permission\":\"The Data Provider's liability is limited to intent and gross negligence. The same applies in regard to the Data Provider's liability for its legal representatives, employees and authorised representatives.\"}" + }, + "SlightNegligenceRightOperand": { + "type": "string", + "const": "cx.slightNegligence:1", + "$comment": "{\"permission\":\"The liability of the Data Provider in cases of ordinary negligence shall be limited to x, as individually agreed by the Parties in the referenced bilateral agreement (cx-policy:ContractReference). The foregoing limitation of liability shall not apply in the event of mandatory statutory liability (in particular under the German Product Liability Act), nor in the event of the assumption of a guarantee or for any culpably caused bodily injury.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/membership-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/membership-constraint-schema.json new file mode 100644 index 0000000000..9ab7a38f7b --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/membership-constraint-schema.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "MembershipConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/MembershipConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/membership-constraint-schema.json", + "definitions": { + "MembershipConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "Membership" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "type": "string", + "const": "active" + } + }, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/precedence-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/precedence-constraint-schema.json new file mode 100644 index 0000000000..5ffa8aed55 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/precedence-constraint-schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "PrecedenceConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/PrecedenceConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/precedence-constraint-schema.json", + "definitions": { + "PrecedenceConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "Precedence" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "oneOf": [ + {"$ref": "#/definitions/PrecedenceContractReferenceRightOperand"}, + {"$ref": "#/definitions/PrecedenceRcAgreementRightOperand"} + ] + } + }, + "additionalProperties": false + }, + "PrecedenceContractReferenceRightOperand": { + "type": "string", + "const": "cx.precedence.contractReference:1", + "$comment": "{\"permission\":\"The Parties are free to agree on additional provisions in a separately referenced contract, in addition to the arrangements made via the Registered Connector (RC) Process (referenced in leftOperand: contractReference). In the event of any conflict between the provisions agreed via the RC Process and those of the referenced contract, the provisions of the contract shall take precedence.\"}" + }, + "PrecedenceRcAgreementRightOperand": { + "type": "string", + "const": "cx.precedence.rcAgreement:1", + "$comment": "{\"permission\":\"The Parties are free to agree on additional provisions in a referenced contract (as referenced in leftOperand: contractReference) in addition to the arrangements agreed via the Registered Connector (RC) Process. In such case, the provisions agreed via the RC Process shall take precedence over the provisions of the referenced contract.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/atomic-constraint-schemas.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/atomic-constraint-schemas.json new file mode 100644 index 0000000000..5166dd49cb --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/atomic-constraint-schemas.json @@ -0,0 +1,174 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "AtomicCatenaXConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/AtomicCatenaXConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/schema/atomic-constraint-schemas.json", + "definitions": { + "AtomicCatenaXConstraint": { + "anyOf": [ + { + "$ref": "#/definitions/AtomicObligationConstraint" + }, + { + "$ref": "#/definitions/AtomicPermissionConstraint" + }, + { + "$ref": "#/definitions/AtomicProhibitionConstraint" + } + ] + }, + "AtomicPermissionConstraint": { + "allOf": [ + { + "$ref": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json#/definitions/AtomicConstraint" + }, + { + "anyOf": [ + { + "$ref": "#/definitions/AtomicAccessPermissionConstraint" + }, + { + "$ref": "#/definitions/AtomicUsagePermissionConstraint" + } + ] + } + ] + }, + "AtomicAccessPermissionConstraint": { + "anyOf": [ + { + "$ref": "https://w3id.org/catenax/2025/9/policy/framework-agreement-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/membership-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/business-partner-number-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/business-partner-group-constraint-schema.json" + } + ] + }, + "AtomicUsagePermissionConstraint": { + "anyOf": [ + { + "$ref": "https://w3id.org/catenax/2025/9/policy/framework-agreement-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/membership-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/usage-purpose-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/contract-reference-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/affiliates-region-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/affiliates-bpnl-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-frequency-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/version-changes-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/contract-termination-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/confidential-information-measures-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/confidential-information-sharing-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/exclusive-usage-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/warranty-constraint-schema.json" + }, + { + "oneOf": [ + { + "$ref": "https://w3id.org/catenax/2025/9/policy/warranty-duration-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/warranty-definition-constraint-schema.json" + } + ] + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/liability-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/jurisdiction-location-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/jurisdiction-location-reference-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/precedence-constraint-schema.json" + }, + { + "oneOf": [ + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-usage-end-duration-days-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-usage-end-date-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-usage-end-definition-constraint-schema.json" + } + ] + } + ] + }, + "AtomicObligationConstraint": { + "allOf": [ + { + "$ref": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json#/definitions/AtomicConstraint" + }, + { + "oneOf": [ + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-provisioning-end-duration-days-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-provisioning-end-date-constraint-schema.json" + } + ] + } + ] + }, + "AtomicProhibitionConstraint": { + "allOf": [ + { + "$ref": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json#/definitions/AtomicConstraint" + }, + { + "anyOf": [ + { + "$ref": "https://w3id.org/catenax/2025/9/policy/affiliates-region-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/affiliates-bpnl-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/usage-restriction-constraint-schema.json" + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/context-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/context-schema.json new file mode 100644 index 0000000000..b77fb468f5 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/context-schema.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "ContextSchema", + "type": "array", + "items": { + "type": "string" + }, + "allOf": [ + { + "$ref": "#/definitions/ContextSchema" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/schema/context-schema.json", + "definitions": { + "ContextSchema": { + "type": "array", + "items": { + "type": "string", + "items": { + "type": "string" + } + }, + "contains": { + "const": "https://w3id.org/catenax/2025/9/policy/context.jsonld" + } + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/policy-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/policy-schema.json new file mode 100644 index 0000000000..87ac1f8f3d --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/schema/policy-schema.json @@ -0,0 +1,300 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "CatenaXPolicySchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/CatenaXPolicy" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/schema/policy-schema.json", + "definitions": { + "CatenaXPolicy": { + "allOf": [ + { + "$ref": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json#/definitions/PolicyClass" + }, + { + "anyOf": [ + { + "$ref": "#/definitions/AccessPolicy" + }, + { + "$ref": "#/definitions/UsagePolicy" + } + ] + } + ] + }, + "AccessPolicy": { + "type": "object", + "properties": { + "permission": { + "type": "array", + "items": { + "allOf": [ + { + "$ref": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json#/definitions/Rule" + }, + { + "properties": { + "action": { + "type": "string", + "const": "access" + }, + "constraint": { + "type": "array", + "items": { + "$ref": "#/definitions/AccessPermissionConstraint" + }, + "minItems": 1, + "maxItems": 1 + } + } + } + ] + }, + "minItems": 1, + "maxItems": 1 + }, + "prohibition": { + "type": "array", + "maxItems": 0 + }, + "obligation": { + "type": "array", + "maxItems": 0 + } + } + }, + "AccessPermissionConstraint": { + "type": "object", + "oneOf": [ + { + "$ref": "#/definitions/AccessPermissionLogicalConstraint" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/schema/atomic-constraint-schemas.json#/definitions/AtomicAccessPermissionConstraint" + } + ] + }, + "AccessPermissionLogicalConstraint": { + "type": "object", + "properties": { + "and": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/AccessPermissionConstraint" + } + } + }, + "required": [ + "and" + ] + }, + "UsagePolicy": { + "type": "object", + "properties": { + "permission": { + "type": "array", + "items": { + "allOf": [ + { + "$ref": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json#/definitions/Rule" + }, + { + "properties": { + "action": { + "type": "string", + "const": "use" + }, + "constraint": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "$ref": "#/definitions/UsagePermissionConstraint" + } + } + }, + "required": [ + "constraint" + ] + } + ] + }, + "minItems": 1, + "maxItems": 1 + }, + "prohibition": { + "type": "array", + "items": { + "allOf": [ + { + "$ref": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json#/definitions/Rule" + }, + { + "properties": { + "action": { + "type": "string", + "const": "use" + }, + "constraint": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "$ref": "#/definitions/UsageProhibitionConstraint" + } + } + }, + "required": [ + "constraint" + ] + } + ] + }, + "minItems": 1, + "maxItems": 1 + }, + "obligation": { + "type": "array", + "items": { + "allOf": [ + { + "$ref": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json#/definitions/Rule" + }, + { + "properties": { + "action": { + "type": "string", + "const": "use" + }, + "constraint": { + "type": "array", + "minItems": 1, + "maxItems": 1, + "items": { + "$ref": "https://w3id.org/catenax/2025/9/policy/schema/atomic-constraint-schemas.json#/definitions/AtomicObligationConstraint" + } + } + }, + "required": [ + "constraint" + ] + } + ] + }, + "minItems": 1, + "maxItems": 1 + } + }, + "anyOf": [ + { + "required": [ + "permission" + ] + }, + { + "required": [ + "prohibition" + ] + }, + { + "required": [ + "obligation" + ] + } + ] + }, + "UsagePermissionConstraint": { + "type": "object", + "oneOf": [ + { + "$ref": "#/definitions/UsagePermissionLogicalConstraint" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/schema/atomic-constraint-schemas.json#/definitions/AtomicUsagePermissionConstraint" + } + ] + }, + "UsagePermissionLogicalConstraint": { + "type": "object", + "properties": { + "and": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "$ref": "#/definitions/UsagePermissionConstraint" + }, + "allOf": [ + { + "description": "Rule 1: Maximum ONE Warranty constraint allowed", + "contains": { + "anyOf": [ + { + "$ref": "https://w3id.org/catenax/2025/9/policy/warranty-duration-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/warranty-definition-constraint-schema.json" + } + ] + }, + "maxContains": 1, + "minContains": 0 + }, + { + "description": "Rule 2: Maximum ONE Data Usage End constraint allowed", + "contains": { + "anyOf": [ + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-usage-end-duration-days-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-usage-end-date-constraint-schema.json" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/data-usage-end-definition-constraint-schema.json" + } + ] + }, + "maxContains": 1, + "minContains": 0 + } + ] + } + }, + "required": [ + "and" + ] + }, + "UsageProhibitionConstraint": { + "type": "object", + "oneOf": [ + { + "$ref": "#/definitions/UsageProhibitionLogicalConstraint" + }, + { + "$ref": "https://w3id.org/catenax/2025/9/policy/schema/atomic-constraint-schemas.json#/definitions/AtomicProhibitionConstraint" + } + ] + }, + "UsageProhibitionLogicalConstraint": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "$ref": "#/definitions/UsageProhibitionConstraint" + } + } + }, + "required": [ + "and" + ] + } + } +} diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/usage-purpose-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/usage-purpose-constraint-schema.json new file mode 100644 index 0000000000..375bdc1a29 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/usage-purpose-constraint-schema.json @@ -0,0 +1,237 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "UsagePurposeConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/UsagePurposeConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/usage-purpose-constraint-schema.json", + "definitions": { + "UsagePurposeConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "UsagePurpose" + }, + "operator": { + "type": "string", + "const": "isAnyOf" + }, + "rightOperand": { + "type":"array", + "minItems": 1, + "items": { + "anyOf": [ + {"$ref": "#/definitions/CoreLegalRequirementForThirdPartyRightOperand"}, + {"$ref": "#/definitions/CoreIndustrycoreRightOperand"}, + {"$ref": "#/definitions/CoreQualityNotificationsRightOperand"}, + {"$ref": "#/definitions/CoreDigitalTwinRegistry"}, + {"$ref": "#/definitions/PcfBaseRightOperand"}, + {"$ref": "#/definitions/QualityBaseRightOperand"}, + {"$ref": "#/definitions/DcmBaseRightOperand"}, + {"$ref": "#/definitions/PurisBaseRightOperand"}, + {"$ref": "#/definitions/CircularDppRightOperand"}, + {"$ref": "#/definitions/CircularSmcRightOperand"}, + {"$ref": "#/definitions/CircularMarketplaceRightOperand"}, + {"$ref": "#/definitions/CircularMaterialaccountingRightOperand"}, + {"$ref": "#/definitions/BpdmGateUploadRightOperand"}, + {"$ref": "#/definitions/BpdmGateDownloadRightOperand"}, + {"$ref": "#/definitions/BpdmPoolRightOperand"}, + {"$ref": "#/definitions/BpdmVasDataqualityUploadRightOperand"}, + {"$ref": "#/definitions/BpdmVasDataqualityDownloadRightOperand"}, + {"$ref": "#/definitions/BpdmVasCountryrisk"}, + {"$ref": "#/definitions/BpdmVasBdvUploadRightOperand"}, + {"$ref": "#/definitions/BpdmVasFpdUploadRightOperand"}, + {"$ref": "#/definitions/BpdmVasFpdDownloadRightOperand"}, + {"$ref": "#/definitions/BpdmVasSwdUploadRightOperand"}, + {"$ref": "#/definitions/BpdmVasSwdDownloadRightOperand"}, + {"$ref": "#/definitions/BpdmVasNpsUploadRightOperand"}, + {"$ref": "#/definitions/BpdmVasNpsDownloadRightOperand"}, + {"$ref": "#/definitions/CcmBaseRightOperand"}, + {"$ref": "#/definitions/BpdmPoolAllRightOperand"}, + {"$ref": "#/definitions/LogisticsBaseRightOperand"}, + {"$ref": "#/definitions/EngineeringBaseRightOperand"}, + {"$ref": "#/definitions/MaterialaccountingBaseRightOperand"}, + {"$ref": "#/definitions/EsdscomBaseRightOperand"}, + {"$ref": "#/definitions/EcuBaseRightOperand"}, + {"$ref": "#/definitions/UsagePurposeIndividualRightOperand"} + ] + } + } + }, + "additionalProperties": false + }, + "CoreLegalRequirementForThirdPartyRightOperand": { + "type": "string", + "const": "cx.core.legalRequirementForThirdparty:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: facilitating compliance with mandatory regulatory requirements for tracking and reporting battery cells, modules & high-voltage batteries.\",\"additionalInformation\":\"Typically used for: Traction Battery Code\"}" + }, + "CoreIndustrycoreRightOperand": { + "type": "string", + "const": "cx.core.industrycore:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: Establishing a digital representation of the automotive supply chain to enable a component specific data exchange.\",\"additionalInformation\":\"Typically used for: SerialPart, Batch, JustInSequencePart,SingleLevelBomAsBuilt, PartAsPlanned, SingleLevelBomAsPlanned, PartSiteInformationAsPlanned, UniqueIDPushAPI\"}" + }, + "CoreQualityNotificationsRightOperand": { + "type": "string", + "const": "cx.core.qualityNotifications:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: quality analyses to identify and select affected components and to send quality notifications to affected customers or suppliers.\",\"additionalInformation\":\"Typically used for: Notification API\"}" + }, + "CoreDigitalTwinRegistry": { + "type": "string", + "const": "cx.core.digitalTwinRegistry:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: Identifying data offers of submodels within the Catena-X ecosystem.\",\"additionalInformation\":\"Typically used for: Digital Twin Registry Asset\"}" + }, + "PcfBaseRightOperand": { + "type": "string", + "const": "cx.pcf.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) sending and receiving product-specific CO2 data and related functionalities such as (but not limited to) certificate exchange and notifications, (ii) conducting plausibility checks and validation measures, (iii) calculating aggregated PCFs of Data Consumer (including calculations operated by a technical service provider that (a) is certified for Catena-X, (b) is not authorized to evaluate data beyond such calculation and (c) provides calculations exclusively for Data Consumer's own purposes.\",\"additionalInformation\":\"Typically used for: PCF Model, PCF Exchange API\"}" + }, + "QualityBaseRightOperand": { + "type": "string", + "const": "cx.quality.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) early identification of anomalies in the use of the product, (ii) collaborative root-cause analysis of a problem / error and determining corrective action, (iii) component tracing to optimize technical actions (in combination with use case Traceability), (iv) confirming corrective action, (v) preventive field observation to detect anomalies, (vi) processing notifications of quality alerts (supply chain bottom-up) and quality investigations (supply chain top-down) (possibly in combination with the use case Traceability).\",\"additionalInformation\":\"Typically used for: Fleet Vehicles, Quality Task, QualityTaskAttachment, PartsAnalysis, ManufacturedPartsQInformation, FleetDiagnosticData, FleetClaim\"}" + }, + "DcmBaseRightOperand": { + "type": "string", + "const": "cx.dcm.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) sending and receiving product-specific demand and capacity data, as well as the associated product functionalities, (ii) early identification of imbalances resulting from demand and capacity comparison, (iii) sending and receiving messages and notifications related to imbalances and to exchanged demand and capacity data, (iv) initiate a collaborative approach to solve imbalances.\",\"additionalInformation\":\"Typically used for: Material Demand, WeekBasedCapacityGroup, IdBasedRequestForUpdate, IdBasedComment\"}" + }, + "PurisBaseRightOperand": { + "type": "string", + "const": "cx.puris.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: optimizing processes, which includes, without limitation, regular exchange of data to prevent and/or solve shortages in the supply chain, conducting plausibility checks against other sources and/or collecting information to facilitate sound decision making, all of the above in the context of predictive unit real-time information relating to production and/or logistics.\",\"additionalInformation\":\"Typically used for: Item Stock, Short-Term Material Demand, Planned Production Output, Delivery Information\"}" + }, + "CircularDppRightOperand": { + "type": "string", + "const": "cx.circular.dpp:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in accordance to those applicable public legal regulation directly requiring digital product passports or affecting the contents or handling of digital product passports.\",\"additionalInformation\":\"Typically used for: Digital Product Pass, Battery Pass\"}" + }, + "CircularSmcRightOperand": { + "type": "string", + "const": "cx.circular.smc:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data about secondary material content (SMC) in line with the following purpose: optimize the SMC-usage.\",\"additionalInformation\":\"Typically used for: SMC-Calculated, SMC-Verifiable\"}" + }, + "CircularMarketplaceRightOperand": { + "type": "string", + "const": "cx.circular.marketplace:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: buy, sell and/or procure parts and materials.\",\"additionalInformation\":\"Typically used for: Market Place Offer\"}" + }, + "CircularMaterialaccountingRightOperand": { + "type": "string", + "const": "cx.circular.materialaccounting:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) display, process, analysis, correlate, modify and amend data, (ii) for (e.g. enablement of) chain of custody processes and commercial transaction related thereto and allocation of material to parts to the supply chain.\"}" + }, + "BpdmGateUploadRightOperand": { + "type": "string", + "const": "cx.bpdm.gate.upload:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: verifying, curating and enriching the Data to create a record of basic information about all entities with a BPN in the Catena-X data space accessible to all participants (Golden Record) and for early warning services (Value Added Services, VASs).\",\"additionalInformation\":\"Typically used for: Gate Data Model\"}" + }, + "BpdmGateDownloadRightOperand": { + "type": "string", + "const": "cx.bpdm.gate.download:1", + "$comment": "{\"permission\":\"The Data Consumer may use the basic information about entities with a BPN in the Catena-X data space provided by the Core Service B Provider for any of the following purposes: (i) identifying counterparty, (ii) usage in Value Added Services (VASs).\",\"additionalInformation\":\"Typically used for: Gate Data Model\"}" + }, + "BpdmPoolRightOperand": { + "type": "string", + "const": "cx.bpdm.pool:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) identifying participants within the Catena-X data space, (ii) identifying counterparty (iii), usage in information processes, (iv) invitation of additional participants into the Catena-X data space, (v) usage in Value Added Services (VASs), \",\"additionalInformation\":\"Typically used for: Pool Data Models\"}" + }, + "BpdmVasCountryrisk": { + "type": "string", + "const": "cx.bpdm.vas.countryrisk:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: screening participants's business data to identify risks when collaborating with a new/existing business partner according to official or company-specific country risk assessments.\",\"additionalInformation\":\"Typically used for: Country Risk Data Model, Gate Data Model, Pool Data Models\"}" + }, + "BpdmVasDataqualityUploadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.dataquality.upload:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) assessing Data Provider's data quality, (ii) creating benchmarks for future screenings of other participants' data to fulfill the goals of the Data Quality Dashboard application.\",\"additionalInformation\":\"Typically used for: Business Partner Data Model\"}" + }, + "BpdmVasDataqualityDownloadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.dataquality.download:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: Assessing quality of own data.\",\"additionalInformation\":\"Typically used for: Data Quality Dashboard Data Model\"}" + }, + "BpdmVasBdvUploadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.bdv.upload:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: screening relevant Data Provider's submitted bank data to verify Data Provider's bank data.\",\"additionalInformation\":\"Typically used for: Gate Data Model, Bank Data Verification Data Model\"}" + }, + "BpdmVasBdvDownloadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.bdv.download:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: verifying Data Consumer's submitted bank data.\",\"additionalInformation\":\"Typically used for: Bank Data Verification Data Model\"}" + }, + "BpdmVasFpdUploadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.fpd.upload:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: screening Data Provider's submitted business partner data to assess occurrence of fraud.\",\"additionalInformation\":\"Typically used for: Fraud Prevention Data Model\"}" + }, + "BpdmVasFpdDownloadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.fpd.download:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: Assessing fraud risks in transactions with another participant.\",\"additionalInformation\":\"Typically used for: Fraud Prevention Data Model\"}" + }, + "BpdmVasSwdUploadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.swd.upload:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: screening Data Provider's submitted beneficial ownership data to assess trade compliance.\",\"additionalInformation\":\"Typically used for: Gate Data Model\"}" + }, + "BpdmVasSwdDownloadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.swd.download:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: assessing trade sanction risks in transactions with another participant.\",\"additionalInformation\":\"Typically used for: Sanction Party Watch List Dashboard Data Model\"}" + }, + "BpdmVasNpsUploadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.nps.upload:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: verifying Data Provider's submitted Business Partner Data against Natural Person data entries.\",\"additionalInformation\":\"Typically used for: Gate Data Model\"}" + }, + "BpdmVasNpsDownloadRightOperand": { + "type": "string", + "const": "cx.bpdm.vas.nps.download:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data in line with the following purpose: verifying its submitted Business Partner Data.\",\"additionalInformation\":\"Typically used for: Natural Person Screening Data Model\"}" + }, + "CcmBaseRightOperand": { + "type": "string", + "const": "cx.ccm.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the exchanged business partner certificates in line with the following purpose: Verification and validation of the existence of a certification.\",\"additionalInformation\":\"Typically used for: Business Partner Certificate\"}" + }, + "BpdmPoolAllRightOperand": { + "type": "string", + "const": "cx.bpdm.poolAll:1", + "$comment": "{\"permission\":\"The Data Consumer may use the basic information about all entities with a BPN in the Catena-X data space provided by the Core Service B Provider for any of the following purposes: (i) identifying internal counterparties, (ii) usage in internal information processes, (iii) usage in Value Added Services (VAS).\",\"additionalInformation\":\"Typically used for: Pool Data Model\"}" + }, + "LogisticsBaseRightOperand": { + "type": "string", + "const": "cx.logistics.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the logistic Data for any of the following purposes: (i) tracking of load carriers, reusable boxes and any packaging, (ii) early identification of delay or damages on transport, and (iii) identification of affected part instances or batch instances on respective transport units.\",\"additionalInformation\":\"Typically used for: asset_tracker_links, batch, global_transport_label, sensor_data, packing_list, serial_part\"}" + }, + "EngineeringBaseRightOperand": { + "type": "string", + "const": "cx.engineering.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) [joint] development of products (e.g., 3D Designs, Simulations) in accordance with the provisions of the ContractReference with the Data Provider, (ii) [joint] development of products (e.g., 3D Designs, Simulations) in accordance with the provisions of the ContractReference, including integrating directed parts of third party manufacturers, as agreed with the Data Provider; the Data Consumer may share the Data with the respective third party manufacturer to the extent required; this relates in particular to such Data that the third party supplier requires, in order to facilitate the final assembly of the directed parts into the product as to be developed by the Data Provider, (iii) regulatory compliance (e.g., material information in master data for secondar material content checks), (iv) mock-up and integration (e.g., collision checks in 3D), (v) versioning & release notifications of products (e.g., new product version that shall be used in a new product generation), (vi) interface alignments (e.g., between interacting systems on physical, logical and functional level). The Data Consumer is prohibited to use the Data for reverse engineering, e.g., by using material classifications for redeveloping and building the respective Data Provider's product as such.\",\"additionalInformation\":\"Typically used for: requirement, digital engineering master data\"}" + }, + "MaterialaccountingBaseRightOperand": { + "type": "string", + "const": "cx.materialaccounting.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) creating material balances along all stages of the reverse value chain, (ii) accounting of secondary material flows and calculating secondary material content, (iii) verifying the fulfillment of regulatory (open or closed loop) secondary material quotas and fulfilling related legal reporting obligations. \",\"additionalInformation\":\"Typically used for: VehicleInformation, WasteCode, RecyclingBatch, Material, RecyclingInformation, Composition\"}" + }, + "EsdscomBaseRightOperand": { + "type": "string", + "const": "cx.esdscom.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) conducting plausibility checks and validation measures, (ii) inhouse processing in data management systems and data bases (e.g., in occupational health and environment management systems, inhouse substance databases), (iii) reporting, registration, and notification duties, (iv) fulfilling import/export requirements of chemicals, (v) dangerous goods classification, (vi) any other not listed data usage required, in order to meet related legal requirements.\",\"additionalInformation\":\"Typically used for: eSDScom\"}" + }, + "EcuBaseRightOperand": { + "type": "string", + "const": "cx.ecu.base:1", + "$comment": "{\"permission\":\"The Data Consumer may use the Data for any of the following purposes: (i) issuing digital certificates for a control unit, e.g., for creating a digital identity for the control unit, (ii) registering a digital device identity already created by the Data Provider, (iii) enabling debug functions on the control unit, (iv) performing updates or customization of the control unit, e.g., overwriting an initial key/password with a value generated by the Data Consumer, (v) dangerous goods classification, (vi) integrating cryptographic keys into products or infrastructure of the Data Consumer to enable secure communication with the control unit, (vii) tracking the software status and changes to a control unit.\",\"additionalInformation\":\"Typically used for: CryptoMaterial,SoftwareInformation\"}" + }, + "UsagePurposeIndividualRightOperand": { + "type": "string", + "$comment": "{\"permission\":\"Data Provider and Data Consumer are free to individually agree this certain purpose of use. The legal meaning of this certain purpose need to be agreed individually between Data Provider and Data Consumer.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/usage-restriction-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/usage-restriction-constraint-schema.json new file mode 100644 index 0000000000..f65e13451b --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/usage-restriction-constraint-schema.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "UsageRestrictionConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/UsageRestrictionConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/usage-restriction-constraint-schema.json", + "definitions": { + "UsageRestrictionConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "UsageRestriction" + }, + "operator": { + "type": "string", + "const": "isAllOf" + }, + "rightOperand": { + "type": "array", + "minItems": 1, + "items": { + "anyOf": [ + {"$ref": "#/definitions/ThirdPartyForbiddenRightOperand"}, + {"$ref": "#/definitions/ManipulationForbiddenRightOperand"}, + {"$ref": "#/definitions/DerivationsForbiddenRightOperand"}, + {"$ref": "#/definitions/ExtraordinaryAnalyticsForbiddenRightOperand"}, + {"$ref": "#/definitions/DataProviderRemovalForbiddenRightOperand"} + ] + } + } + }, + "additionalProperties": false + }, + "ThirdPartyForbiddenRightOperand": { + "type": "string", + "const": "cx.thirdParty.forbidden:1", + "$comment": "{\"prohibition\":\"The Data Consumer is prohibited from making the Data available to third parties, either temporarily or permanently, from reproducing, distributing, or publicly displaying the Data; this also applies insofar as the data constitutes essential or non-essential parts of a database (Section 87a German Act on Copyright and Related Rights (UrhG)), unless otherwise individually agreed between the Parties in the usage purposes for a specific use case (cx-policy:UsagePurpose) or in the referenced bilateral contract (cx-policy:ContractReference). The Data Provider’s right to reproduce the Data provided by it for internal purposes remains unaffected.\"}" + }, + "ManipulationForbiddenRightOperand": { + "type": "string", + "const": "cx.manipulation.forbidden:1", + "$comment": "{\"prohibition\":\"The Data Consumer is prohibited from modifying the Data, separating the associated metadata from the Data, or otherwise altering it, or from attempting any of the aforementioned actions or permitting a third party to perform such actions, unless otherwise individually agreed between the parties in the usage purposes for a specific use case (cx-policy:UsagePurpose) or in the referenced bilateral contract (cx-policy:ContractReference). The Data Provider’s right to reproduce the Data provided by it for internal purposes remains unaffected.\"}" + }, + "DerivationsForbiddenRightOperand": { + "type": "string", + "const": "cx.derivations.forbidden:1", + "$comment": "{\"prohibition\":\"The Data Consumer is prohibited from creating derivative works from the Data (including making substantial changes to any databases provided within the meaning of Section 87a para. 1 sentence 2 German Act on Copyright and Related Rights (UrhG), unless otherwise individually agreed between the Parties in the usage purposes for a specific Use Case (cx-policy:UsagePurpose) or in the referenced bilateral contract (cx-policy:ContractReference).\"}" + }, + "ExtraordinaryAnalyticsForbiddenRightOperand": { + "type": "string", + "const": "cx.extraordinaryAnalytics.forbidden:1", + "$comment": "{\"prohibition\":\"The Data Consumer is prohibited, insofar as the Data constitutes insignificant parts of a database within the meaning of Section 87b para. 1 sentence 1 German Act on Copyright and Related Rights (UrhG), from repeatedly and systematically carrying out actions that conflict with the normal evaluation of a database or unreasonably impair the legitimate interests of the Data Provider (Section 87b para. 1 sentence 2 UrhG), unless otherwise individually agreed between the Parties in the usage purposes for a specific Use Case (cx-policy:UsagePurpose) or in the referenced bilateral contract (cx-policy:ContractReference).\"}" + }, + "DataProviderRemovalForbiddenRightOperand": { + "type": "string", + "const": "cx.dataProviderRemoval.forbidden:1", + "$comment": "{\"prohibition\":\"The Data Consumer is prohibited from removing the company identifiers and/or other references to the Data Provider contained in the Data and/or the associated metadata or databases, unless otherwise individually agreed between the Parties in the usage purposes for a specific Use Case (cx-policy:UsagePurpose) or in the referenced bilateral contract (cx-policy:ContractReference).\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/version-changes-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/version-changes-constraint-schema.json new file mode 100644 index 0000000000..55adc88ddb --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/version-changes-constraint-schema.json @@ -0,0 +1,43 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "VersionChangesConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/VersionChangesConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/version-changes-constraint-schema.json", + "definitions": { + "VersionChangesConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "VersionChanges" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "oneOf": [ + {"$ref": "#/definitions/VersionChangesMinorRightOperand"}, + {"$ref": "#/definitions/VersionChangesMajorRightOperand"} + ] + } + }, + "additionalProperties": false + }, + "VersionChangesMinorRightOperand": { + "type": "string", + "const": "cx.versionChanges.minor:1", + "$comment": "{\"permission\":\"The Agreement concluded via the Registered Connector (RC) covers only the exchange of Data effected on the basis of the major API version (as specified in the dataset attribute base-URL), the major Asset-Version (dataset attribute cx-common:version), and/or the major Aspect Model Version as applicable at the time of concluding the Agreement. The Agreement concluded via the RC must be renegotiated in the event of any change to at least one of these major versions. The Agreement does not need to be renegotiated in the event of any change to one of these minor versions. The definitions of major and minor version is based on Semantic Versioning (https://semver.org/).\"}" + }, + "VersionChangesMajorRightOperand": { + "type": "string", + "const": "cx.versionChanges.major:1", + "$comment": "{\"permission\":\"The Agreement concluded via the Registered Connector (RC) covers any data exchange, which shall be effected via the API specified by the dataset attribute dct:type, irrespective of whether the API version applicable at the time of contract conclusion (as part of the dataset attribute base-URL), the Asset Version (dataset attribute cx-common:version), or the Aspect Model version changes.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-constraint-schema.json new file mode 100644 index 0000000000..2a5be72e5b --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-constraint-schema.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "WarrantyConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/WarrantyConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/warranty-constraint-schema.json", + "definitions": { + "WarrantyConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "Warranty" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "oneOf": [ + {"$ref": "#/definitions/WarrantyNoneRightOperand"}, + {"$ref": "#/definitions/WarrantyContractReferenceRightOperand"}, + {"$ref": "#/definitions/WarrantyDataQualityIssuesRightOperand"} + ] + } + }, + "additionalProperties": false + }, + "WarrantyNoneRightOperand": { + "type": "string", + "const": "cx.warranty.none:1", + "$comment": "{\"permission\":\"The provision of the Data is made with the exclusion of any warranty for material defects and defects in title, unless the Data Provider fraudulently conceals such a defect.\"}" + }, + "WarrantyContractReferenceRightOperand": { + "type": "string", + "const": "cx.warranty.contractReference:1", + "$comment": "{\"permission\":\"The provision of the Data is subject to the warranty for material defects and defects in title as agreed in the description of the subject matter of performance according to the referenced contract (leftOperand: ContractReference).\"}" + }, + "WarrantyDataQualityIssuesRightOperand": { + "type": "string", + "const": "cx.warranty.dataQualityIssues:1", + "$comment": "{\"permission\":\"In the event of a material deviation from the contractually agreed data quality, the Data Provider shall be entitled to (i) demand the rectification of defects by provision of Data in the quality owed, (ii) terminate the contract in the event of failure to remedy the defect, and (iii) claim damages in accordance with the liability provisions set out below.\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-definition-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-definition-constraint-schema.json new file mode 100644 index 0000000000..ca22d9cdf2 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-definition-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "WarrantyConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/WarrantyConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/warranty-definition-constraint-schema.json", + "definitions": { + "WarrantyConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "WarrantyDefinition" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/WarrantyContractEndDateRightOperand" + } + }, + "additionalProperties": false + }, + "WarrantyContractEndDateRightOperand": { + "type": "string", + "const": "cx.warranty.contractEndDate:1", + "$comment": "{\"permission\":\"The provision of the Data is subject to a warranty for material defects and defects in title until the end of the Agreement concluded via the Registered Connector (RC).\"}" + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-duration-constraint-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-duration-constraint-schema.json new file mode 100644 index 0000000000..639dbfa2b5 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/cx-policy/warranty-duration-constraint-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "WarrantyDurationConstraintSchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/WarrantyDurationConstraint" + } + ], + "$id": "https://w3id.org/catenax/2025/9/policy/warranty-duration-constraint-schema.json", + "definitions": { + "WarrantyDurationConstraint": { + "type": "object", + "properties": { + "leftOperand": { + "type": "string", + "const": "WarrantyDurationMonths" + }, + "operator": { + "type": "string", + "const": "eq" + }, + "rightOperand": { + "$ref": "#/definitions/WarrantyDurationMonthsRightOperand" + } + }, + "additionalProperties": false + }, + "WarrantyDurationMonthsRightOperand": { + "type": "string", + "pattern": "^[1-9][0-9]*$", + "$comment": "{\"permission\":\"The provision of the Data is subject to a warranty for material and legal defects for a period specified herein in months.\"}" + } + } +} diff --git a/edc-extensions/cx-policy/src/main/resources/jsonschema/dspace/contract-schema.json b/edc-extensions/cx-policy/src/main/resources/jsonschema/dspace/contract-schema.json new file mode 100644 index 0000000000..90b43c4078 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/resources/jsonschema/dspace/contract-schema.json @@ -0,0 +1,374 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "title": "PolicySchema", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/Policy" + } + ], + "$id": "https://w3id.org/dspace/2025/1/negotiation/contract-schema.json", + "definitions": { + "Policy": { + "oneOf": [ + { + "$ref": "#/definitions/MessageOffer" + }, + { + "$ref": "#/definitions/Offer" + }, + { + "$ref": "#/definitions/Agreement" + } + ] + }, + "PolicyClass": { + "type": "object", + "properties": { + "@id": { + "type": "string" + }, + "profile": { + "oneOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "string" + } + ] + }, + "permission": { + "type": "array", + "items": { + "$ref": "#/definitions/Permission" + }, + "minItems": 1 + }, + "prohibition": { + "type": "array", + "items": { + "$ref": "#/definitions/Prohibition" + }, + "minItems": 1 + }, + "obligation": { + "type": "array", + "items": { + "$ref": "#/definitions/Duty" + }, + "minItems": 1 + } + }, + "required": [ + "@id" + ] + }, + "MessageOffer": { + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/PolicyClass" + }, + { + "properties": { + "@type": { + "type": "string", + "const": "Offer" + }, + "target": { + "type": "string" + } + } + }, + { + "anyOf": [ + { + "required": [ + "permission" + ] + }, + { + "required": [ + "prohibition" + ] + } + ] + } + ], + "required": [ + "@type" + ] + }, + "Offer": { + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/PolicyClass" + }, + { + "properties": { + "@type": { + "type": "string", + "const": "Offer" + } + } + }, + { + "anyOf": [ + { + "required": [ + "permission" + ] + }, + { + "required": [ + "prohibition" + ] + } + ] + } + ], + "not": { + "required": [ + "target" + ] + } + }, + "Agreement": { + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/PolicyClass" + }, + { + "properties": { + "@type": { + "type": "string", + "const": "Agreement" + }, + "target": { + "type": "string" + }, + "assigner": { + "type": "string" + }, + "assignee": { + "type": "string" + }, + "timestamp": { + "type": "string", + "pattern": "-?([1-9][0-9]{3,}|0[0-9]{3})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T(([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?|(24:00:00(\\.0+)?))(Z|(\\+|-)((0[0-9]|1[0-3]):[0-5][0-9]|14:00))?" + } + } + }, + { + "anyOf": [ + { + "required": [ + "permission" + ] + }, + { + "required": [ + "prohibition" + ] + } + ] + } + ], + "required": [ + "@type", + "target", + "assignee", + "assigner" + ] + }, + "Rule": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/Action" + }, + "constraint": { + "type": "array", + "items": { + "$ref": "#/definitions/Constraint" + } + } + }, + "required": [ + "action" + ] + }, + "Permission": { + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/Rule" + } + ] + }, + "Prohibition": { + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/Rule" + } + ] + }, + "Duty": { + "type": "object", + "allOf": [ + { + "properties": { + "action": { + "$ref": "#/definitions/Action" + }, + "constraint": { + "type": "array", + "items": { + "$ref": "#/definitions/Constraint" + } + } + }, + "required": [ + "action" + ] + } + ] + }, + "Action": { + "type": "string" + }, + "Constraint": { + "type": "object", + "oneOf": [ + { + "$ref": "#/definitions/LogicalConstraint" + }, + { + "$ref": "#/definitions/AtomicConstraint" + } + ] + }, + "LogicalConstraint": { + "type": "object", + "properties": { + "and": { + "type": "array", + "items": { + "$ref": "#/definitions/Constraint" + } + }, + "andSequence": { + "type": "array", + "items": { + "$ref": "#/definitions/Constraint" + } + }, + "or": { + "type": "array", + "items": { + "$ref": "#/definitions/Constraint" + } + }, + "xone": { + "type": "array", + "items": { + "$ref": "#/definitions/Constraint" + } + } + }, + "oneOf": [ + { + "required": [ + "and" + ] + }, + { + "required": [ + "andSequence" + ] + }, + { + "required": [ + "or" + ] + }, + { + "required": [ + "xone" + ] + } + ] + }, + "AtomicConstraint": { + "type": "object", + "properties": { + "rightOperand": { + "$ref": "#/definitions/RightOperand" + }, + "leftOperand": { + "$ref": "#/definitions/LeftOperand" + }, + "operator": { + "$ref": "#/definitions/Operator" + } + }, + "required": [ + "rightOperand", + "operator", + "leftOperand" + ] + }, + "Operator": { + "type": "string", + "enum": [ + "eq", + "gt", + "gteq", + "lteq", + "hasPart", + "isA", + "isAllOf", + "isAnyOf", + "isNoneOf", + "isPartOf", + "lt", + "term-lteq", + "neq" + ] + }, + "RightOperand": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + }, + { + "type": "array" + } + ] + }, + "LeftOperand": { + "type": "string" + }, + "Reference": { + "type": "object", + "properties": { + "@id": { + "type": "string" + } + }, + "required": [ + "@id" + ] + } + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/validator/CxJsonSchemaPolicyDefinitionValidatorTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/validator/CxJsonSchemaPolicyDefinitionValidatorTest.java new file mode 100644 index 0000000000..9445f710ed --- /dev/null +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/validator/CxJsonSchemaPolicyDefinitionValidatorTest.java @@ -0,0 +1,98 @@ +/******************************************************************************** + * Copyright (c) 2026 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.policy.cx.validator; + +import jakarta.json.Json; +import jakarta.json.JsonObject; +import jakarta.json.JsonValue; +import org.eclipse.tractusx.edc.policy.cx.validator.jsonschema.CxJsonSchemaPolicyDefinitionValidator; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; + +class CxJsonSchemaPolicyDefinitionValidatorTest { + + private final CxJsonSchemaPolicyDefinitionValidator validator = new CxJsonSchemaPolicyDefinitionValidator(); + + @Test + void shouldValidateJsonSchema_whenValidPolicyDefinition() { + var policy = Json.createObjectBuilder() + .add(TYPE, "Set") + .add(ID, "id") + .build(); + var policyDefinition = policyDefinition(policy); + + var result = validator.validate(policyDefinition); + + assertThat(result.succeeded()).isTrue(); + } + + @Test + void shouldResolveReferencedSchemas_whenPolicyContainsConstraints() { + var constraint = Json.createObjectBuilder() + .add("leftOperand", "Membership") + .add("operator", "eq") + .add("rightOperand", "active"); + var permission = Json.createObjectBuilder() + .add("action", "access") + .add("constraint", Json.createArrayBuilder().add(constraint)); + var policy = Json.createObjectBuilder() + .add(TYPE, "Set") + .add(ID, "id") + .add("permission", Json.createArrayBuilder().add(permission)) + .build(); + var policyDefinition = policyDefinition(policy); + + assertThatNoException().isThrownBy(() -> validator.validate(policyDefinition)); + } + + @Test + void shouldReturnFailure_whenPolicyMissing() { + var policyDefinition = policyDefinition(null); + + var result = validator.validate(policyDefinition); + + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureMessages()).anyMatch(message -> message.contains("Attribute 'policy' is missing from PolicyDefinition.")); + } + + @Test + void shouldReturnFailure_whenPolicyNotAnObject() { + var policyDefinition = policyDefinition(Json.createArrayBuilder().build()); + + var result = validator.validate(policyDefinition); + + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureMessages()).anyMatch(message -> message.contains("Attribute 'policy' is not a valid JSON object.")); + } + + private JsonObject policyDefinition(JsonValue policy) { + var builder = Json.createObjectBuilder() + .add(TYPE, "PolicyDefinition"); + if (policy != null) { + builder.add("policy", policy); + } + + return builder.build(); + } +} diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/helpers/PolicyHelperFunctions.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/helpers/PolicyHelperFunctions.java index 3cb224da49..08e100b995 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/helpers/PolicyHelperFunctions.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/helpers/PolicyHelperFunctions.java @@ -2,6 +2,7 @@ * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) * Copyright (c) 2025 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. * Copyright (c) 2026 Cofinity-X GmbH + * Copyright (c) 2026 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -21,18 +22,13 @@ package org.eclipse.tractusx.edc.tests.helpers; - import jakarta.json.Json; import jakarta.json.JsonArrayBuilder; import jakarta.json.JsonObject; -import jakarta.json.JsonObjectBuilder; -import org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition; -import org.eclipse.edc.policy.model.AtomicConstraint; import org.eclipse.edc.policy.model.Operator; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -42,114 +38,113 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; 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.ODRL_CONSTRAINT_TYPE; -import static org.eclipse.edc.jsonld.spi.PropertyAndTypeNames.ODRL_LOGICAL_CONSTRAINT_TYPE; -import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_NS; +import static org.eclipse.tractusx.edc.cx.CxJsonLdExtension.CX_POLICY_2025_09_CONTEXT; public class PolicyHelperFunctions { public static final String ODRL_CONTEXT = "https://w3id.org/dspace/2025/1/odrl-profile.jsonld"; - private static final String BUSINESS_PARTNER_EVALUATION_KEY = "BusinessPartnerNumber"; - - private static final String BUSINESS_PARTNER_CONSTRAINT_KEY = CX_POLICY_2025_09_NS + "BusinessPartnerGroup"; - - public static final String FRAMEWORK_AGREEMENT_LITERAL = CX_POLICY_2025_09_NS + "FrameworkAgreement"; - private static final String USAGE_PURPOSE_LITERAL = CX_POLICY_2025_09_NS + "UsagePurpose"; + private static final String FRAMEWORK_AGREEMENT_KEY = "FrameworkAgreement"; + private static final String USAGE_PURPOSE_KEY = "UsagePurpose"; - public static final String DATA_PROVISIONING_END_DATE_LITERAL = CX_POLICY_2025_09_NS + "DataProvisioningEndDate"; - public static final String DATA_PROVISIONING_END_DURATION_LITERAL = CX_POLICY_2025_09_NS + "DataProvisioningEndDurationDays"; - public static final String DATA_USAGE_END_DATE_LITERAL = CX_POLICY_2025_09_NS + "DataUsageEndDate"; - public static final String DATA_USAGE_END_DURATION_LITERAL = CX_POLICY_2025_09_NS + "DataUsageEndDurationDays"; + public static final String DATA_USAGE_END_DATE_KEY = "DataUsageEndDate"; + public static final String DATA_USAGE_END_DURATION_KEY = "DataUsageEndDurationDays"; - public static JsonObject bpnGroupPolicy(Operator operator, String... allowedGroups) { - return bpnGroupPolicy(operator.getOdrlRepresentation(), false, allowedGroups); - } - - public static JsonObject bpnGroupPolicyWithRightOperandAsArray(Operator operator, String... allowedGroups) { - return bpnGroupPolicy(operator.getOdrlRepresentation(), true, allowedGroups); + public static JsonObject emptyPolicy() { + return Json.createObjectBuilder() + .add(CONTEXT, Json.createArrayBuilder() + .add(ODRL_CONTEXT) + .add(CX_POLICY_2025_09_CONTEXT)) + .add(TYPE, "Set") + .add(ID, "id") + .build(); } - /** - * Creates a {@link PolicyDefinition} using the given ID, that contains equality constraints for each of the given BusinessPartnerNumbers: - * each BPN is converted into an {@link AtomicConstraint} {@code BusinessPartnerNumber EQ [BPN]}. - */ + public static JsonObject bpnPolicy(Operator operator, String... bpns) { + JsonArrayBuilder bpnArray = Json.createArrayBuilder(); + Stream.of(bpns).forEach(bpnArray::add); - public static JsonObject frameworkPolicy(String id, Map permissions, String action) { - return policyDefinitionBuilder(frameworkPolicy(permissions, action)) - .add(ID, id) + var bpnConstraint = Json.createObjectBuilder() + .add("leftOperand", "BusinessPartnerNumber") + .add("operator", operatorValueWithoutNamespace(operator)) + .add("rightOperand", bpnArray) .build(); - } - public static JsonObject frameworkPolicy(Map permissions, String action) { + var permission = Json.createObjectBuilder() + .add("action", "access") + .add("constraint", Json.createArrayBuilder() + .add(bpnConstraint) + .build()) + .build(); return Json.createObjectBuilder() - .add(CONTEXT, ODRL_CONTEXT) + .add(CONTEXT, Json.createArrayBuilder() + .add(ODRL_CONTEXT) + .add(CX_POLICY_2025_09_CONTEXT)) .add(TYPE, "Set") + .add(ID, "id") .add("permission", Json.createArrayBuilder() - .add(frameworkConstraint(new HashMap<>(permissions), action, Operator.EQ, false))) + .add(permission)) .build(); } - public static JsonObject frameworkPolicy(Map permissions, String action, String operator) { - return frameworkPolicy(permissions, action, Operator.valueOf(operator)); - } + public static JsonObject bpnGroupPolicy(String operator, boolean rightOperandAsArray, String... allowedGroups) { - public static JsonObject frameworkPolicy(Map permissions, String action, Operator operator) { - return Json.createObjectBuilder() - .add(CONTEXT, ODRL_CONTEXT) - .add(TYPE, "Set") - .add("permission", Json.createArrayBuilder() - .add(frameworkConstraint(new HashMap<>(permissions), action, operator, false))) - .build(); - } + var groupConstraint = atomicConstraint("BusinessPartnerGroup", operator, Arrays.asList(allowedGroups), rightOperandAsArray); + var permission = Json.createObjectBuilder() + .add("action", "access") + .add("constraint", Json.createArrayBuilder() + .add(groupConstraint) + .build()) + .build(); - public static JsonObject emptyPolicy() { return Json.createObjectBuilder() - .add(CONTEXT, ODRL_CONTEXT) + .add(CONTEXT, Json.createArrayBuilder() + .add(ODRL_CONTEXT) + .add(CX_POLICY_2025_09_CONTEXT)) .add(TYPE, "Set") + .add(ID, "id") + .add("permission", Json.createArrayBuilder() + .add(permission)) .build(); } - public static JsonObject frameworkPolicy(String leftOperand, Operator operator, Object rightOperand, String action) { - return frameworkPolicy(leftOperand, operator, rightOperand, action, false); - } - public static JsonObject frameworkPolicy(String leftOperand, Operator operator, Object rightOperand, String action, boolean createRightOperandsAsArray) { - var constraint = atomicConstraint(leftOperand, operator.getOdrlRepresentation(), rightOperand, createRightOperandsAsArray); + var constraint = atomicConstraint(leftOperand, operatorValueWithoutNamespace(operator), rightOperand, createRightOperandsAsArray); var constraintsBuilder = Json.createArrayBuilder() .add(constraint); - if (!leftOperand.equals(FRAMEWORK_AGREEMENT_LITERAL) && action.contains("use")) { + if (!leftOperand.equals(FRAMEWORK_AGREEMENT_KEY) && action.contains("use")) { constraintsBuilder.add(frameworkAgreementConstraint()); } - if (!leftOperand.equals(USAGE_PURPOSE_LITERAL) && action.contains("use")) { + if (!leftOperand.equals(USAGE_PURPOSE_KEY) && action.contains("use")) { constraintsBuilder.add(usagePurposeConstraint()); } var permission = Json.createObjectBuilder() .add("action", action) - .add("constraint", Json.createObjectBuilder() - .add(TYPE, ODRL_LOGICAL_CONSTRAINT_TYPE) - .add("and", constraintsBuilder.build()) + .add("constraint", Json.createArrayBuilder() + .add(Json.createObjectBuilder() + .add("and", constraintsBuilder.build()) + .build()) .build()) .build(); return Json.createObjectBuilder() - .add(CONTEXT, ODRL_CONTEXT) + .add(CONTEXT, Json.createArrayBuilder() + .add(ODRL_CONTEXT) + .add(CX_POLICY_2025_09_CONTEXT)) .add(TYPE, "Set") + .add(ID, "id") .add("permission", Json.createArrayBuilder().add(permission)) .build(); } private static JsonObject frameworkAgreementConstraint() { return Json.createObjectBuilder() - .add(TYPE, ODRL_CONSTRAINT_TYPE) - .add("leftOperand", FRAMEWORK_AGREEMENT_LITERAL) + .add("leftOperand", FRAMEWORK_AGREEMENT_KEY) .add("operator", "eq") .add("rightOperand", "DataExchangeGovernance:1.0") .build(); @@ -157,157 +152,38 @@ private static JsonObject frameworkAgreementConstraint() { private static JsonObject usagePurposeConstraint() { return Json.createObjectBuilder() - .add(TYPE, ODRL_CONSTRAINT_TYPE) - .add("leftOperand", USAGE_PURPOSE_LITERAL) + .add("leftOperand", USAGE_PURPOSE_KEY) .add("operator", "isAnyOf") - .add("rightOperand", "cx.pcf.base:1") - .build(); - } - - public static JsonObject legacyFrameworkPolicy() { - var constraint1 = atomicConstraint(CX_POLICY_NS + "FrameworkAgreement", Operator.EQ.getOdrlRepresentation(), "DataExchangeGovernance:1.0", false); - var constraint2 = atomicConstraint(CX_POLICY_NS + "UsagePurpose", Operator.EQ.getOdrlRepresentation(), "cx.core.digitalTwinRegistry:1", false); - - var constraintsBuilder = Json.createArrayBuilder() - .add(constraint1) - .add(constraint2); - - var permission = Json.createObjectBuilder() - .add("action", "use") - .add("constraint", Json.createObjectBuilder() - .add(TYPE, ODRL_LOGICAL_CONSTRAINT_TYPE) - .add("and", constraintsBuilder.build()) - .build()) - .build(); - - return Json.createObjectBuilder() - .add(CONTEXT, ODRL_CONTEXT) - .add(TYPE, "Set") - .add("permission", Json.createArrayBuilder().add(permission)) - .build(); - } - - public static JsonObject inForceDatePolicyLegacy(String operatorStart, Object startDate, String operatorEnd, Object endDate) { - var constraint = Json.createObjectBuilder() - .add("@type", "LogicalConstraint") - .add("and", Json.createArrayBuilder() - .add(atomicConstraint("https://w3id.org/edc/v0.0.1/ns/inForceDate", operatorStart, startDate, false)) - .add(atomicConstraint("https://w3id.org/edc/v0.0.1/ns/inForceDate", operatorEnd, endDate, false)) - .add(atomicConstraint("https://w3id.org/catenax/policy/Membership", "eq", "active", false)) - .build()) - .build(); - - return policy(List.of(Json.createObjectBuilder() - .add("action", "use") - .add("constraint", constraint) - .build())); - } - - public static JsonObjectBuilder policyDefinitionBuilder() { - return Json.createObjectBuilder() - .add(TYPE, EDC_NAMESPACE + "PolicyDefinitionDto"); - } - - public static JsonObjectBuilder policyDefinitionBuilder(JsonObject policy) { - return policyDefinitionBuilder() - .add(EDC_NAMESPACE + "policy", policy); - } - - public static JsonObject bpnPolicy(String... bpns) { - return Json.createObjectBuilder() - .add(CONTEXT, ODRL_CONTEXT) - .add(TYPE, "Set") - .add("permission", Json.createArrayBuilder() - .add(permission(bpns))) - .build(); - } - - public static JsonObject bpnPolicy(Operator operator, String... bpns) { - JsonArrayBuilder bpnArray = Json.createArrayBuilder(); - Stream.of(bpns).forEach(bpnArray::add); - - var bpnConstraint = Json.createObjectBuilder() - .add(TYPE, ODRL_CONSTRAINT_TYPE) - .add("leftOperand", CX_POLICY_2025_09_NS + BUSINESS_PARTNER_EVALUATION_KEY) - .add("operator", operator.getOdrlRepresentation()) - .add("rightOperand", bpnArray) - .build(); - - var permission = Json.createObjectBuilder() - .add("action", CX_POLICY_2025_09_NS + "access") - .add("constraint", Json.createObjectBuilder() - .add(TYPE, ODRL_LOGICAL_CONSTRAINT_TYPE) - .add("and", bpnConstraint) - .build()) - .build(); - return Json.createObjectBuilder() - .add(CONTEXT, ODRL_CONTEXT) - .add(TYPE, "Set") - .add("permission", Json.createArrayBuilder() - .add(permission)) - .build(); - } - - private static JsonObject bpnGroupPolicy(String operator, boolean rightOperandAsArray, String... allowedGroups) { - - var groupConstraint = atomicConstraint(BUSINESS_PARTNER_CONSTRAINT_KEY, operator, Arrays.asList(allowedGroups), rightOperandAsArray); - - var permission = Json.createObjectBuilder() - .add("action", CX_POLICY_2025_09_NS + "access") - .add("constraint", Json.createObjectBuilder() - .add(TYPE, ODRL_LOGICAL_CONSTRAINT_TYPE) - .add("and", groupConstraint) - .build()) - .build(); - - return Json.createObjectBuilder() - .add(CONTEXT, ODRL_CONTEXT) - .add(TYPE, "Set") - .add("permission", permission) - .build(); - } - - private static JsonObject permission(String... bpns) { - - var bpnConstraints = Stream.of(bpns) - .map(bpn -> atomicConstraint(CX_POLICY_2025_09_NS + BUSINESS_PARTNER_EVALUATION_KEY, "isAnyOf", bpn, false)) - .collect(Json::createArrayBuilder, JsonArrayBuilder::add, JsonArrayBuilder::add); - - return Json.createObjectBuilder() - .add("action", CX_POLICY_2025_09_NS + "access") - .add("constraint", Json.createObjectBuilder() - .add(TYPE, ODRL_LOGICAL_CONSTRAINT_TYPE) - .add("and", bpnConstraints) - .build()) + .add("rightOperand", Json.createArrayBuilder().add("cx.pcf.base:1").build()) .build(); } public static JsonObject frameworkConstraint(Map operandMappings, String action, Operator operator, boolean createRightOperandsAsArray) { var constraints = operandMappings.entrySet().stream() - .map(constraint -> atomicConstraint(constraint.getKey(), operator.getOdrlRepresentation(), constraint.getValue(), createRightOperandsAsArray)) + .map(constraint -> atomicConstraint(constraint.getKey(), operatorValueWithoutNamespace(operator), constraint.getValue(), createRightOperandsAsArray)) .collect(Json::createArrayBuilder, JsonArrayBuilder::add, JsonArrayBuilder::add); if (action.contains("use")) { - if (!operandMappings.containsKey(FRAMEWORK_AGREEMENT_LITERAL)) { + if (!operandMappings.containsKey(FRAMEWORK_AGREEMENT_KEY)) { constraints.add(frameworkAgreementConstraint()); } - if (!operandMappings.containsKey(USAGE_PURPOSE_LITERAL)) { + if (!operandMappings.containsKey(USAGE_PURPOSE_KEY)) { constraints.add(usagePurposeConstraint()); } } return Json.createObjectBuilder() .add("action", action) - .add("constraint", Json.createObjectBuilder() - .add(TYPE, ODRL_LOGICAL_CONSTRAINT_TYPE) - .add("and", constraints) + .add("constraint", Json.createArrayBuilder() + .add(Json.createObjectBuilder() + .add("and", constraints) + .build()) .build()) .build(); } private static JsonObject atomicConstraint(String leftOperand, String operator, Object rightOperand, boolean createRightOperandsAsArray) { var builder = Json.createObjectBuilder() - .add(TYPE, ODRL_CONSTRAINT_TYPE) .add("leftOperand", leftOperand) .add("operator", operator); @@ -318,6 +194,8 @@ private static JsonObject atomicConstraint(String leftOperand, String operator, .build()); } else if (rightOperand instanceof Collection coll) { builder.add("rightOperand", coll.stream().map(Object::toString).collect(Collectors.joining(","))); + } else if (createRightOperandsAsArray) { + builder.add("rightOperand", Json.createArrayBuilder().add(rightOperand.toString()).build()); } else { builder.add("rightOperand", rightOperand.toString()); } @@ -326,99 +204,112 @@ private static JsonObject atomicConstraint(String leftOperand, String operator, public static JsonObject dataUsageEndDurationDays(Integer duration) { var constraint = Json.createObjectBuilder() - .add("@type", "LogicalConstraint") .add("and", Json.createArrayBuilder() - .add(atomicConstraint(DATA_USAGE_END_DURATION_LITERAL, "eq", duration, false)) + .add(atomicConstraint(DATA_USAGE_END_DURATION_KEY, "eq", duration, false)) .add(frameworkAgreementConstraint()) .add(usagePurposeConstraint()) .build()) .build(); - return policy(List.of(Json.createObjectBuilder() + var permission = Json.createObjectBuilder() .add("action", "use") - .add("constraint", constraint) - .build())); + .add("constraint", Json.createArrayBuilder() + .add(constraint) + .build()) + .build(); + + var contextArrayBuilder = Json.createArrayBuilder(); + contextArrayBuilder.add(ODRL_CONTEXT); + contextArrayBuilder.add(CX_POLICY_2025_09_CONTEXT); + + return Json.createObjectBuilder() + .add(CONTEXT, contextArrayBuilder) + .add(TYPE, "Set") + .add(ID, "id") + .add("permission", Json.createArrayBuilder() + .add(permission)) + .build(); } public static JsonObject dataUsageEndDate(String endDate) { var constraint = Json.createObjectBuilder() - .add("@type", "LogicalConstraint") .add("and", Json.createArrayBuilder() - .add(atomicConstraint(DATA_USAGE_END_DATE_LITERAL, "eq", endDate, false)) + .add(atomicConstraint(DATA_USAGE_END_DATE_KEY, "eq", endDate, false)) .add(frameworkAgreementConstraint()) .add(usagePurposeConstraint()) .build()) .build(); - return policy(List.of(Json.createObjectBuilder() + var permission = Json.createObjectBuilder() .add("action", "use") - .add("constraint", constraint) - .build())); + .add("constraint", Json.createArrayBuilder() + .add(constraint) + .build()) + .build(); + + var contextArrayBuilder = Json.createArrayBuilder(); + contextArrayBuilder.add(ODRL_CONTEXT); + contextArrayBuilder.add(CX_POLICY_2025_09_CONTEXT); + + return Json.createObjectBuilder() + .add(CONTEXT, contextArrayBuilder) + .add(TYPE, "Set") + .add(ID, "id") + .add("permission", Json.createArrayBuilder() + .add(permission)) + .build(); } - public static JsonObject dataProvisioningEndDurationDays(Integer duration) { + public static JsonObject dataProvisioningEndDate(String endDate) { var requiredUsagePermissionConstraints = Json.createObjectBuilder() - .add("@type", "LogicalConstraint") .add("and", Json.createArrayBuilder() .add(frameworkAgreementConstraint()) .add(usagePurposeConstraint()) .build()) .build(); - var dataProvisioningConstraint = Json.createObjectBuilder() - .add("@type", "LogicalConstraint") - .add("and", Json.createArrayBuilder() - .add(atomicConstraint(DATA_PROVISIONING_END_DURATION_LITERAL, "eq", duration, false)) - .build()) - .build(); + var dataProvisioningConstraint = atomicConstraint("DataProvisioningEndDate", "eq", endDate, false); return Json.createObjectBuilder() - .add("@context", "http://www.w3.org/ns/odrl.jsonld") - .add("@type", "http://www.w3.org/ns/odrl/2/Set") + .add(CONTEXT, Json.createArrayBuilder() + .add(ODRL_CONTEXT) + .add(CX_POLICY_2025_09_CONTEXT)) + .add(TYPE, "Set") + .add(ID, "id") .add("permission", Json.createArrayBuilder( List.of(Json.createObjectBuilder() .add("action", "use") - .add("constraint", requiredUsagePermissionConstraints) + .add("constraint", Json.createArrayBuilder() + .add(requiredUsagePermissionConstraints)) .build()) )) .add("obligation", Json.createArrayBuilder( List.of(Json.createObjectBuilder() .add("action", "use") - .add("constraint", dataProvisioningConstraint) + .add("constraint", Json.createArrayBuilder() + .add(dataProvisioningConstraint)) .build()) )).build(); } - public static JsonObject dataProvisioningEndDate(String endDate) { - var requiredUsagePermissionConstraints = Json.createObjectBuilder() + public static JsonObject inForceDatePolicyLegacy(String operatorStart, Object startDate, String operatorEnd, Object endDate) { + var constraint = Json.createObjectBuilder() .add("@type", "LogicalConstraint") .add("and", Json.createArrayBuilder() - .add(frameworkAgreementConstraint()) - .add(usagePurposeConstraint()) + .add(atomicConstraint("https://w3id.org/edc/v0.0.1/ns/inForceDate", operatorStart, startDate, false)) + .add(atomicConstraint("https://w3id.org/edc/v0.0.1/ns/inForceDate", operatorEnd, endDate, false)) + .add(atomicConstraint("https://w3id.org/catenax/policy/Membership", "eq", "active", false)) .build()) .build(); - var dataProvisioningConstraint = Json.createObjectBuilder() - .add("@type", "LogicalConstraint") - .add("and", Json.createArrayBuilder() - .add(atomicConstraint(DATA_PROVISIONING_END_DATE_LITERAL, "eq", endDate, false)) - .build()) - .build(); + return policy(List.of(Json.createObjectBuilder() + .add("action", "use") + .add("constraint", constraint) + .build())); + } - return Json.createObjectBuilder() - .add("@context", "http://www.w3.org/ns/odrl.jsonld") - .add("@type", "http://www.w3.org/ns/odrl/2/Set") - .add("permission", Json.createArrayBuilder( - List.of(Json.createObjectBuilder() - .add("action", "use") - .add("constraint", requiredUsagePermissionConstraints) - .build()) - )) - .add("obligation", Json.createArrayBuilder( - List.of(Json.createObjectBuilder() - .add("action", "use") - .add("constraint", dataProvisioningConstraint) - .build()) - )).build(); + private static String operatorValueWithoutNamespace(Operator operator) { + var parts = operator.getOdrlRepresentation().split("/"); + return parts[parts.length - 1]; } } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ConsumerPullBaseTest.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ConsumerPullBaseTest.java index 4360c54e3e..5fb3fdf0f7 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ConsumerPullBaseTest.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ConsumerPullBaseTest.java @@ -22,6 +22,7 @@ import com.github.tomakehurst.wiremock.junit5.WireMockExtension; import jakarta.json.JsonObject; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates; +import org.eclipse.edc.policy.model.Operator; import org.eclipse.tractusx.edc.tests.ParticipantAwareTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -167,10 +168,10 @@ protected JsonObject httpDataDestination() { } protected JsonObject createAccessPolicy(String bpn) { - return bpnPolicy(bpn); + return bpnPolicy(Operator.IS_ANY_OF, bpn); } protected JsonObject createContractPolicy(String bpn) { - return bpnPolicy(bpn); + return bpnPolicy(Operator.IS_ANY_OF, bpn); } } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java index 4c56e4003c..2cb6430398 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java @@ -47,10 +47,8 @@ import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates.COMPLETED; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.FRAMEWORK_AGREEMENT_LITERAL; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.legacyFrameworkPolicy; import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; /** @@ -80,8 +78,8 @@ void httpPushDataTransfer() { "type", "HttpData", "contentType", "application/json"); provider().createAsset(assetId, Map.of(), dataAddress); - var accessPolicyId = provider().createPolicyDefinition(bpnPolicy(consumer().getBpn())); - var policyId = provider().createPolicyDefinition(frameworkPolicy(FRAMEWORK_AGREEMENT_LITERAL, Operator.EQ, "DataExchangeGovernance:1.0", "use")); + var accessPolicyId = provider().createPolicyDefinition(bpnPolicy(Operator.IS_ANY_OF, consumer().getBpn())); + var policyId = provider().createPolicyDefinition(frameworkPolicy("FrameworkAgreement", Operator.EQ, "DataExchangeGovernance:1.0", "use", false)); provider().createContractDefinition(assetId, "def-1", accessPolicyId, policyId); var destination = httpDataAddress(destinationUrl); @@ -95,34 +93,6 @@ void httpPushDataTransfer() { server.verify(anyRequestedFor(urlPathEqualTo(MOCK_BACKEND_SOURCE_PATH))); server.verify(anyRequestedFor(urlPathEqualTo(MOCK_BACKEND_DESTINATION_PATH))); } - - @Test - void httpPushDataTransfer_withLegacyUsagePolicy() { - var sourceUrl = createMockHttpDataUrl(MOCK_BACKEND_SOURCE_PATH); - var destinationUrl = createMockHttpDataUrl(MOCK_BACKEND_DESTINATION_PATH); - - var assetId = UUID.randomUUID().toString(); - Map dataAddress = Map.of( - "name", "transfer-test", - "baseUrl", sourceUrl, - "type", "HttpData", - "contentType", "application/json"); - provider().createAsset(assetId, Map.of(), dataAddress); - var accessPolicyId = provider().createPolicyDefinition(bpnPolicy(consumer().getBpn())); - var policyId = provider().createPolicyDefinition(legacyFrameworkPolicy()); - provider().createContractDefinition(assetId, "def-1", accessPolicyId, policyId); - - var destination = httpDataAddress(destinationUrl); - var transferProcessId = consumer() - .requestAssetFrom(assetId, provider()) - .withDestination(destination) - .withTransferType("HttpData-PUSH") - .execute(); - - await().atMost(ASYNC_TIMEOUT).untilAsserted(() -> transferProcessIsInState(transferProcessId, COMPLETED)); - server.verify(anyRequestedFor(urlPathEqualTo(MOCK_BACKEND_SOURCE_PATH))); - server.verify(anyRequestedFor(urlPathEqualTo(MOCK_BACKEND_DESTINATION_PATH))); - } @Test void httpPushNonFiniteDataTransfer() { @@ -137,7 +107,7 @@ void httpPushNonFiniteDataTransfer() { "contentType", "application/json", "isNonFinite", "true"); provider().createAsset(assetId, Map.of(), dataAddress); - var policyId = provider().createPolicyDefinition(bpnPolicy(consumer().getBpn())); + var policyId = provider().createPolicyDefinition(bpnPolicy(Operator.IS_ANY_OF, consumer().getBpn())); provider().createContractDefinition(assetId, "def-1", policyId, policyId); var destination = httpDataAddress(destinationUrl); diff --git a/edc-tests/e2e/bpn-event-tests/build.gradle.kts b/edc-tests/e2e/bpn-event-tests/build.gradle.kts index 3c6acb337f..ea2c40fd72 100644 --- a/edc-tests/e2e/bpn-event-tests/build.gradle.kts +++ b/edc-tests/e2e/bpn-event-tests/build.gradle.kts @@ -32,3 +32,10 @@ dependencies { edcBuild { publish.set(false) } + +configurations.all { + resolutionStrategy { + val version = libs.versions.jsonschema.get() + force("com.networknt:json-schema-validator:${version}") + } +} diff --git a/edc-tests/e2e/catalog-tests/build.gradle.kts b/edc-tests/e2e/catalog-tests/build.gradle.kts index 9414cc8a94..6221736101 100644 --- a/edc-tests/e2e/catalog-tests/build.gradle.kts +++ b/edc-tests/e2e/catalog-tests/build.gradle.kts @@ -38,3 +38,10 @@ dependencies { edcBuild { publish.set(false) } + +configurations.all { + resolutionStrategy { + val version = libs.versions.jsonschema.get() + force("com.networknt:json-schema-validator:${version}") + } +} diff --git a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java index f6d329ed82..00d7e14c12 100644 --- a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java +++ b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java @@ -40,13 +40,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import java.util.Map; - import static java.util.stream.IntStream.range; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.controlplane.test.system.utils.PolicyFixtures.noConstraintPolicy; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_NS; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; @@ -58,9 +53,8 @@ import static org.eclipse.tractusx.edc.tests.helpers.CatalogHelperFunctions.getDatasetAssetId; import static org.eclipse.tractusx.edc.tests.helpers.CatalogHelperFunctions.getDatasetPolicies; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnGroupPolicy; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnGroupPolicyWithRightOperandAsArray; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.emptyPolicy; import static org.eclipse.tractusx.edc.tests.helpers.QueryHelperFunctions.createQuery; import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; @@ -102,8 +96,8 @@ void setup() { void requestCatalog_fulfillsPolicy_shouldReturnOffer() { // arrange PROVIDER.createAsset("test-asset"); - var ap = PROVIDER.createPolicyDefinition(noConstraintPolicy()); - var cp = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var ap = PROVIDER.createPolicyDefinition(emptyPolicy()); + var cp = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createContractDefinition("test-asset", "test-def", ap, cp); // act @@ -122,11 +116,11 @@ void requestCatalog_fulfillsPolicy_shouldReturnOffer() { @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the legacy BPN validation)") void requestCatalog_filteredByBpnLegacy_shouldReject() { var onlyConsumerPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAAAA", "BPNL123456ABCDEF", CONSUMER.getBpn()); - var onlyDiogenesPolicy = bpnPolicy("BPNLAAAAAAAAAABC"); + var onlyDiogenesPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAABC"); var onlyConsumerId = PROVIDER.createPolicyDefinition(onlyConsumerPolicy); var onlyDiogenesId = PROVIDER.createPolicyDefinition(onlyDiogenesPolicy); - var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createAsset("test-asset1"); PROVIDER.createAsset("test-asset2"); @@ -148,14 +142,11 @@ void requestCatalog_filteredByBpnLegacy_shouldReject() { void requestCatalog_filteredByBpnLegacy_WithNamespace_shouldReject() { var onlyConsumerPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAAAA", "BPNL123456ABCDEF", CONSUMER.getBpn()); - var onlyDiogenesPolicy = frameworkPolicy( - Map.of(CX_POLICY_2025_09_NS + "BusinessPartnerNumber", "BPNLAAAAAAAAAAAB"), - CX_POLICY_2025_09_NS + "access", - Operator.IS_ANY_OF); + var onlyDiogenesPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAAAB"); var onlyConsumerId = PROVIDER.createPolicyDefinition(onlyConsumerPolicy); var onlyDiogenesId = PROVIDER.createPolicyDefinition(onlyDiogenesPolicy); - var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createAsset("test-asset1"); PROVIDER.createAsset("test-asset2"); @@ -175,13 +166,13 @@ void requestCatalog_filteredByBpnLegacy_WithNamespace_shouldReject() { @DisplayName("Verify that the consumer receives only the offers he is permitted to (using BPN group validation)") void requestCatalog_filteredByBpnGroup_shouldReturnOffer() { var allowedGroup = "allowed-group"; - var accessPolicy = bpnGroupPolicyWithRightOperandAsArray(Operator.IS_ANY_OF, allowedGroup, "test-group"); + var accessPolicy = bpnGroupPolicy("isAnyOf", true, allowedGroup, "test-group"); PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), allowedGroup); PROVIDER.createAsset("test-asset"); var accessPolicyId = PROVIDER.createPolicyDefinition(accessPolicy); - var contractPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var contractPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createContractDefinition("test-asset", "def", accessPolicyId, contractPolicyId); var catalog = CONSUMER.getCatalogDatasets(PROVIDER); @@ -191,15 +182,14 @@ void requestCatalog_filteredByBpnGroup_shouldReturnOffer() { @Test @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the new BPN validation)") void requestCatalog_filteredByBpn_shouldReject() { - - var mustBeGreekPhilosopher = bpnGroupPolicy(Operator.IS_ANY_OF, "greek_customer", "philosopher"); - var mustBeGreekMathematician = bpnGroupPolicy(Operator.IS_NONE_OF, "greek_customer", "mathematician"); + var mustBeGreekPhilosopher = bpnGroupPolicy("isAnyOf", true, "greek_customer", "philosopher"); + var mustBeGreekMathematician = bpnGroupPolicy("isNoneOf", true, "greek_customer", "mathematician"); PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "greek_customer", "philosopher"); var philosopherId = PROVIDER.createPolicyDefinition(mustBeGreekPhilosopher); var mathId = PROVIDER.createPolicyDefinition(mustBeGreekMathematician); - var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createAsset("test-asset1"); PROVIDER.createAsset("test-asset2"); @@ -242,8 +232,8 @@ void requestCatalog_filteredByBpn_UsingLegacyCxPolicy_shouldReject() { void requestCatalog_multipleOffersForAsset() { PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "test-group"); PROVIDER.createAsset("asset-1"); - var noConstraintId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); - var groupConstraintId = PROVIDER.createPolicyDefinition(bpnGroupPolicy(Operator.IS_ANY_OF, "test-group")); + var noConstraintId = PROVIDER.createPolicyDefinition(emptyPolicy()); + var groupConstraintId = PROVIDER.createPolicyDefinition(bpnGroupPolicy("isAnyOf", true, "test-group")); PROVIDER.createContractDefinition("asset-1", "def1", noConstraintId, noConstraintId); PROVIDER.createContractDefinition("asset-1", "def2", groupConstraintId, noConstraintId); @@ -259,9 +249,9 @@ void requestCatalog_multipleOffersForAsset() { @Test @DisplayName("Catalog with 1000 offers") void requestCatalog_of1000Assets_shouldContainAll() { - var policy = bpnGroupPolicy(Operator.IS_NONE_OF, "test-group1", "test-group2"); + var policy = bpnGroupPolicy("isNoneOf", true, "test-group1", "test-group2"); var policyId = PROVIDER.createPolicyDefinition(policy); - var noConstraintId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var noConstraintId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "test-group-3"); range(0, 1000) @@ -284,7 +274,7 @@ void requestCatalog_of1000Assets_shouldContainAll() { private PolicyDefinition buildLegacyPolicyDefinition(String id, String leftExpression, Operator operator, Object rightExpression) { var action = Action.Builder.newInstance() - .type(CX_POLICY_NS + "access") + .type("access") .build(); var constraint = AtomicConstraint.Builder.newInstance() diff --git a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java index f807dbfd76..7ecc876885 100644 --- a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java +++ b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java @@ -31,6 +31,7 @@ import org.eclipse.edc.policy.model.Permission; import org.eclipse.edc.policy.model.Policy; import org.eclipse.edc.policy.model.PolicyType; +import org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions; import org.eclipse.tractusx.edc.tests.participant.TransferParticipant; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; import org.junit.jupiter.api.BeforeEach; @@ -39,12 +40,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.controlplane.test.system.utils.PolicyFixtures.noConstraintPolicy; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_NS; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; @@ -55,9 +51,8 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; import static org.eclipse.tractusx.edc.tests.helpers.CatalogHelperFunctions.getDatasetAssetId; import static org.eclipse.tractusx.edc.tests.helpers.CatalogHelperFunctions.getDatasetPolicies; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnGroupPolicy; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.emptyPolicy; import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; @EndToEndTest @@ -98,8 +93,8 @@ void setup() { void requestCatalog_fulfillsPolicy_shouldReturnOffer() { // arrange PROVIDER.createAsset("test-asset"); - var ap = PROVIDER.createPolicyDefinition(noConstraintPolicy()); - var cp = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var ap = PROVIDER.createPolicyDefinition(emptyPolicy()); + var cp = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createContractDefinition("test-asset", "test-def", ap, cp); // act @@ -118,11 +113,11 @@ void requestCatalog_fulfillsPolicy_shouldReturnOffer() { @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the legacy BPN validation)") void requestCatalog_filteredByBpnLegacy_shouldReject() { var onlyConsumerPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAAAA", "BPNL123456ABCDEF", CONSUMER.getBpn()); - var onlyDiogenesPolicy = bpnPolicy("BPNLAAAAAAAAAABC"); + var onlyDiogenesPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAABC"); var onlyConsumerId = PROVIDER.createPolicyDefinition(onlyConsumerPolicy); var onlyDiogenesId = PROVIDER.createPolicyDefinition(onlyDiogenesPolicy); - var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createAsset("test-asset1"); PROVIDER.createAsset("test-asset2"); @@ -142,16 +137,12 @@ void requestCatalog_filteredByBpnLegacy_shouldReject() { @Test @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the legacy BPN validation)") void requestCatalog_filteredByBpnLegacy_WithNamespace_shouldReject() { - var onlyConsumerPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAAAA", "BPNL123456ABCDEF", CONSUMER.getBpn()); - var onlyDiogenesPolicy = frameworkPolicy( - Map.of(CX_POLICY_2025_09_NS + "BusinessPartnerNumber", "BPNLAAAAAAAAAAAB"), - CX_POLICY_2025_09_NS + "access", - Operator.IS_ANY_OF); + var onlyDiogenesPolicy = bpnPolicy(Operator.IS_ANY_OF, "BPNLAAAAAAAAAABC"); var onlyConsumerId = PROVIDER.createPolicyDefinition(onlyConsumerPolicy); var onlyDiogenesId = PROVIDER.createPolicyDefinition(onlyDiogenesPolicy); - var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createAsset("test-asset1"); PROVIDER.createAsset("test-asset2"); @@ -170,15 +161,14 @@ void requestCatalog_filteredByBpnLegacy_WithNamespace_shouldReject() { @Test @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the new BPN validation)") void requestCatalog_filteredByBpn_shouldReject() { - - var mustBeGreekPhilosopher = bpnGroupPolicy(Operator.IS_ANY_OF, "greek_customer", "philosopher"); - var mustBeGreekMathematician = bpnGroupPolicy(Operator.IS_NONE_OF, "greek_customer", "mathematician"); + var mustBeGreekPhilosopher = PolicyHelperFunctions.bpnGroupPolicy("isAnyOf", true, "greek_customer", "philosopher"); + var mustBeGreekMathematician = PolicyHelperFunctions.bpnGroupPolicy("isNoneOf", true, "greek_customer", "mathematician"); PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "greek_customer", "philosopher"); var philosopherId = PROVIDER.createPolicyDefinition(mustBeGreekPhilosopher); var mathId = PROVIDER.createPolicyDefinition(mustBeGreekMathematician); - var noConstraintPolicyId = PROVIDER.createPolicyDefinition(noConstraintPolicy()); + var noConstraintPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createAsset("test-asset1"); PROVIDER.createAsset("test-asset2"); @@ -218,7 +208,7 @@ void requestCatalog_filteredByBpn_UsingLegacyCxPolicy_shouldReject() { private PolicyDefinition buildLegacyPolicyDefinition(String id, String leftExpression, Operator operator, Object rightExpression) { var action = Action.Builder.newInstance() - .type(CX_POLICY_NS + "access") + .type("access") .build(); var constraint = AtomicConstraint.Builder.newInstance() diff --git a/edc-tests/e2e/dcp-tests/build.gradle.kts b/edc-tests/e2e/dcp-tests/build.gradle.kts index 2cc8116abc..f9979e4d8e 100644 --- a/edc-tests/e2e/dcp-tests/build.gradle.kts +++ b/edc-tests/e2e/dcp-tests/build.gradle.kts @@ -56,3 +56,10 @@ dependencies { edcBuild { publish.set(false) } + +configurations.all { + resolutionStrategy { + val version = libs.versions.jsonschema.get() + force("com.networknt:json-schema-validator:${version}") + } +} diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java index bc9e127c1b..a4dadbff9c 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java @@ -33,6 +33,7 @@ import org.eclipse.edc.identityhub.spi.verifiablecredentials.model.VerifiableCredentialResource; import org.eclipse.edc.identityhub.spi.verifiablecredentials.store.CredentialStore; import org.eclipse.edc.junit.extensions.RuntimeExtension; +import org.eclipse.edc.policy.model.Operator; import org.eclipse.edc.spi.query.Criterion; import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.tractusx.edc.tests.participant.DataspaceIssuer; @@ -69,7 +70,6 @@ import static org.awaitility.Awaitility.await; import static org.awaitility.pollinterval.FibonacciPollInterval.fibonacci; import static org.eclipse.edc.util.io.Ports.getFreePort; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; @@ -336,7 +336,7 @@ void catalogRequest_whenRequestedCredentialMissing() { @Override protected JsonObject createContractPolicy(String bpn) { - return frameworkPolicy(Map.of(CX_POLICY_2025_09_NS + "Membership", "active"), CX_POLICY_2025_09_NS + "access"); + return frameworkPolicy("Membership", Operator.EQ, "active", "access", false); } protected abstract RuntimeExtension credentialStoreRuntime(); @@ -347,8 +347,8 @@ private static class ValidContractPolicyProvider implements ArgumentsProvider { @Override public Stream provideArguments(ExtensionContext extensionContext) { return Stream.of( - Arguments.of(frameworkPolicy(Map.of(CX_POLICY_2025_09_NS + "Membership", "active"), CX_POLICY_2025_09_NS + "access"), "MembershipCredential"), - Arguments.of(frameworkPolicy(Map.of(CX_POLICY_2025_09_NS + "FrameworkAgreement", "DataExchangeGovernance:1.0"), "use"), "DataExchangeGovernance use case") + Arguments.of(frameworkPolicy("Membership", Operator.EQ, "active", "access", false), "MembershipCredential"), + Arguments.of(frameworkPolicy("FrameworkAgreement", Operator.EQ, "DataExchangeGovernance:1.0", "use", false), "DataExchangeGovernance use case") ); } } diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java index 0ff65e3652..305a4aac93 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java @@ -32,6 +32,7 @@ import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.junit.utils.LazySupplier; +import org.eclipse.edc.policy.model.Operator; import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.edc.spi.result.Result; @@ -221,7 +222,7 @@ void withMock(Function dataAddress) { PROVIDER.createAsset(assetId, Map.of(), dataAddress); - var policyId = PROVIDER.createPolicyDefinition(bpnPolicy(CONSUMER.getBpn())); + var policyId = PROVIDER.createPolicyDefinition(bpnPolicy(Operator.IS_ANY_OF, CONSUMER.getBpn())); PROVIDER.createContractDefinition(assetId, contractDefinitionId, policyId, policyId); return CONSUMER.requestAssetFrom(assetId, PROVIDER) diff --git a/edc-tests/e2e/management-tests/build.gradle.kts b/edc-tests/e2e/management-tests/build.gradle.kts index f17990b786..02dca60a84 100644 --- a/edc-tests/e2e/management-tests/build.gradle.kts +++ b/edc-tests/e2e/management-tests/build.gradle.kts @@ -33,3 +33,10 @@ dependencies { edcBuild { publish.set(false) } + +configurations.all { + resolutionStrategy { + val version = libs.versions.jsonschema.get() + force("com.networknt:json-schema-validator:${version}") + } +} diff --git a/edc-tests/e2e/policy-tests/build.gradle.kts b/edc-tests/e2e/policy-tests/build.gradle.kts index d51250bdba..3658450fde 100644 --- a/edc-tests/e2e/policy-tests/build.gradle.kts +++ b/edc-tests/e2e/policy-tests/build.gradle.kts @@ -36,3 +36,10 @@ dependencies { edcBuild { publish.set(false) } + +configurations.all { + resolutionStrategy { + val version = libs.versions.jsonschema.get() + force("com.networknt:json-schema-validator:${version}") + } +} diff --git a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java index 762dba72ac..3622a70c08 100644 --- a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java +++ b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java @@ -25,6 +25,7 @@ import io.restassured.response.Response; import jakarta.json.Json; import jakarta.json.JsonObject; +import jakarta.json.JsonValue; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.policy.model.Operator; @@ -41,13 +42,17 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Stream; +import static com.apicatalog.jsonld.lang.Keywords.ID; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT_V2; import static org.eclipse.tractusx.edc.cx.CxJsonLdExtension.CX_POLICY_2025_09_CONTEXT; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; @@ -64,6 +69,7 @@ @EndToEndTest public class PolicyDefinitionEndToEndTest { + private static final TransferParticipant CONSUMER = TransferParticipant.Builder.newInstance() .name(CONSUMER_NAME) .id(CONSUMER_DID) @@ -88,113 +94,113 @@ public class PolicyDefinitionEndToEndTest { private static final RuntimeExtension PROVIDER_RUNTIME = pgRuntime(PROVIDER, POSTGRES); @DisplayName("Policy is accepted") - @ParameterizedTest(name = "{1}") + @ParameterizedTest(name = "{2}") @ArgumentsSource(ValidContractPolicyProvider.class) - void shouldAcceptValidPolicyDefinitions(JsonObject policy, String description) { - PROVIDER.createPolicyDefinition(policy); - } - - @DisplayName("Policy is not accepted due to missing context") - @ParameterizedTest(name = "{1}") - @ArgumentsSource(InValidNamespaceContractPolicyProvider.class) - void shouldNotAcceptInvalidNamespacePolicyDefinitions(JsonObject policy, String description) { - checkForValidationFailure(policy); + void shouldAcceptValidPolicyDefinitions(ManagementApiVersion apiVersion, JsonObject policy, String description) { + var response = createPolicyDefinition(apiVersion, policy); + assertThat(response.statusCode()).isEqualTo(200); } @DisplayName("Policy is not accepted because definition is not correct") - @ParameterizedTest(name = "{1}") - @ArgumentsSource(InValidContractPolicyProvider.class) - void shouldNotAcceptInvalidPolicyDefinitions(JsonObject policy, String description) { - checkForValidationFailure(policy); + @ParameterizedTest(name = "{2}") + @ArgumentsSource(InvalidContractPolicyProvider.class) + void shouldNotAcceptInvalidPolicyDefinitions(ManagementApiVersion apiVersion, JsonObject policy, String description) { + checkForValidationFailure(apiVersion, policy); } - private void checkForValidationFailure(JsonObject policy) { - var response = createPolicyDefinition(policy); + private void checkForValidationFailure(ManagementApiVersion apiVersion, JsonObject policy) { + var response = createPolicyDefinition(apiVersion, policy); assertThat(response.statusCode()).isEqualTo(400); assertThat(response.body().jsonPath().getString("[0].type")).isEqualTo("ValidationFailure"); } - private abstract static class BasePolicyProvider implements ArgumentsProvider { + private abstract static class ApiVersionsArgumentsProvider implements ArgumentsProvider { + List apiVersions = List.of(ManagementApiVersion.V3, ManagementApiVersion.V4); - protected final String namespace; + protected abstract Stream arguments(); - private BasePolicyProvider(String namespace) { - this.namespace = namespace; + /** + * Creates a new set of arguments, where every combination of arguments from the subclass + * is combined with management API versions v3 & v4. + * + * @param extensionContext the current extension context; never {@code null} + * @return a stream of arguments, where each combination of original arguments is paired with both management API versions (v3 & v4) + */ + @Override + public Stream provideArguments(ExtensionContext extensionContext) { + return arguments() + .flatMap(arguments -> apiVersions.stream() + .map(apiVersion -> { + var newParams = new ArrayList<>(); + newParams.add(apiVersion); + newParams.addAll(Arrays.asList(arguments.get())); + return Arguments.of(newParams.toArray()); + })); } + } + + private static class ValidContractPolicyProvider extends ApiVersionsArgumentsProvider { @Override - public Stream provideArguments(ExtensionContext extensionContext) { + public Stream arguments() { return Stream.of( - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("Membership", "active"), "use", Operator.EQ, false)), "MembershipCredential"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("FrameworkAgreement", "DataExchangeGovernance:1.0"), "use", Operator.EQ, false)), "DataExchangeGovernance use case"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("AffiliatesRegion", List.of("cx.region.all:1", "cx.region.europe:1", "cx.region.northAmerica:1")), "use", Operator.IS_ANY_OF, true)), "Affiliates Region"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("AffiliatesRegion", List.of("cx.region.europe:1")), "use", Operator.IS_ANY_OF, true)), "Affiliates Region (IS_ANY_OF, one element)"), - Arguments.of(policyFromRules("permission", namespace, - frameworkConstraint(Map.of("AffiliatesBpnl", "BPNL00000000001A"), "use", Operator.IS_ANY_OF, false)), "Affiliates BPNL"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", + frameworkConstraint(Map.of("AffiliatesBpnl", "BPNL00000000001A"), "use", Operator.IS_ANY_OF, true)), "Affiliates BPNL"), + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("DataFrequency", "cx.dataFrequency.once:1"), "use", Operator.EQ, false)), "Data Frequency"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("DataUsageEndDate", "2025-06-30T14:30:00Z"), "use", Operator.EQ, false)), "Data Usage End Date"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("DataUsageEndDefinition", "cx.dataUsageEnd.unlimited:1"), "use", Operator.EQ, false)), "Data Usage End Date Definition"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("DataUsageEndDurationDays", 3), "use", Operator.EQ, false)), "Data Usage End Duration Days"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("JurisdictionLocation", "test location"), "use", Operator.EQ, false)), "Jurisdiction Location"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("JurisdictionLocationReference", "cx.location.dataConsumer:1"), "use", Operator.EQ, false)), "Jurisdiction Location Reference"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("Liability", "cx.grossNegligence:1"), "use", Operator.EQ, false)), "Liability"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("Liability", "cx.slightNegligence:1"), "use", Operator.EQ, false)), "Liability"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("Precedence", "cx.precedence.contractReference:1"), "use", Operator.EQ, false)), "Precedence"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("UsagePurpose", List.of("cx.core.legalRequirementForThirdparty:1", "cx.core.industrycore:1")), "use", Operator.IS_ANY_OF, true)), "Usage Purpose"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("VersionChanges", "cx.versionChanges.minor:1"), "use", Operator.EQ, false)), "Version Changes"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("Warranty", "cx.warranty.none:1"), "use", Operator.EQ, false)), "Warranty"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("WarrantyDefinition", "cx.warranty.contractEndDate:1"), "use", Operator.EQ, false)), "Warranty Definition"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("WarrantyDurationMonths", 3), "use", Operator.EQ, false)), "Warranty Duration Months"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("ExclusiveUsage", "cx.exclusiveUsage.dataConsumer:1"), "use", Operator.EQ, false)), "Exclusive Usage"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("ContractReference", List.of("contractReference")), "use", Operator.IS_ALL_OF, true)), "Contract reference"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("ContractTermination", "cx.data.deletion:1"), "use", Operator.EQ, false)), "ContractTermination"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("ConfidentialInformationMeasures", "cx.confidentiality.measures:1"), "use", Operator.EQ, false)), "Confidential Information Measures"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("ConfidentialInformationSharing", List.of("cx.sharing.affiliates:1")), "use", Operator.IS_ANY_OF, true)), "Confidential Information Sharing"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("BusinessPartnerGroup", List.of("Some-group")), "access", Operator.IS_ANY_OF, true)), "Business Partner Group"), - Arguments.of(policyFromRules("permission", namespace, - frameworkConstraint(Map.of("BusinessPartnerNumber", List.of("BPNL00000000001A")), "access", Operator.IS_ANY_OF, true)), "Business Partner Number") - ); - } - } - - private static class ValidContractPolicyProvider extends BasePolicyProvider { - - private ValidContractPolicyProvider() { - super(CX_POLICY_2025_09_CONTEXT); - } - - @Override - public Stream provideArguments(ExtensionContext extensionContext) { - return Stream.concat(super.provideArguments(extensionContext), Stream.of( + Arguments.of(policyFromRules("permission", + frameworkConstraint(Map.of("BusinessPartnerNumber", List.of("BPNL00000000001A")), "access", Operator.IS_ANY_OF, true)), "Business Partner Number"), Arguments.of( emptyPolicy(), "Empty Policy"), Arguments.of( - policyWithEmptyRule("access", this.namespace), + policyWithEmptyRule("access"), "Access policy with empty permission"), Arguments.of( dataUsageEndDurationDays(1), @@ -202,74 +208,80 @@ public Stream provideArguments(ExtensionContext extensionCo Arguments.of( dataUsageEndDate(Instant.now().plus(1, ChronoUnit.SECONDS).truncatedTo(ChronoUnit.SECONDS).toString()), "Enforce data usage end date 1 second in the future") - )); - } - } - - private static class InValidNamespaceContractPolicyProvider extends BasePolicyProvider { - - private InValidNamespaceContractPolicyProvider() { - super(""); + ); } } - private static class InValidContractPolicyProvider extends BasePolicyProvider { - - private InValidContractPolicyProvider() { - super(CX_POLICY_2025_09_CONTEXT); - } + private static class InvalidContractPolicyProvider extends ApiVersionsArgumentsProvider { @Override - public Stream provideArguments(ExtensionContext extensionContext) { + public Stream arguments() { return Stream.of( - Arguments.of(policyWithEmptyRule("use", this.namespace), "Usage policy with empty permission"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyWithEmptyRule("use"), "Usage policy with empty permission"), + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("Membership", "active"), "access", Operator.EQ, false), frameworkConstraint(Map.of("UsagePurpose", List.of("cx.core.industrycore:1")), "use", Operator.IS_ANY_OF, true)), "Policy with different actions types"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("Membership", "active"), "unknown-action", Operator.EQ, false)), "Policy with unknown actions types"), - Arguments.of(policyFromRules("prohibition", namespace, + Arguments.of(policyFromRules("prohibition", frameworkConstraint(Map.of("Membership", "active"), "access", Operator.EQ, false)), "Access Policy with prohibition rule"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("UsagePurpose", "cx.core.industrycore:1"), "access", Operator.EQ, false)), "Access policy permission with not allowed constraints"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("BusinessPartnerNumber", "BPN0022232"), "use", Operator.EQ, false)), "Usage policy permission with not allowed constraints"), - Arguments.of(policyFromRules("prohibition", namespace, + Arguments.of(policyFromRules("prohibition", frameworkConstraint(Map.of("AffiliatesRegion", "cx.region.europe:1"), "use", Operator.EQ, false)), "Usage policy prohibition with not allowed constraints"), - Arguments.of(policyFromRules("obligation", namespace, + Arguments.of(policyFromRules("obligation", frameworkConstraint(Map.of("UsagePurpose", "cx.core.industrycore:1"), "use", Operator.EQ, false)), "Usage policy obligation with not allowed constraints"), - Arguments.of(policyFromRules("permission", namespace, + Arguments.of(policyFromRules("permission", frameworkConstraint(Map.of("WarrantyDurationMonths", 3), "use", Operator.EQ, false), frameworkConstraint(Map.of("WarrantyDefinition", "cx.warranty.contractEndDate:1"), "use", Operator.EQ, false)), "Policy with mutually exclusive constraints") ); } } - private Response createPolicyDefinition(JsonObject policy) { - JsonObject requestBody = Json.createObjectBuilder().add("@context", - Json.createObjectBuilder().add("@vocab", "https://w3id.org/edc/v0.0.1/ns/")).add("@type", "PolicyDefinition").add("policy", policy).build(); - return (Response) PROVIDER.baseManagementRequest().basePath("/v3").contentType(ContentType.JSON).body(requestBody).when().post("/policydefinitions", new Object[0]).then().extract(); + private Response createPolicyDefinition(ManagementApiVersion apiVersion, JsonObject policy) { + JsonValue context; + switch (apiVersion) { + case V3 -> context = Json.createObjectBuilder() + .add("@vocab", "https://w3id.org/edc/v0.0.1/ns/") + .build(); + case V4 -> context = Json.createValue(EDC_CONNECTOR_MANAGEMENT_CONTEXT_V2); + default -> context = null; + } + + var requestBody = Json.createObjectBuilder() + .add(CONTEXT, context) + .add(TYPE, "PolicyDefinition") + .add("policy", policy) + .build(); + return (Response) PROVIDER.baseManagementRequest() + .basePath("/%s".formatted(apiVersion.apiPath)) + .contentType(ContentType.JSON) + .body(requestBody) + .when() + .post("/policydefinitions", new Object[0]) + .then().extract(); } - private static JsonObject policyFromRules(String ruleType, String policyDefinition, JsonObject... rules) { + private static JsonObject policyFromRules(String ruleType, JsonObject... rules) { var rulesArrayBuilder = Json.createArrayBuilder(); for (JsonObject rule : rules) { rulesArrayBuilder.add(rule); } var contextArrayBuilder = Json.createArrayBuilder(); contextArrayBuilder.add(ODRL_CONTEXT); - if (!policyDefinition.isBlank()) { - contextArrayBuilder.add(policyDefinition); - } + contextArrayBuilder.add(CX_POLICY_2025_09_CONTEXT); return Json.createObjectBuilder() + .add(ID, "id") .add(CONTEXT, contextArrayBuilder) .add(TYPE, "Set") .add(ruleType, rulesArrayBuilder) .build(); } - private static JsonObject policyWithEmptyRule(String action, String policyContext) { + private static JsonObject policyWithEmptyRule(String action) { var rule = Json.createObjectBuilder() .add("action", action) .build(); @@ -277,12 +289,24 @@ private static JsonObject policyWithEmptyRule(String action, String policyContex rulesArrayBuilder.add(rule); var contextArrayBuilder = Json.createArrayBuilder(); contextArrayBuilder.add(ODRL_CONTEXT); - contextArrayBuilder.add(policyContext); + contextArrayBuilder.add(CX_POLICY_2025_09_CONTEXT); return Json.createObjectBuilder() + .add(ID, "id") .add(CONTEXT, contextArrayBuilder) .add(TYPE, "Set") .add("permission", rulesArrayBuilder) .build(); } + + private enum ManagementApiVersion { + V3("v3"), + V4("v4"); + + final String apiPath; + + ManagementApiVersion(String apiPath) { + this.apiPath = apiPath; + } + } } diff --git a/edc-tests/e2e/transfer-tests/build.gradle.kts b/edc-tests/e2e/transfer-tests/build.gradle.kts index 307ad673b2..c605b6aa64 100644 --- a/edc-tests/e2e/transfer-tests/build.gradle.kts +++ b/edc-tests/e2e/transfer-tests/build.gradle.kts @@ -39,3 +39,10 @@ dependencies { edcBuild { publish.set(false) } + +configurations.all { + resolutionStrategy { + val version = libs.versions.jsonschema.get() + force("com.networknt:json-schema-validator:${version}") + } +} diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java index cb300c566f..fec936b1d0 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java @@ -27,7 +27,6 @@ import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.policy.model.Operator; -import org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions; import org.eclipse.tractusx.edc.tests.participant.TransferParticipant; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; import org.junit.jupiter.api.BeforeEach; @@ -42,7 +41,6 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; @@ -51,6 +49,8 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnGroupPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_POLL_INTERVAL; import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; @@ -108,8 +108,8 @@ void retireAgreement_shouldCloseTransferProcesses() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "test-group1"); - var accessPolicy = PROVIDER.createPolicyDefinition(PolicyHelperFunctions.bpnGroupPolicy(Operator.IS_ANY_OF, "test-group1")); - var policy = PolicyHelperFunctions.frameworkPolicy(Map.of(), CX_POLICY_2025_09_NS + "access"); + var accessPolicy = PROVIDER.createPolicyDefinition(bpnGroupPolicy("isAnyOf", true, "test-group1")); + var policy = frameworkPolicy("Membership", Operator.EQ, "active", "use", false); var contractPolicy = PROVIDER.createPolicyDefinition(policy); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicy, contractPolicy); diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java index 6f3c7f9015..b98c7d63e3 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java @@ -25,6 +25,7 @@ import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; +import org.eclipse.edc.policy.model.Operator; import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.eclipse.tractusx.edc.tests.MockBdrsClient; @@ -247,10 +248,10 @@ private JsonObject httpDataDestination() { } protected JsonObject createAccessPolicy(String bpn) { - return bpnPolicy(bpn); + return bpnPolicy(Operator.IS_ANY_OF, bpn); } protected JsonObject createContractPolicy(String bpn) { - return bpnPolicy(bpn); + return bpnPolicy(Operator.IS_ANY_OF, bpn); } } diff --git a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts index df2f0735e6..6ba3f022e2 100644 --- a/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts +++ b/edc-tests/runtime/dcp/runtime-memory-dcp-ih/build.gradle.kts @@ -42,12 +42,6 @@ dependencies { exclude("org.eclipse.edc", "data-plane-selector-client") } - constraints { - implementation("com.networknt:json-schema-validator:3.0.6") { - because("older versions cause runtime issues") - } - } - implementation(libs.edc.core.controlplane) implementation(libs.edc.core.did) implementation(libs.edc.decentralized.claims.transform) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a0a55910fa..52d3406f3d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,7 @@ common-tck = "1.0.0" flyway = "12.11.0" jackson = "2.22.1" jakarta-json = "2.1.3" +jsonschema = "2.0.0" junit = "6.1.2" kafka = "3.9.1" nimbus = "10.9.1" @@ -97,8 +98,10 @@ edc-auth-oauth2-client = { module = "org.eclipse.edc:oauth2-client", version.ref edc-transaction-local = { module = "org.eclipse.edc:transaction-local", version.ref = "edc" } edc-ext-http = { module = "org.eclipse.edc:http", version.ref = "edc" } edc-ext-jsonld = { module = "org.eclipse.edc:json-ld", version.ref = "edc" } +edc-lib-jsonld = { module = "org.eclipse.edc:json-ld-lib", version.ref = "edc" } edc-validator-data-address-http-data = { module = "org.eclipse.edc:validator-data-address-http-data", version.ref = "edc" } edc-runtime-metamodel = { module = "org.eclipse.edc:runtime-metamodel", version.ref = "edc" } +edc-api-management-validator-jsonschema = { module = "org.eclipse.edc:management-api-schema-validator", version.ref = "edc" } # EDC lib dependencies edc-lib-api = { module = "org.eclipse.edc:api-lib", version.ref = "edc" } @@ -225,6 +228,7 @@ flyway-database-postgres = { module = "org.flywaydb:flyway-database-postgresql", jacksonJsonP = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp", version.ref = "jackson" } jakarta-rsApi = { module = "jakarta.ws.rs:jakarta.ws.rs-api", version.ref = "rsApi" } jakartaJson = { module = "jakarta.json:jakarta.json-api", version.ref = "jakarta-json" } +jsonschema = { module = "com.networknt:json-schema-validator", version.ref = "jsonschema" } kafka-clients = { module = "org.apache.kafka:kafka-clients", version.ref = "kafka" } nimbus-jwt = { module = "com.nimbusds:nimbus-jose-jwt", version.ref = "nimbus" } okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } From ee7ac72cfb14093cbeeded3aa07103dca8175381 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:09:19 +0200 Subject: [PATCH 221/259] chore(deps): bump the github-actions-all group across 2 directories with 7 updates (#2990) Bumps the github-actions-all group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [github/codeql-action/init](https://github.com/github/codeql-action) | `4.37.1` | `4.37.3` | | [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.37.1` | `4.37.3` | | [actions/setup-python](https://github.com/actions/setup-python) | `6.3.0` | `7.0.0` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.1` | `4.37.3` | | [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) | `3.95.9` | `3.96.0` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.6.0` | `0.6.1` | Bumps the github-actions-all group with 1 update in the /.github/actions/publish-docker-image directory: [docker/login-action](https://github.com/docker/login-action). Updates `github/codeql-action/init` from 4.37.1 to 4.37.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81) Updates `github/codeql-action/analyze` from 4.37.1 to 4.37.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81) Updates `actions/setup-python` from 6.3.0 to 7.0.0 - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/ece7cb06caefa5fff74198d8649806c4678c61a1...5fda3b95a4ea91299a34e894583c3862153e4b97) Updates `github/codeql-action/upload-sarif` from 4.37.1 to 4.37.3 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/7188fc363630916deb702c7fdcf4e481b751f97a...e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81) Updates `trufflesecurity/trufflehog` from 3.95.9 to 3.96.0 - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/27b0417c16317ca9a472a9a8092acce143b49c55...6f3c981e7b77f235fd2702dd74af25fc4b72bf11) Updates `zizmorcore/zizmor-action` from 0.6.0 to 0.6.1 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/6599ee8b7a49aef6a770f63d261d214911a7ce02...6fc4b006235f201fdab3722e17240ab420d580e5) Updates `docker/login-action` from 4.4.0 to 4.5.1 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/af1e73f918a031802d376d3c8bbc3fe56130a9b0...abd2ef45e78c5afb21d64d4ca52ee8550d9572c7) --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.37.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/analyze dependency-version: 4.37.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: actions/setup-python dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions-all - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: trufflesecurity/trufflehog dependency-version: 3.96.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: zizmorcore/zizmor-action dependency-version: 0.6.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: docker/login-action dependency-version: 4.5.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- .github/workflows/codeql.yaml | 4 ++-- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 2 +- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/workflow-security-lint.yaml | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index b91f83a547..b7e81dbba7 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -66,7 +66,7 @@ runs: # Login to DockerHub ##################### - name: DockerHub login - uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0 + uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 with: username: ${{ inputs.docker_user }} password: ${{ inputs.docker_token }} diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 7ddd42175d..4e13a338f7 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 + uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 + uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index cbf48f195e..bb036a4794 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -58,7 +58,7 @@ jobs: persist-credentials: false - uses: ./.github/actions/setup-helm - name: python (setup) - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: 3.13 - name: chart-testing (setup) diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index eb8a1db4d3..3e3bb2c855 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 + uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 6f8d73a383..f6474af527 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -53,7 +53,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@27b0417c16317ca9a472a9a8092acce143b49c55 + uses: trufflesecurity/trufflehog@6f3c981e7b77f235fd2702dd74af25fc4b72bf11 continue-on-error: true with: path: ./ # Scan the entire repository diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 189b680a01..b7a367bf10 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -56,7 +56,7 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 # v0.6.0 + uses: zizmorcore/zizmor-action@6fc4b006235f201fdab3722e17240ab420d580e5 # v0.6.1 with: version: "1.23.1" advanced-security: "true" @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1 + uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 if: always() with: sarif_file: results-fixed.sarif From f864606d45339e87b55b7cc20974560f018b8bd3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:09:58 +0200 Subject: [PATCH 222/259] chore(deps): bump the database group with 2 updates (#2986) Bumps the database group with 2 updates: org.flywaydb:flyway-core and org.flywaydb:flyway-database-postgresql. Updates `org.flywaydb:flyway-core` from 12.11.0 to 13.0.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.11.0 to 13.0.0 Updates `org.flywaydb:flyway-database-postgresql` from 12.11.0 to 13.0.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 13.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 13.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 13.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: database ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 52d3406f3d..4b8384cd43 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" -flyway = "12.11.0" +flyway = "13.0.0" jackson = "2.22.1" jakarta-json = "2.1.3" jsonschema = "2.0.0" From d8a95537ad0ebb520eecface4c3ec9f3e1e2a252 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:10:15 +0200 Subject: [PATCH 223/259] chore(deps): bump the cloud-sdks group with 2 updates (#2985) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.48.2 to 2.49.1 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.48.2 to 2.49.1 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.48.2 to 2.49.1 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.49.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.49.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.49.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4b8384cd43..b46d903c1d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.3" awaitility = "4.3.0" -aws = "2.48.2" +aws = "2.49.1" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" From aa2b79084913f1637a842d1dd347d7609581db70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:10:37 +0200 Subject: [PATCH 224/259] chore(deps): bump the logging group with 3 updates (#2983) Bumps the logging group with 3 updates: [io.opentelemetry.javaagent:opentelemetry-javaagent](https://github.com/open-telemetry/opentelemetry-java-instrumentation), [io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations](https://github.com/open-telemetry/opentelemetry-java-instrumentation) and [io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17](https://github.com/open-telemetry/opentelemetry-java-instrumentation). Updates `io.opentelemetry.javaagent:opentelemetry-javaagent` from 2.29.0 to 2.30.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.29.0...v2.30.0) Updates `io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations` from 2.29.0 to 2.30.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/compare/v2.29.0...v2.30.0) Updates `io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17` from 2.29.0-alpha to 2.30.0-alpha - [Release notes](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-java-instrumentation/commits) --- updated-dependencies: - dependency-name: io.opentelemetry.javaagent:opentelemetry-javaagent dependency-version: 2.30.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: logging - dependency-name: io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations dependency-version: 2.30.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: logging - dependency-name: io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 dependency-version: 2.30.0-alpha dependency-type: direct:production update-type: version-update:semver-minor dependency-group: logging ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b46d903c1d..582e760005 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,9 +20,9 @@ junit = "6.1.2" kafka = "3.9.1" nimbus = "10.9.1" okhttp = "5.4.0" -opentelemetry = "2.29.0" -opentelemetry-instrumentation = "2.29.0" -opentelemetry-log4j-appender = "2.29.0-alpha" +opentelemetry = "2.30.0" +opentelemetry-instrumentation = "2.30.0" +opentelemetry-log4j-appender = "2.30.0-alpha" postgres = "42.7.13" restAssured = "6.0.1" rsApi = "4.0.0" From 21506715facee5180b827face96ada5e4e83d52d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:11:09 +0200 Subject: [PATCH 225/259] chore(deps): bump the test-dependencies group with 2 updates (#2981) Bumps the test-dependencies group with 2 updates: [io.qameta.allure:allure-junit5](https://github.com/allure-framework/allure-java) and [com.github.dasniko:testcontainers-keycloak](https://github.com/dasniko/testcontainers-keycloak). Updates `io.qameta.allure:allure-junit5` from 2.35.3 to 2.35.4 - [Release notes](https://github.com/allure-framework/allure-java/releases) - [Commits](https://github.com/allure-framework/allure-java/compare/2.35.3...2.35.4) Updates `com.github.dasniko:testcontainers-keycloak` from 4.3.0 to 4.3.1 - [Release notes](https://github.com/dasniko/testcontainers-keycloak/releases) - [Commits](https://github.com/dasniko/testcontainers-keycloak/compare/v4.3.0...v4.3.1) --- updated-dependencies: - dependency-name: io.qameta.allure:allure-junit5 dependency-version: 2.35.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: test-dependencies - dependency-name: com.github.dasniko:testcontainers-keycloak dependency-version: 4.3.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: test-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 582e760005..fd9f640a60 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ format.version = "1.1" [versions] edc = "0.17.0" edc-build = "1.5.2" -allure = "2.35.3" +allure = "2.35.4" awaitility = "4.3.0" aws = "2.49.1" azure-storage-blob = "12.35.0" @@ -27,7 +27,7 @@ postgres = "42.7.13" restAssured = "6.0.1" rsApi = "4.0.0" testcontainers = "2.0.5" -testcontainers-keycloak = "4.3.0" +testcontainers-keycloak = "4.3.1" titanium = "1.7.0" log4j2 = "2.26.1" wiremock = "3.13.2" From 460fd8c91f02d3e7becff3e3494413ee141fdc3e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:44:39 +0200 Subject: [PATCH 226/259] chore(deps): bump com.gradleup.shadow in the build-tooling group (#2982) Bumps the build-tooling group with 1 update: [com.gradleup.shadow](https://github.com/GradleUp/shadow). Updates `com.gradleup.shadow` from 9.6.0 to 9.6.1 - [Release notes](https://github.com/GradleUp/shadow/releases) - [Commits](https://github.com/GradleUp/shadow/compare/9.6.0...9.6.1) --- updated-dependencies: - dependency-name: com.gradleup.shadow dependency-version: 9.6.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tooling ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fd9f640a60..4b8dda9b51 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -261,6 +261,6 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } -shadow = { id = "com.gradleup.shadow", version = "9.6.0" } +shadow = { id = "com.gradleup.shadow", version = "9.6.1" } swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.52" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From 01c9c3d72409875e77f78de0dd21a4c6030482d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 09:45:36 +0200 Subject: [PATCH 227/259] chore(deps): bump org.apache.kafka:kafka-clients from 3.9.1 to 4.3.1 (#2987) * chore(deps): bump org.apache.kafka:kafka-clients from 3.9.1 to 4.3.1 Bumps org.apache.kafka:kafka-clients from 3.9.1 to 4.3.1. --- updated-dependencies: - dependency-name: org.apache.kafka:kafka-clients dependency-version: 4.3.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * feat: add to existing dependabot group --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: AndrYurk --- .github/dependabot.yml | 1 + gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index aa716f2bb3..c7efc523fa 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -83,6 +83,7 @@ updates: patterns: - "org.postgresql*" - "org.flywaydb*" + - "org.apache.kafka*" # Github Actions - diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4b8dda9b51..716e9036e3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -17,7 +17,7 @@ jackson = "2.22.1" jakarta-json = "2.1.3" jsonschema = "2.0.0" junit = "6.1.2" -kafka = "3.9.1" +kafka = "4.3.1" nimbus = "10.9.1" okhttp = "5.4.0" opentelemetry = "2.30.0" From ea6c7ccf4c536d41f6067f84f072ced0ce9799b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 31 Jul 2026 10:00:09 +0200 Subject: [PATCH 228/259] chore(deps): bump the cloud-sdks group with 2 updates (#2991) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.49.1 to 2.49.2 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.49.1 to 2.49.2 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.49.1 to 2.49.2 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.49.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.49.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.49.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 716e9036e3..325335c27d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.4" awaitility = "4.3.0" -aws = "2.49.1" +aws = "2.49.2" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" From c6e6e0d792a83f9cc2233be49ac4ab156233319c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 09:06:05 +0200 Subject: [PATCH 229/259] chore(deps): bump the cloud-sdks group with 2 updates (#2997) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.49.2 to 2.50.0 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.49.2 to 2.50.0 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.49.2 to 2.50.0 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.50.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.50.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.50.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 325335c27d..bba946d8ae 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.4" awaitility = "4.3.0" -aws = "2.49.2" +aws = "2.50.0" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" From 8118769ea1acde682688292be8f31090ac55b524 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 11:00:05 +0200 Subject: [PATCH 230/259] chore(deps): bump the database group with 2 updates (#2998) Bumps the database group with 2 updates: org.flywaydb:flyway-core and org.flywaydb:flyway-database-postgresql. Updates `org.flywaydb:flyway-core` from 13.0.0 to 13.1.0 Updates `org.flywaydb:flyway-database-postgresql` from 13.0.0 to 13.1.0 Updates `org.flywaydb:flyway-database-postgresql` from 13.0.0 to 13.1.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 13.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 13.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 13.1.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bba946d8ae..641aa1f765 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" -flyway = "13.0.0" +flyway = "13.1.0" jackson = "2.22.1" jakarta-json = "2.1.3" jsonschema = "2.0.0" From db02648e2dd1678a9feeae6551848992e875f274 Mon Sep 17 00:00:00 2001 From: Mathias Moser Date: Fri, 7 Aug 2026 13:34:36 +0200 Subject: [PATCH 231/259] chore: Revise project description in CONTRIBUTING.md (#3000) Updated project description and license information. --- CONTRIBUTING.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f9cbd34489..3450c95d2c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,21 +4,11 @@ Thanks for your interest in this project. ## Project description -The companies involved want to increase the automotive industry's -competitiveness, improve efficiency through industry-specific cooperation and -accelerate company processes through standardization and access to information -and data. A special focus is also on SMEs, whose active participation is of -central importance for the network's success. That is why Catena-X has been -conceived from the outset as an open network with solutions ready for SMEs, -where these companies will be able to participate quickly and with little IT -infrastructure investment. Tractus-X is meant to be the PoC project of the -Catena-X alliance focusing on parts traceability. - -* +Here you can find the latest project description: ## Project licenses -The Tractus-X project uses the following licenses: +The Eclipse Tractus-X project uses the following licenses: * Apache-2.0 for code * CC-BY-4.0 for non-code From 90a851c41a38828cbc246cb733c19153e16a8217 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:34:52 +0200 Subject: [PATCH 232/259] chore(deps): bump the github-actions-all group across 3 directories with 6 updates (#2999) Bumps the github-actions-all group with 4 updates in the / directory: [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action), [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) and [actions/stale](https://github.com/actions/stale). Bumps the github-actions-all group with 1 update in the /.github/actions/publish-docker-image directory: [docker/login-action](https://github.com/docker/login-action). Bumps the github-actions-all group with 1 update in the /.github/actions/setup-java directory: [actions/setup-java](https://github.com/actions/setup-java). Updates `github/codeql-action/init` from 4.37.3 to 4.37.4 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...f205ea1c3313d32999d8d6a48b4f6530d4437b38) Updates `github/codeql-action/analyze` from 4.37.3 to 4.37.4 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...f205ea1c3313d32999d8d6a48b4f6530d4437b38) Updates `github/codeql-action/upload-sarif` from 4.37.3 to 4.37.4 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81...f205ea1c3313d32999d8d6a48b4f6530d4437b38) Updates `actions/stale` from 10.4.0 to 11.0.0 - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/1e223db275d687790206a7acac4d1a11bd6fe629...4391f3da665fdf50b6810c1a66712fb9ba21aa93) Updates `docker/login-action` from 4.5.1 to 4.6.0 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/abd2ef45e78c5afb21d64d4ca52ee8550d9572c7...dbcb813823bdd20940b903addbd779551569679f) Updates `actions/setup-java` from 5.6.0 to 5.7.0 - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/03ad4de0992f5dab5e18fcb136590ce7c4a0ac95...b6effb05e454b25005698d916606bdc6ffcbf961) --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.37.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/analyze dependency-version: 4.37.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: actions/stale dependency-version: 11.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions-all - dependency-name: docker/login-action dependency-version: 4.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: actions/setup-java dependency-version: 5.7.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/publish-docker-image/action.yml | 2 +- .github/actions/setup-java/action.yml | 2 +- .github/workflows/codeql.yaml | 4 ++-- .github/workflows/kics.yml | 2 +- .github/workflows/stale-bot.yml | 2 +- .github/workflows/workflow-security-lint.yaml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index b7e81dbba7..0ea86c26a1 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -66,7 +66,7 @@ runs: # Login to DockerHub ##################### - name: DockerHub login - uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: username: ${{ inputs.docker_user }} password: ${{ inputs.docker_token }} diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index c6afdb417d..e794cb5d5d 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -26,7 +26,7 @@ runs: using: "composite" steps: - name: Setup JDK 21 - uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0 + uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 with: java-version: '21' distribution: 'temurin' diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 4e13a338f7..0bac264e43 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 + uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 + uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 3e3bb2c855..74a0bdc764 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 + uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index aa563a3d77..7d372b9ffa 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -42,7 +42,7 @@ jobs: uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10.4.0 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 with: operations-per-run: 1000 days-before-issue-stale: 32 diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index b7a367bf10..13d861dbe9 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4.37.3 + uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 if: always() with: sarif_file: results-fixed.sarif From 16df0b879afbe410a96e869202cbdcd69d87e81a Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Thu, 13 Aug 2026 12:42:47 +0200 Subject: [PATCH 233/259] fix: Add the contractNegotiationId conditionally (#3003) * feat: Add the contractNegotiationId conditionally * fix: Add the contractNegotiationId conditionally --- ...EndpointDataReferenceEntryTransformer.java | 12 +++++++---- ...ointDataReferenceEntryTransformerTest.java | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformer.java b/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformer.java index e3bd4ecb45..e9efb2e470 100644 --- a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformer.java +++ b/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformer.java @@ -48,15 +48,19 @@ public JsonObjectFromEndpointDataReferenceEntryTransformer(JsonBuilderFactory js @Override public @Nullable JsonObject transform(@NotNull EndpointDataReferenceEntry entry, @NotNull TransformerContext context) { - return jsonFactory.createObjectBuilder() + var builder = jsonFactory.createObjectBuilder() .add(ID, entry.getId()) .add(TYPE, EDR_ENTRY_TYPE) .add(EDR_ENTRY_PROVIDER_ID, entry.getProviderId()) .add(EDR_ENTRY_ASSET_ID, entry.getAssetId()) .add(EDR_ENTRY_AGREEMENT_ID, entry.getAgreementId()) .add(EDR_ENTRY_TRANSFER_PROCESS_ID, entry.getTransferProcessId()) - .add(EDR_ENTRY_CREATED_AT, entry.getCreatedAt()) - .add(EDR_ENTRY_CONTRACT_NEGOTIATION_ID, entry.getContractNegotiationId()) - .build(); + .add(EDR_ENTRY_CREATED_AT, entry.getCreatedAt()); + + if (entry.getContractNegotiationId() != null) { + builder.add(EDR_ENTRY_CONTRACT_NEGOTIATION_ID, entry.getContractNegotiationId()); + } + + return builder.build(); } } diff --git a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformerTest.java b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformerTest.java index 56ab8170d8..403467b270 100644 --- a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformerTest.java +++ b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/transform/JsonObjectFromEndpointDataReferenceEntryTransformerTest.java @@ -66,4 +66,24 @@ void transform() { assertThat(jsonObject.getJsonString(EDR_ENTRY_PROVIDER_ID).getString()).isNotNull().isEqualTo(dto.getProviderId()); } + + @Test + void transform_withoutContractNegotiationId() { + + var dto = EndpointDataReferenceEntry.Builder.newInstance() + .assetId("id") + .transferProcessId("tpId") + .agreementId("aId") + .providerId("providerId") + .build(); + + var jsonObject = transformer.transform(dto, context); + + assertThat(jsonObject).isNotNull(); + assertThat(jsonObject.containsKey(EDR_ENTRY_CONTRACT_NEGOTIATION_ID)).isFalse(); + assertThat(jsonObject.getJsonString(EDR_ENTRY_AGREEMENT_ID).getString()).isEqualTo(dto.getAgreementId()); + assertThat(jsonObject.getJsonString(EDR_ENTRY_ASSET_ID).getString()).isEqualTo(dto.getAssetId()); + assertThat(jsonObject.getJsonString(EDR_ENTRY_TRANSFER_PROCESS_ID).getString()).isEqualTo(dto.getTransferProcessId()); + assertThat(jsonObject.getJsonString(EDR_ENTRY_PROVIDER_ID).getString()).isEqualTo(dto.getProviderId()); + } } From 0db882cf97136bacbeefa1ba4c6d08c49deaf791 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 06:31:21 +0200 Subject: [PATCH 234/259] chore(deps): bump the cloud-sdks group with 2 updates (#3007) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.50.0 to 2.51.2 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.50.0 to 2.51.2 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.50.0 to 2.51.2 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.51.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.51.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.51.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 641aa1f765..c362ea9b34 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.4" awaitility = "4.3.0" -aws = "2.50.0" +aws = "2.51.2" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" From 5e4e7e9d6af5fdb7d2fec8dd51c0d53b118d35e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 06:31:43 +0200 Subject: [PATCH 235/259] chore(deps): bump io.swagger.core.v3.swagger-gradle-plugin (#3006) Bumps the build-tooling group with 1 update: io.swagger.core.v3.swagger-gradle-plugin. Updates `io.swagger.core.v3.swagger-gradle-plugin` from 2.2.52 to 2.2.53 --- updated-dependencies: - dependency-name: io.swagger.core.v3.swagger-gradle-plugin dependency-version: 2.2.53 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tooling ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c362ea9b34..8caf784f34 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -262,5 +262,5 @@ edc-sts = [ [plugins] docker = { id = "com.bmuschko.docker-remote-api", version = "10.0.0" } shadow = { id = "com.gradleup.shadow", version = "9.6.1" } -swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.52" } +swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.53" } edc-build = { id = "org.eclipse.edc.edc-build", version.ref = "edc-build" } From 3933373482e9607de6d47f5b12d26afaafaee3e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 06:32:04 +0200 Subject: [PATCH 236/259] chore(deps): bump gradle-wrapper from 9.6.1 to 9.7.0 (#3009) Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.6.1 to 9.7.0. - [Release notes](https://github.com/gradle/gradle/releases) - [Commits](https://github.com/gradle/gradle/compare/v9.6.1...v9.7.0) --- updated-dependencies: - dependency-name: gradle-wrapper dependency-version: 9.7.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.jar | Bin 48462 -> 47505 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index b1b8ef56b44f16b14dc800fa8103a6d89abb526f..eddabd2eef8d94a5437d6168ff9c87a78ff725b3 100644 GIT binary patch delta 39079 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 F{Rc_uT_ykk delta 40101 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a9db11550c..69dd0d0404 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.0-bin.zip networkTimeout=10000 retries=0 retryBackOffMs=500 From 9904128e08f37dcf87f9621b50a9ac7d79b96193 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 11:49:29 +0200 Subject: [PATCH 237/259] chore(deps): bump the database group with 2 updates (#3008) Bumps the database group with 2 updates: org.flywaydb:flyway-core and org.flywaydb:flyway-database-postgresql. Updates `org.flywaydb:flyway-core` from 13.1.0 to 13.2.0 Updates `org.flywaydb:flyway-database-postgresql` from 13.1.0 to 13.2.0 Updates `org.flywaydb:flyway-database-postgresql` from 13.1.0 to 13.2.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 13.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 13.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 13.2.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8caf784f34..f76994e40d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" -flyway = "13.1.0" +flyway = "13.2.0" jackson = "2.22.1" jakarta-json = "2.1.3" jsonschema = "2.0.0" From cd9fecbf58d116a98b332b01c17be9cde95dd902 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 14 Aug 2026 11:50:30 +0200 Subject: [PATCH 238/259] chore(deps): bump the github-actions-all group across 2 directories with 6 updates (#3010) Bumps the github-actions-all group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.20.0` | `2.20.1` | | [github/codeql-action/init](https://github.com/github/codeql-action) | `4.37.4` | `4.37.6` | | [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.37.4` | `4.37.6` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.4` | `4.37.6` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.6.1` | `0.6.2` | Bumps the github-actions-all group with 1 update in the /.github/actions/setup-java directory: [gradle/actions/setup-gradle](https://github.com/gradle/actions). Updates `step-security/harden-runner` from 2.20.0 to 2.20.1 - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/bf7454d06d71f1098171f2acdf0cd4708d7b5920...b09bb98e06d4d774595224525879c09bc6e98c40) Updates `github/codeql-action/init` from 4.37.4 to 4.37.6 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/f205ea1c3313d32999d8d6a48b4f6530d4437b38...5595ccaf912efad79be6eef63a5619ff05969be3) Updates `github/codeql-action/analyze` from 4.37.4 to 4.37.6 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/f205ea1c3313d32999d8d6a48b4f6530d4437b38...5595ccaf912efad79be6eef63a5619ff05969be3) Updates `github/codeql-action/upload-sarif` from 4.37.4 to 4.37.6 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/f205ea1c3313d32999d8d6a48b4f6530d4437b38...5595ccaf912efad79be6eef63a5619ff05969be3) Updates `zizmorcore/zizmor-action` from 0.6.1 to 0.6.2 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/6fc4b006235f201fdab3722e17240ab420d580e5...3dc1ecc9bcb9e94e9b2c709687979e1298497054) Updates `gradle/actions/setup-gradle` from 6.2.0 to 6.3.0 - [Release notes](https://github.com/gradle/actions/releases) - [Commits](https://github.com/gradle/actions/compare/3f131e8634966bd73d06cc69884922b02e6faf92...9c971963bec38e04b3d30dcc455b5382be2fdbfb) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.20.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/init dependency-version: 4.37.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/analyze dependency-version: 4.37.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: zizmorcore/zizmor-action dependency-version: 0.6.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: gradle/actions/setup-gradle dependency-version: 6.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/actions/setup-java/action.yml | 2 +- .github/workflows/codeql.yaml | 6 ++--- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/deployment-test.yaml | 6 ++--- .github/workflows/draft-release.yaml | 2 +- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 4 ++-- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 6 ++--- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 2 +- .github/workflows/stale-bot.yml | 2 +- .github/workflows/triage-issue.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 4 ++-- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 8 +++---- 19 files changed, 44 insertions(+), 44 deletions(-) diff --git a/.github/actions/setup-java/action.yml b/.github/actions/setup-java/action.yml index e794cb5d5d..8cffbb18b5 100644 --- a/.github/actions/setup-java/action.yml +++ b/.github/actions/setup-java/action.yml @@ -31,4 +31,4 @@ runs: java-version: '21' distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0 + uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 0bac264e43..eade316499 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -55,7 +55,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Checkout repository @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 + uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 + uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index d6340c923e..8aae272109 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Copy labels from linked issue to PR diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index bb3d53fbb0..0b959a04c6 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: test-prepare steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -84,7 +84,7 @@ jobs: "v1.33.7" ] steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 54ea0e85c3..0d5a7e24b7 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -44,7 +44,7 @@ jobs: is_official_release: ${{ steps.validation.outputs.is_official_release }} steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index a9656178b5..dab71a6988 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index bb036a4794..8b3bb4ea67 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit ############## diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 74a0bdc764..07be9ef3d9 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 + uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index aa7b0abfe4..d730e44397 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -38,7 +38,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index 838ff11c73..bdba15f628 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -72,7 +72,7 @@ jobs: HAS_SWAGGER: ${{ steps.secret-presence.outputs.HAS_SWAGGER }} steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Check whether secrets exist @@ -95,7 +95,7 @@ jobs: DATED: ${{ steps.get-version.outputs.DATED }} steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -165,7 +165,7 @@ jobs: if: ${{ needs.determine-version.outputs.DATED == 'true' }} steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c692efd2b5..1243ad68aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,7 +60,7 @@ jobs: update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -152,7 +152,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -192,7 +192,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -255,7 +255,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit @@ -298,7 +298,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Checkout main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index f6474af527..3c76d985e0 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -42,7 +42,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Checkout Repository diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index 7d372b9ffa..fbf089c50c 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -39,7 +39,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 diff --git a/.github/workflows/triage-issue.yml b/.github/workflows/triage-issue.yml index 9117a40692..1d9c58cab7 100644 --- a/.github/workflows/triage-issue.yml +++ b/.github/workflows/triage-issue.yml @@ -36,7 +36,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - run: gh issue edit "$NUMBER" --add-label "$LABELS" diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index 1edc83e02b..4f5788d64b 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -70,7 +70,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 0d76003c1c..2fa6692548 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 6907ee9db0..8e80a0bb88 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: [ test-prepare ] steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 5ea32b3d26..1b267306d7 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -36,7 +36,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -152,7 +152,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -171,7 +171,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -191,7 +191,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -213,7 +213,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -247,7 +247,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -264,7 +264,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -286,7 +286,7 @@ jobs: contents: write steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 13d861dbe9..85bb6272ea 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -46,7 +46,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit @@ -56,7 +56,7 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@6fc4b006235f201fdab3722e17240ab420d580e5 # v0.6.1 + uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2 with: version: "1.23.1" advanced-security: "true" @@ -71,7 +71,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 with: egress-policy: audit @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 + uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 if: always() with: sarif_file: results-fixed.sarif From c97a34bb83e0c99a66ad8ce14cb8ef79d3d37877 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Wed, 19 Aug 2026 08:51:19 +0200 Subject: [PATCH 239/259] feat: DR recoverable refresh token (#3005) * feat: DR recoverable refresh token * feat: DR recoverable refresh token * feat: add no configuration explanation --- .../README.md | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 docs/development/decision-records/2026-08-10-refresh-token-retire-on-acknowledgement/README.md diff --git a/docs/development/decision-records/2026-08-10-refresh-token-retire-on-acknowledgement/README.md b/docs/development/decision-records/2026-08-10-refresh-token-retire-on-acknowledgement/README.md new file mode 100644 index 0000000000..f670362ad9 --- /dev/null +++ b/docs/development/decision-records/2026-08-10-refresh-token-retire-on-acknowledgement/README.md @@ -0,0 +1,106 @@ +# Retire Refresh Tokens on Acknowledgement + +## Decision + +The provider data plane will retire a rotated refresh token only once the consumer has proven that it received the +replacement. The proof of receipt is the consumer presenting the new refresh token. Until that happens, the token it +replaced remains acceptable, and presenting it again returns the current refresh token — the one the consumer failed to +receive — instead of rotating a second time. The access token is issued fresh on both paths. + +This is a behavioural change with no configuration surface and no way to opt out. There is nothing worth switching off: +the old behaviour is the one that breaks transfers on a network timeout, and the new one costs one extra string in the +vault record. The request and response formats are unchanged, so conforming consumers see no difference either way. + +## Rationale + +Token refresh as specified in the +[Tractus-X Refresh Token Grant Profile](https://github.com/eclipse-tractusx/tractusx-profiles/blob/main/tx/refresh/refresh.token.grant.profile.md) +and implemented per [2024-03-05_token_refresh](../2024-03-05_token_refresh/README.md) rotates the refresh token on every +successful call. The implementation treated the moment of *issuing* a new token as the moment the old one dies: the +vault entry was overwritten and the previous token was rejected from then on. + +That is only correct if the response always reaches the consumer, which is not a property an HTTP call has. Observed in +production: a refresh takes longer than a proxy or ingress in front of the public API tolerates, the request is answered +with HTTP 504, or the consumer cancels and the access log shows 499. The provider has rotated; the consumer still holds +the old refresh token; it never saw the new one. Every subsequent refresh is answered with HTTP 401 because the token +presented no longer matches the stored one. The transfer is permanently broken and can only be recovered by +restarting the transfer process — for a failure mode that is a plain network timeout. + +The observation that resolves this is that **the acknowledgement already exists in the protocol**. A consumer that +presents the new refresh token can only have obtained it from the response it is confirming. No extra message, no +profile change, and no timer is needed — the provider simply defers retirement until it sees that evidence. + +The refresh token is sender-constrained: holding one does not authorise a refresh. Every request must also carry an +authentication token signed with the key behind the consumer's DID and issued by the participant the EDR was issued to +(`AuthTokenAudienceRule`), so an intercepted or leaked refresh token is unusable on its own, however often it is +replayed. Retention changes how long the consumer's own copy stays valid, not who is able to use it. + +## Approach + +### Retained state + +`RefreshToken`, the record persisted in the vault under the access token's ID, gains a single component: + +```java +public record RefreshToken(String refreshToken, Long expiresIn, String refreshEndpoint, + @Nullable String previousRefreshToken) { +} +``` + +`previousRefreshToken` is the token that `refreshToken` replaced. Entries written by earlier versions deserialize to +`null` there and are treated as having no predecessor, so no migration of existing vault entries is required. The record +additionally ignores unknown properties, so a further component could be added without breaking records already stored. + +The record holds refresh tokens only. The access token is never stored — every call mints a new one, whether it rotates +the refresh token or serves a repeat, so a consumer retrying late still gets a usable access token. + +At most two generations of refresh token are live at any time, and the older one is retired by the very request that +proves it is no longer needed. + +### Refresh flow + +`RefreshTokenValidationRule` keeps its place in the access token's validation chain and its single vault read, and is +widened to accept the superseded token in addition to the current one. Deciding between the two outcomes needs to know +*which* token matched, which a `Result` cannot express, so the rule exposes the resolved record through +`replayedToken()` — non-null only in the superseded case. Instances are already created per refresh request, so this +stays confined to one request. + +`DataPlaneTokenRefreshServiceImpl.refreshToken()` then branches on that single value when deciding what to pair the +newly issued access token with: + +- `replayedToken()` is non-null — the consumer never saw the response that rotated its token, so it is given the current + refresh token from the stored record. Nothing is rotated and nothing is written. Rotating here would be worse than + useless: the provider cannot tell which of the two tokens the consumer ended up with, so it would strand the consumer + for good. +- otherwise — the presented token is the current one, which is the acknowledgement. A new refresh token is issued and + stored, with the presented token recorded as the new `previousRefreshToken`. + +A token matching neither is still rejected by the rule, with the message unchanged, so client-visible behaviour and the +existing end-to-end assertions are unaffected. + +## Further considerations + +**Security.** The superseded token stays usable for one extra generation, unbounded in time. That widens an existing +window: a captured *complete* refresh request can be replayed for a generation longer, and without the 401 collision +that makes such an intrusion visible. The authentication token must therefore carry an `exp` claim and is validated +against it. + +**Standards conformance.** The behaviour stays within [RFC 6749](https://www.rfc-editor.org/rfc/rfc6749). Section 6 +makes both halves of rotation optional — "The authorization server MAY issue a new refresh token […] The authorization +server MAY revoke the old refresh token after issuing a new refresh token to the client." A new refresh token is issued +and only the optional revocation is deferred, until the client has demonstrably received it, which is also what that +sentence's "to the client" describes. Its three MUSTs are unaffected: client authentication is required, the refresh +token is checked to have been issued to the authenticated client (`AuthTokenAudienceRule` together with the DID +signature on the authentication token), and the refresh token is validated. Section 10.4 holds as well — both +generations stay confidential in the vault, both are bound to the same client through the shared `AccessTokenData`, and +refresh tokens remain unguessable provider-signed JWTs. What is given up is the detection property of +strict single-use rotation: the first appearance of a superseded token no longer signals a possible compromise, because +it is indistinguishable from the legitimate retry this decision exists to support. + +## NOTICE + +This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). + +- SPDX-License-Identifier: CC-BY-4.0 +- SPDX-FileCopyrightText: 2026 Cofinity-X GmbH +- Source URL: [https://github.com/eclipse-tractusx/tractusx-edc](https://github.com/eclipse-tractusx/tractusx-edc) From 472138a2c792de7cc9c48c9067ecf6fbba7b1db9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Aug 2026 09:24:24 +0200 Subject: [PATCH 240/259] chore(deps): bump the cloud-sdks group with 2 updates (#3016) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.51.2 to 2.52.0 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.51.2 to 2.52.0 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.51.2 to 2.52.0 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.52.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.52.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.52.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f76994e40d..bc5f66d89e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.4" awaitility = "4.3.0" -aws = "2.51.2" +aws = "2.52.0" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" From 4d3bd87008cb2d211da522663a439c75532c79db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Aug 2026 09:24:40 +0200 Subject: [PATCH 241/259] chore(deps): bump org.junit.platform:junit-platform-launcher (#3014) Bumps the test-dependencies group with 1 update: [org.junit.platform:junit-platform-launcher](https://github.com/junit-team/junit-framework). Updates `org.junit.platform:junit-platform-launcher` from 6.1.2 to 6.1.3 - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](https://github.com/junit-team/junit-framework/compare/r6.1.2...r6.1.3) --- updated-dependencies: - dependency-name: org.junit.platform:junit-platform-launcher dependency-version: 6.1.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: test-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bc5f66d89e..0c0114ecf3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ flyway = "13.2.0" jackson = "2.22.1" jakarta-json = "2.1.3" jsonschema = "2.0.0" -junit = "6.1.2" +junit = "6.1.3" kafka = "4.3.1" nimbus = "10.9.1" okhttp = "5.4.0" From 3848f900ed21eece62e35658f3a9ee4dd84824b0 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Thu, 20 Aug 2026 14:15:58 +0200 Subject: [PATCH 242/259] feat: update supported kubernetes versions (#3017) * feat: update supported kubernetes versions * feat: update supported kubernetes versions * feat: update supported kubernetes versions --- .github/actions/run-deployment-test/action.yml | 7 ++++++- .github/workflows/deployment-test.yaml | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/actions/run-deployment-test/action.yml b/.github/actions/run-deployment-test/action.yml index f4f5b3a039..06ffacb820 100644 --- a/.github/actions/run-deployment-test/action.yml +++ b/.github/actions/run-deployment-test/action.yml @@ -44,7 +44,7 @@ inputs: k8sversion: required: false description: "Version of Kubernetes to use" - default: "v1.34.3" + default: "v1.36.1" runs: using: "composite" @@ -60,6 +60,11 @@ runs: - name: Create k8s Kind Cluster uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0 with: + # kind >= v0.32.0 is required for the current node images (containerd config v4); + # the kind-action default (v0.31.0) fails "kind load" with: + # "unknown containerd config version: 4 (supported versions: 2 and 3)". + # Drop this pin once helm/kind-action's default kind version is >= v0.32.0. + version: v0.32.0 node_image: kindest/node:${{ inputs.k8sversion }} - name: Build docker images diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 0b959a04c6..63f797579c 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -79,9 +79,9 @@ jobs: fail-fast: false # this will verify that the official distribution of the Tractus-X EDC Helm chart runs on the last 3 Kubernetes versions matrix: - k8s-version: [ "v1.35.1", - "v1.34.3", - "v1.33.7" ] + k8s-version: [ "v1.36.1", + "v1.35.5", + "v1.34.8" ] steps: - name: Harden Runner uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 From 9e87e2b072b39878ebe392c02cef2dd32ba2e87f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:30:41 +0200 Subject: [PATCH 243/259] chore(deps): bump the github-actions-all group across 1 directory with 5 updates (#3022) Bumps the github-actions-all group with 5 updates in the / directory: | Package | From | To | | --- | --- | --- | | [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.20.1` | `2.21.0` | | [github/codeql-action/init](https://github.com/github/codeql-action) | `4.37.6` | `4.37.7` | | [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.37.6` | `4.37.7` | | [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.37.6` | `4.37.7` | | [trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) | `3.96.0` | `3.97.0` | Updates `step-security/harden-runner` from 2.20.1 to 2.21.0 - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/b09bb98e06d4d774595224525879c09bc6e98c40...05e31511f85b41b11d1cf0ef85d0992719546e2c) Updates `github/codeql-action/init` from 4.37.6 to 4.37.7 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/5595ccaf912efad79be6eef63a5619ff05969be3...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd) Updates `github/codeql-action/analyze` from 4.37.6 to 4.37.7 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/5595ccaf912efad79be6eef63a5619ff05969be3...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd) Updates `github/codeql-action/upload-sarif` from 4.37.6 to 4.37.7 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/5595ccaf912efad79be6eef63a5619ff05969be3...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd) Updates `trufflesecurity/trufflehog` from 3.96.0 to 3.97.0 - [Release notes](https://github.com/trufflesecurity/trufflehog/releases) - [Commits](https://github.com/trufflesecurity/trufflehog/compare/6f3c981e7b77f235fd2702dd74af25fc4b72bf11...bcfcf73aaf4759d4dadc2783177c245a02792318) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.21.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all - dependency-name: github/codeql-action/init dependency-version: 4.37.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/analyze dependency-version: 4.37.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-all - dependency-name: trufflesecurity/trufflehog dependency-version: 3.97.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-all ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yaml | 6 ++--- .github/workflows/copy-labels.yaml | 2 +- .github/workflows/deployment-test.yaml | 6 ++--- .github/workflows/draft-release.yaml | 2 +- .../generate-and-publish-dependencies.yaml | 2 +- .github/workflows/helm-lint.yaml | 2 +- .github/workflows/kics.yml | 4 ++-- .github/workflows/publish-context.yaml | 2 +- .github/workflows/publish-new-snapshot.yaml | 6 ++--- .github/workflows/release.yml | 10 ++++----- .github/workflows/secrets-scan.yml | 4 ++-- .github/workflows/stale-bot.yml | 2 +- .github/workflows/triage-issue.yml | 2 +- .github/workflows/trigger-docker-publish.yaml | 2 +- .github/workflows/trigger-maven-publish.yaml | 2 +- .github/workflows/upgradeability-test.yaml | 4 ++-- .github/workflows/verify.yaml | 22 +++++++++---------- .github/workflows/workflow-security-lint.yaml | 6 ++--- 18 files changed, 43 insertions(+), 43 deletions(-) diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index eade316499..13fbf0e51e 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -55,7 +55,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Checkout repository @@ -65,7 +65,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file @@ -84,6 +84,6 @@ jobs: ./gradlew compileJava --no-daemon --no-build-cache - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/copy-labels.yaml b/.github/workflows/copy-labels.yaml index 8aae272109..129b01d445 100644 --- a/.github/workflows/copy-labels.yaml +++ b/.github/workflows/copy-labels.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Copy labels from linked issue to PR diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 63f797579c..6def412538 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: test-prepare steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -84,7 +84,7 @@ jobs: "v1.34.8" ] steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 0d5a7e24b7..dd33278f89 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -44,7 +44,7 @@ jobs: is_official_release: ${{ steps.validation.outputs.is_official_release }} steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/generate-and-publish-dependencies.yaml b/.github/workflows/generate-and-publish-dependencies.yaml index dab71a6988..b7d16aac5d 100644 --- a/.github/workflows/generate-and-publish-dependencies.yaml +++ b/.github/workflows/generate-and-publish-dependencies.yaml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 8b3bb4ea67..c6f3b45023 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit ############## diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index 07be9ef3d9..c177ef9d85 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -64,6 +64,6 @@ jobs: - name: Upload SARIF file for GitHub Advanced Security Dashboard if: always() - uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: kicsResults/results.sarif diff --git a/.github/workflows/publish-context.yaml b/.github/workflows/publish-context.yaml index d730e44397..220073e07d 100644 --- a/.github/workflows/publish-context.yaml +++ b/.github/workflows/publish-context.yaml @@ -38,7 +38,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/publish-new-snapshot.yaml b/.github/workflows/publish-new-snapshot.yaml index bdba15f628..7a596f192d 100644 --- a/.github/workflows/publish-new-snapshot.yaml +++ b/.github/workflows/publish-new-snapshot.yaml @@ -72,7 +72,7 @@ jobs: HAS_SWAGGER: ${{ steps.secret-presence.outputs.HAS_SWAGGER }} steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Check whether secrets exist @@ -95,7 +95,7 @@ jobs: DATED: ${{ steps.get-version.outputs.DATED }} steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -165,7 +165,7 @@ jobs: if: ${{ needs.determine-version.outputs.DATED == 'true' }} steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1243ad68aa..db9bf83246 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,7 +60,7 @@ jobs: update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -152,7 +152,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -192,7 +192,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -255,7 +255,7 @@ jobs: if: needs.validation.outputs.RELEASE_VERSION steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit @@ -298,7 +298,7 @@ jobs: pages: write steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Checkout main diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 3c76d985e0..a01f926583 100644 --- a/.github/workflows/secrets-scan.yml +++ b/.github/workflows/secrets-scan.yml @@ -42,7 +42,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Checkout Repository @@ -53,7 +53,7 @@ jobs: - name: TruffleHog OSS id: trufflehog - uses: trufflesecurity/trufflehog@6f3c981e7b77f235fd2702dd74af25fc4b72bf11 + uses: trufflesecurity/trufflehog@bcfcf73aaf4759d4dadc2783177c245a02792318 continue-on-error: true with: path: ./ # Scan the entire repository diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index fbf089c50c..43b58ff5f1 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -39,7 +39,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0 diff --git a/.github/workflows/triage-issue.yml b/.github/workflows/triage-issue.yml index 1d9c58cab7..fcc056b2a1 100644 --- a/.github/workflows/triage-issue.yml +++ b/.github/workflows/triage-issue.yml @@ -36,7 +36,7 @@ jobs: issues: write steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - run: gh issue edit "$NUMBER" --add-label "$LABELS" diff --git a/.github/workflows/trigger-docker-publish.yaml b/.github/workflows/trigger-docker-publish.yaml index 4f5788d64b..51020d629e 100644 --- a/.github/workflows/trigger-docker-publish.yaml +++ b/.github/workflows/trigger-docker-publish.yaml @@ -70,7 +70,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/trigger-maven-publish.yaml b/.github/workflows/trigger-maven-publish.yaml index 2fa6692548..52c40c0db8 100644 --- a/.github/workflows/trigger-maven-publish.yaml +++ b/.github/workflows/trigger-maven-publish.yaml @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index 8e80a0bb88..945877898c 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Cache ContainerD Image Layers @@ -50,7 +50,7 @@ jobs: needs: [ test-prepare ] steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Checkout diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 1b267306d7..79d3b36d45 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -36,7 +36,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -59,7 +59,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -77,7 +77,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -94,7 +94,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -152,7 +152,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -171,7 +171,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -191,7 +191,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -213,7 +213,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -247,7 +247,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -264,7 +264,7 @@ jobs: contents: read steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -286,7 +286,7 @@ jobs: contents: write steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit - name: Checkout repository diff --git a/.github/workflows/workflow-security-lint.yaml b/.github/workflows/workflow-security-lint.yaml index 85bb6272ea..b820274d22 100644 --- a/.github/workflows/workflow-security-lint.yaml +++ b/.github/workflows/workflow-security-lint.yaml @@ -46,7 +46,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit @@ -71,7 +71,7 @@ jobs: security-events: write # required to upload SARIF to GitHub Advanced Security steps: - name: Harden Runner - uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1 + uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0 with: egress-policy: audit @@ -90,7 +90,7 @@ jobs: run: python3 .github/scripts/fix-poutine-sarif.py - name: Upload poutine SARIF to GitHub Advanced Security - uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 if: always() with: sarif_file: results-fixed.sarif From f36ed669fb16ba6f9fb2cb04be67d8a1b87c5205 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:30:57 +0200 Subject: [PATCH 244/259] chore(deps): bump postgres (#3020) Bumps the docker-base-images group with 1 update in the /edc-tests/e2e-fixtures/src/testFixtures/resources directory: postgres. Updates `postgres` from 18.4 to 18.6 --- updated-dependencies: - dependency-name: postgres dependency-version: '18.6' dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docker-base-images ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile b/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile index ed298d0373..c194458f3e 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile +++ b/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile @@ -1,2 +1,2 @@ -FROM postgres:18.4 +FROM postgres:18.6 USER "Dummy" From 61bdc764b2da4ca7b3ffe5c389dec16846cae95a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:31:14 +0200 Subject: [PATCH 245/259] chore(deps): bump the cloud-sdks group with 2 updates (#3019) Bumps the cloud-sdks group with 2 updates: software.amazon.awssdk:s3 and software.amazon.awssdk:s3-transfer-manager. Updates `software.amazon.awssdk:s3` from 2.52.0 to 2.53.0 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.52.0 to 2.53.0 Updates `software.amazon.awssdk:s3-transfer-manager` from 2.52.0 to 2.53.0 --- updated-dependencies: - dependency-name: software.amazon.awssdk:s3 dependency-version: 2.53.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.53.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks - dependency-name: software.amazon.awssdk:s3-transfer-manager dependency-version: 2.53.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cloud-sdks ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0c0114ecf3..2fa52928f5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ edc = "0.17.0" edc-build = "1.5.2" allure = "2.35.4" awaitility = "4.3.0" -aws = "2.52.0" +aws = "2.53.0" azure-storage-blob = "12.35.0" bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" From d61fb723fd620b057d50ab41f115ddc8e30a7de7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:40:59 +0200 Subject: [PATCH 246/259] chore(deps): bump the database group with 2 updates (#3021) Bumps the database group with 2 updates: org.flywaydb:flyway-core and org.flywaydb:flyway-database-postgresql. Updates `org.flywaydb:flyway-core` from 13.2.0 to 13.3.0 Updates `org.flywaydb:flyway-database-postgresql` from 13.2.0 to 13.3.0 Updates `org.flywaydb:flyway-database-postgresql` from 13.2.0 to 13.3.0 --- updated-dependencies: - dependency-name: org.flywaydb:flyway-core dependency-version: 13.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 13.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database - dependency-name: org.flywaydb:flyway-database-postgresql dependency-version: 13.3.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: database ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2fa52928f5..4781b74fdb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ bouncyCastle-jdk18on = "1.85" dcp-tck = "1.0.1" dsp-tck = "1.0.0" common-tck = "1.0.0" -flyway = "13.2.0" +flyway = "13.3.0" jackson = "2.22.1" jakarta-json = "2.1.3" jsonschema = "2.0.0" From c8998e53ae371dc9e0f32ae6c5ca5efc532c589f Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Mon, 24 Aug 2026 08:31:05 +0200 Subject: [PATCH 247/259] feat: make refresh token recoverable (#3004) * feat: make refresh token recoverable * feat: add validation of an exp claim * feat: fix unit tests * feat: fix unit tests * feat: fix unit tests * feat: add unit test * feat: documentation improvement --- .../DataPlaneTokenRefreshServiceImpl.java | 51 ++++- .../tokenrefresh/core/RefreshToken.java | 10 +- .../rules/RefreshTokenValidationRule.java | 23 ++- ...eTokenRefreshServiceImplComponentTest.java | 183 +++++++++++++++++- .../rules/RefreshTokenValidationRuleTest.java | 39 +++- .../runtimes/ParticipantRuntimeExtension.java | 8 +- .../DataPlaneTokenRefreshEndToEndTest.java | 10 + 7 files changed, 302 insertions(+), 22 deletions(-) diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java index 87ab771466..0bf8485767 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImpl.java @@ -82,6 +82,7 @@ public class DataPlaneTokenRefreshServiceImpl implements DataPlaneTokenRefreshService, DataPlaneAccessTokenService { public static final String ACCESS_TOKEN_CLAIM = "token"; public static final String TOKEN_ID_CLAIM = "jti"; + private static final long SLOW_PHASE_THRESHOLD_MS = 5000; private final long tokenExpirySeconds; private final List authenticationTokenValidationRules; private final ParticipantContextSupplier participantContextSupplier; @@ -132,6 +133,7 @@ public DataPlaneTokenRefreshServiceImpl(Clock clock, new ClaimIsPresentRule(AUDIENCE), // we don't check the contents, only it is present new ClaimIsPresentRule(ACCESS_TOKEN_CLAIM), new ClaimIsPresentRule(TOKEN_ID_CLAIM), + new ExpirationIssuedAtValidationRule(clock, tokenExpiryToleranceSeconds, false), new AuthTokenAudienceRule(accessTokenDataStore)); this.participantContextSupplier = participantContextSupplier; accessTokenAuthorizationRules = List.of(new IssuerEqualsSubjectRule(), @@ -150,7 +152,8 @@ public DataPlaneTokenRefreshServiceImpl(Clock clock, *

  • verify the token's signature
  • *
  • assert {@code iss} and {@code sub} claims are identical
  • *
  • assert the the token contains an {@code token} claim, and that the value is identical to the access token we have on record
  • - *
  • assert that the {@code refreshToken} parameter is identical to the refresh token we have on record
  • + *
  • assert that the {@code refreshToken} parameter is identical to the refresh token we have on record, or to + * the one that record superseded
  • * * * @param refreshToken The refresh token that was issued in the original/previous token request. @@ -159,9 +162,11 @@ public DataPlaneTokenRefreshServiceImpl(Clock clock, @Override public Result refreshToken(String refreshToken, String authenticationToken) { - authenticationToken = authenticationToken.replace("Bearer", "").trim(); + var authToken = authenticationToken.replace("Bearer", "").trim(); - var authTokenRes = tokenValidationService.validate(authenticationToken, publicKeyResolver, authenticationTokenValidationRules); + var authTokenRes = timed("validate-authentication-token [DID resolution]", + () -> tokenValidationService.validate(authToken, + publicKeyResolver, authenticationTokenValidationRules)); if (authTokenRes.failed()) { var msg = "Authentication token validation failed: %s".formatted(authTokenRes.getFailureDetail()); monitor.debug(msg); @@ -179,8 +184,10 @@ public Result refreshToken(String refreshToken, String authentica // 2. extract access token and validate it var accessToken = authTokenRes.getContent().getStringClaim("token"); var refreshTokenValidationRule = new RefreshTokenValidationRule(vault, refreshToken, objectMapper, participantContext); - var accessTokenDataResult = tokenValidationService.validate(accessToken, localPublicKeyService, refreshTokenValidationRule) - .map(accessTokenClaims -> accessTokenDataStore.getById(accessTokenClaims.getStringClaim(JwtRegisteredClaimNames.JWT_ID))); + + Result accessTokenDataResult = timed("validate-access-token [Vault resolveSecret + store getById]", + () -> tokenValidationService.validate(accessToken, localPublicKeyService, refreshTokenValidationRule) + .map(accessTokenClaims -> accessTokenDataStore.getById(accessTokenClaims.getStringClaim(JwtRegisteredClaimNames.JWT_ID)))); if (accessTokenDataResult.failed()) { var msg = "Access token validation failed: %s".formatted(accessTokenDataResult.getFailureDetail()); @@ -195,7 +202,11 @@ public Result refreshToken(String refreshToken, String authentica .build(); var newAccessToken = createToken(newTokenParams).map(tr -> tr.tokenRepresentation().getToken()); - var newRefreshToken = createToken(TokenParameters.Builder.newInstance().build()).map(tr -> tr.tokenRepresentation().getToken()); + + var replayed = refreshTokenValidationRule.replayedToken(); + var newRefreshToken = replayed != null + ? ServiceResult.success(replayed.refreshToken()) + : createToken(TokenParameters.Builder.newInstance().build()).map(tr -> tr.tokenRepresentation().getToken()); if (newAccessToken.failed() || newRefreshToken.failed()) { var errors = new ArrayList<>(newAccessToken.getFailureMessages()); errors.addAll(newRefreshToken.getFailureMessages()); @@ -204,13 +215,19 @@ public Result refreshToken(String refreshToken, String authentica return Result.failure(msg); } - storeRefreshToken(existingAccessTokenData.id(), new RefreshToken(newRefreshToken.getContent(), tokenExpirySeconds, refreshEndpoint), participantContext); + if (replayed != null) { + monitor.info("Refresh token for '%s' was already rotated, handing out the current one again.".formatted(existingAccessTokenData.id())); + return Result.success(new TokenResponse(newAccessToken.getContent(), newRefreshToken.getContent(), tokenExpirySeconds, tokenExpirySeconds, "bearer")); + } + + timed("store-refresh-token [Vault storeSecret]", + () -> storeRefreshToken(existingAccessTokenData.id(), new RefreshToken(newRefreshToken.getContent(), tokenExpirySeconds, refreshEndpoint, refreshToken), participantContext)); // the ClaimToken is created based solely on the TokenParameters. The additional information (refresh token...) is persisted separately var claimToken = ClaimToken.Builder.newInstance().claims(newTokenParams.getClaims()).build(); var accessTokenData = new AccessTokenData(existingAccessTokenData.id(), claimToken, existingAccessTokenData.dataAddress(), existingAccessTokenData.additionalProperties()); - var storeResult = accessTokenDataStore.update(accessTokenData); + var storeResult = timed("update-access-token [store update]", () -> accessTokenDataStore.update(accessTokenData)); if (storeResult.failed()) { monitor.severe("Failed to store refreshed access token data: %s".formatted(storeResult.getFailureDetail())); @@ -395,6 +412,24 @@ private Result toJson(Object object) { } } + /** + * Executes the given action and records how long it took. Phases exceeding {@link #SLOW_PHASE_THRESHOLD_MS} are + * logged at DEBUG so that a slow/stalled external dependency (DID resolution, Vault, database) can be identified + * from the logs even when the overall request eventually completes. + */ + private T timed(String phase, Supplier action) { + var start = System.nanoTime(); + try { + return action.get(); + } finally { + var elapsedMs = (System.nanoTime() - start) / 1_000_000; + var msg = "refreshToken phase '%s' took %d ms".formatted(phase, elapsedMs); + if (elapsedMs >= SLOW_PHASE_THRESHOLD_MS) { + monitor.debug(msg); + } + } + } + /** * container object for a TokenRepresentation and an ID */ diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/RefreshToken.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/RefreshToken.java index 57873e5bbf..653e84e2e8 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/RefreshToken.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/RefreshToken.java @@ -19,6 +19,14 @@ package org.eclipse.tractusx.edc.dataplane.tokenrefresh.core; -public record RefreshToken(String refreshToken, Long expiresIn, String refreshEndpoint) { +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.jetbrains.annotations.Nullable; +@JsonIgnoreProperties(ignoreUnknown = true) +public record RefreshToken(String refreshToken, Long expiresIn, String refreshEndpoint, + @Nullable String previousRefreshToken) { + + public RefreshToken(String refreshToken, Long expiresIn, String refreshEndpoint) { + this(refreshToken, expiresIn, refreshEndpoint, null); + } } diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/rules/RefreshTokenValidationRule.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/rules/RefreshTokenValidationRule.java index 63b7c53bac..3ce6022a43 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/rules/RefreshTokenValidationRule.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/rules/RefreshTokenValidationRule.java @@ -39,12 +39,18 @@ /** * Validates that the refresh token information associated with a token's ID ({@code jti}), that is stored in the {@link Vault} * matches a refresh token string. The refresh token in question is passed into the CTor. + *

    + * The token that the last refresh replaced is accepted as well: a client presenting it never received the response of + * that refresh, and retiring it before the client has proven receipt would strand the transfer for good. In that case + * {@link #replayedToken()} carries the stored record, so that the current refresh token can be handed out again + * instead of rotating a second time. Instances are therefore single-use, one per refresh request. */ public class RefreshTokenValidationRule implements TokenValidationRule { private final Vault vault; private final String incomingRefreshToken; private final ObjectMapper objectMapper; private final ParticipantContext participantContext; + private RefreshToken replayedToken; public RefreshTokenValidationRule(Vault vault, String incomingRefreshToken, ObjectMapper objectMapper, ParticipantContext participantContext) { this.vault = vault; @@ -62,9 +68,20 @@ public Result checkRule(@NotNull ClaimToken accessToken, @Nullable Map incomingRefreshToken.equals(rt.refreshToken()) ? - success() : - failure("Provided refresh token does not match the stored refresh token.")); + .compose(rt -> { + if (incomingRefreshToken.equals(rt.refreshToken())) { + return success(); + } + if (incomingRefreshToken.equals(rt.previousRefreshToken())) { + replayedToken = rt; + return success(); + } + return failure("Provided refresh token does not match the stored refresh token."); + }); + } + + public @Nullable RefreshToken replayedToken() { + return replayedToken; } private Result parse(String storedRefreshTokenJson) { diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplComponentTest.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplComponentTest.java index 692f011c67..c6ff02156f 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplComponentTest.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceImplComponentTest.java @@ -57,7 +57,11 @@ import java.text.ParseException; import java.time.Clock; +import java.time.Duration; import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.util.Date; import java.util.List; import java.util.Map; @@ -86,11 +90,13 @@ class DataPlaneTokenRefreshServiceImplComponentTest { private final ParticipantContextSupplier participantContextSupplier = () -> ServiceResult.success( ParticipantContext.Builder.newInstance().participantContextId("participantContextId").identity("identity").build() ); + private static final long TOKEN_EXPIRY_SECONDS = 300L; private DataPlaneTokenRefreshServiceImpl tokenRefreshService; private final InMemoryAccessTokenDataStore tokenDataStore = new InMemoryAccessTokenDataStore(CriterionOperatorRegistryImpl.ofDefaults()); private final Monitor monitor = mock(); private final InMemoryVault vault = new InMemoryVault(mock(), null); private final ObjectMapper objectMapper = new ObjectMapper(); + private final MutableClock clock = new MutableClock(Instant.now()); private ECKey consumerKey; private ECKey providerKey; @@ -101,7 +107,7 @@ void setup() throws JOSEException { consumerKey = new ECKeyGenerator(Curve.P_384).keyID(CONSUMER_DID + "#consumer-key").keyUse(KeyUse.SIGNATURE).generate(); when(monitor.withPrefix(anyString())).thenReturn(monitor); - tokenRefreshService = new DataPlaneTokenRefreshServiceImpl(Clock.systemUTC(), + tokenRefreshService = new DataPlaneTokenRefreshServiceImpl(clock, new TokenValidationServiceImpl(), didPkResolverMock, localPublicKeyService, @@ -111,7 +117,7 @@ void setup() throws JOSEException { monitor, TEST_REFRESH_ENDPOINT, 1, - 300L, + TOKEN_EXPIRY_SECONDS, () -> providerKey.getKeyID(), vault, objectMapper, participantContextSupplier); @@ -177,6 +183,93 @@ void refresh_success() throws JOSEException { .doesNotContainKey("refreshToken"); } + @DisplayName("Verify that a refresh whose response got lost can be repeated with the same refresh token") + @Test + void refresh_whenResponseWasLost_returnsCurrentRefreshTokenAndFreshAccessToken() throws JOSEException { + var tokenId = "test-token-id"; + var edr = tokenRefreshService.obtainToken(tokenParams(tokenId), DataAddress.Builder.newInstance().type("test-type").build(), Map.of(AUDIENCE_PROPERTY, CONSUMER_DID)) + .orElseThrow(f -> new RuntimeException(f.getFailureDetail())); + + var refreshToken = edr.getAdditional().get(EDR_PROPERTY_REFRESH_TOKEN).toString(); + + // the client never sees this response, e.g. because a proxy in between timed out + var lostResponse = tokenRefreshService.refreshToken(refreshToken, createAuthToken(tokenId, edr.getToken())) + .orElseThrow(f -> new AssertionError(f.getFailureDetail())); + + clock.advanceBy(Duration.ofSeconds(10)); + + // ...so it retries with the only refresh token it has, and gets the very same pair back + var retriedResponse = tokenRefreshService.refreshToken(refreshToken, createAuthToken(tokenId, edr.getToken())); + + assertThat(retriedResponse).withFailMessage(retriedResponse::getFailureDetail).isSucceeded() + // the refresh token is the one the client failed to receive, not a rotated one + .satisfies(tr -> assertThat(tr.refreshToken()).isEqualTo(lostResponse.refreshToken())) + // the access token is minted fresh, so the client gets a usable one however late it retries + .satisfies(tr -> assertThat(tokenRefreshService.resolve(tr.accessToken())).isSucceeded()); + } + + @DisplayName("Verify that the token pair handed out on a repeat can be refreshed again") + @Test + void refresh_afterRepeat_newTokenIsUsable() throws JOSEException { + var tokenId = "test-token-id"; + var edr = tokenRefreshService.obtainToken(tokenParams(tokenId), DataAddress.Builder.newInstance().type("test-type").build(), Map.of(AUDIENCE_PROPERTY, CONSUMER_DID)) + .orElseThrow(f -> new RuntimeException(f.getFailureDetail())); + + var refreshToken = edr.getAdditional().get(EDR_PROPERTY_REFRESH_TOKEN).toString(); + + tokenRefreshService.refreshToken(refreshToken, createAuthToken(tokenId, edr.getToken())) + .orElseThrow(f -> new AssertionError(f.getFailureDetail())); + var repeated = tokenRefreshService.refreshToken(refreshToken, createAuthToken(tokenId, edr.getToken())) + .orElseThrow(f -> new AssertionError(f.getFailureDetail())); + + var nextResponse = tokenRefreshService.refreshToken(repeated.refreshToken(), createAuthToken(tokenId, repeated.accessToken())); + + assertThat(nextResponse).withFailMessage(nextResponse::getFailureDetail).isSucceeded() + .satisfies(tr -> assertThat(tr.refreshToken()).isNotEqualTo(repeated.refreshToken())); + } + + @DisplayName("Verify that a rotated refresh token is rejected once the client proved it received the new one") + @Test + void refresh_whenSupersededTokenWasAcknowledged_shouldFail() throws JOSEException { + var tokenId = "test-token-id"; + var edr = tokenRefreshService.obtainToken(tokenParams(tokenId), DataAddress.Builder.newInstance().type("test-type").build(), Map.of(AUDIENCE_PROPERTY, CONSUMER_DID)) + .orElseThrow(f -> new RuntimeException(f.getFailureDetail())); + + var firstRefreshToken = edr.getAdditional().get(EDR_PROPERTY_REFRESH_TOKEN).toString(); + var second = tokenRefreshService.refreshToken(firstRefreshToken, createAuthToken(tokenId, edr.getToken())) + .orElseThrow(f -> new AssertionError(f.getFailureDetail())); + + // using the second token proves that the client received it, which retires the first one + tokenRefreshService.refreshToken(second.refreshToken(), createAuthToken(tokenId, second.accessToken())) + .orElseThrow(f -> new AssertionError(f.getFailureDetail())); + + assertThat(tokenRefreshService.refreshToken(firstRefreshToken, createAuthToken(tokenId, edr.getToken()))) + .isFailed() + .detail() + .isEqualTo("Access token validation failed: Provided refresh token does not match the stored refresh token."); + } + + @DisplayName("Verify that a rotated refresh token stays acceptable no matter how long the client takes to retry") + @Test + void refresh_whenResponseWasLostLongAgo_stillSucceeds() throws JOSEException { + var tokenId = "test-token-id"; + var edr = tokenRefreshService.obtainToken(tokenParams(tokenId), DataAddress.Builder.newInstance().type("test-type").build(), Map.of(AUDIENCE_PROPERTY, CONSUMER_DID)) + .orElseThrow(f -> new RuntimeException(f.getFailureDetail())); + + var refreshToken = edr.getAdditional().get(EDR_PROPERTY_REFRESH_TOKEN).toString(); + var lostResponse = tokenRefreshService.refreshToken(refreshToken, createAuthToken(tokenId, edr.getToken())) + .orElseThrow(f -> new AssertionError(f.getFailureDetail())); + + // the client still has not proven receipt, so its only refresh token must remain usable - there is no window + // after which it is retired + clock.advanceBy(Duration.ofDays(1)); + + var retriedResponse = tokenRefreshService.refreshToken(refreshToken, createAuthToken(tokenId, edr.getToken())); + + assertThat(retriedResponse).withFailMessage(retriedResponse::getFailureDetail).isSucceeded() + .satisfies(tr -> assertThat(tr.refreshToken()).isEqualTo(lostResponse.refreshToken())); + } + @DisplayName("Verify that a stolen refresh token cannot be used to refresh an access token") @Test void refresh_originalTokenWasIssuedToDifferentPrincipal() throws JOSEException { @@ -197,8 +290,7 @@ void refresh_originalTokenWasIssuedToDifferentPrincipal() throws JOSEException { signedAuthToken.sign(CryptoConverter.createSigner(consumerKey)); var tokenResponse = tokenRefreshService.refreshToken(edr.getAdditional().get(EDR_PROPERTY_REFRESH_TOKEN).toString(), signedAuthToken.serialize()); - // todo: once the AuthTokenAudienceRule is re-enabled in the DataPlaneTokenRefreshServiceImpl the following assertion needs to be uncommented - // assertThat(tokenResponse).isFailed().detail().isEqualTo("Authentication token validation failed: Principal 'did:web:bob' is not authorized to refresh this token."); + assertThat(tokenResponse).isFailed().detail().isEqualTo("Authentication token validation failed: Principal 'did:web:bob' is not authorized to refresh this token."); } @DisplayName("Verify that a spoofed refresh attempt is rejected ") @@ -223,6 +315,50 @@ void refresh_issuerNotVerifiable() throws JOSEException { assertThat(tokenResponse).isFailed().detail().isEqualTo("Authentication token validation failed: JWT signature not valid"); } + @DisplayName("Verify that an authentication token without an expiry is rejected") + @Test + void refresh_whenAuthTokenHasNoExpiry_shouldFail() throws JOSEException { + var tokenId = "test-token-id"; + var edr = tokenRefreshService.obtainToken(tokenParams(tokenId), DataAddress.Builder.newInstance().type("test-type").build(), Map.of(AUDIENCE_PROPERTY, CONSUMER_DID)) + .orElseThrow(f -> new RuntimeException(f.getFailureDetail())); + + // without an expiry an intercepted refresh request could be replayed indefinitely + var claimsSet = new JWTClaimsSet.Builder() + .jwtID(tokenId) + .issuer(CONSUMER_DID) + .subject(CONSUMER_DID) + .audience(PROVIDER_DID) + .claim("token", edr.getToken()) + .build(); + + var jwsHeader = new JWSHeader.Builder(JWSAlgorithm.ES384).keyID(consumerKey.getKeyID()).build(); + var signedAuthToken = new SignedJWT(jwsHeader, claimsSet); + signedAuthToken.sign(CryptoConverter.createSigner(consumerKey)); + + assertThat(tokenRefreshService.refreshToken(edr.getAdditional().get(EDR_PROPERTY_REFRESH_TOKEN).toString(), signedAuthToken.serialize())) + .isFailed() + .detail() + .contains("Required expiration time (exp) claim is missing in token"); + } + + @DisplayName("Verify that an expired authentication token is rejected") + @Test + void refresh_whenAuthTokenExpired_shouldFail() throws JOSEException { + var tokenId = "test-token-id"; + var edr = tokenRefreshService.obtainToken(tokenParams(tokenId), DataAddress.Builder.newInstance().type("test-type").build(), Map.of(AUDIENCE_PROPERTY, CONSUMER_DID)) + .orElseThrow(f -> new RuntimeException(f.getFailureDetail())); + + var authToken = createAuthToken(tokenId, edr.getToken()); + + // the authentication token outlives its own validity, e.g. because it was captured and replayed later + clock.advanceBy(Duration.ofSeconds(120)); + + assertThat(tokenRefreshService.refreshToken(edr.getAdditional().get(EDR_PROPERTY_REFRESH_TOKEN).toString(), authToken)) + .isFailed() + .detail() + .contains("Token has expired (exp)"); + } + @DisplayName("Verify that a refresh attempt fails if no \"token\" claim is present") @Test void refresh_whenNoAccessTokenClaim() throws JOSEException { @@ -328,12 +464,21 @@ void revoke_successful() throws JsonProcessingException { assertThat(vault.resolveSecret(tokenId)).isNull(); } + private String createAuthToken(String tokenId, String accessToken) throws JOSEException { + var jwsHeader = new JWSHeader.Builder(JWSAlgorithm.ES384).keyID(consumerKey.getKeyID()).build(); + var signedAuthToken = new SignedJWT(jwsHeader, getAuthTokenClaims(tokenId, accessToken).build()); + signedAuthToken.sign(CryptoConverter.createSigner(consumerKey)); + return signedAuthToken.serialize(); + } + private JWTClaimsSet.Builder getAuthTokenClaims(String tokenId, String accessToken) { return new JWTClaimsSet.Builder() .jwtID(tokenId) .issuer(CONSUMER_DID) .subject(CONSUMER_DID) .audience(PROVIDER_DID) + .issueTime(Date.from(clock.instant())) + .expirationTime(Date.from(clock.instant().plusSeconds(60))) .claim("token", accessToken); } @@ -361,4 +506,34 @@ private Map asClaims(String serializedJwt) { throw new RuntimeException(e); } } + + /** + * Clock that only moves when the test tells it to, so that token expiry can be exercised without waiting. + */ + private static class MutableClock extends Clock { + private Instant instant; + + MutableClock(Instant instant) { + this.instant = instant; + } + + void advanceBy(Duration duration) { + instant = instant.plus(duration); + } + + @Override + public ZoneId getZone() { + return ZoneOffset.UTC; + } + + @Override + public Clock withZone(ZoneId zone) { + return this; + } + + @Override + public Instant instant() { + return instant; + } + } } diff --git a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/rules/RefreshTokenValidationRuleTest.java b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/rules/RefreshTokenValidationRuleTest.java index c7ed1a2a1a..2934f6486c 100644 --- a/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/rules/RefreshTokenValidationRuleTest.java +++ b/edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/rules/RefreshTokenValidationRuleTest.java @@ -22,10 +22,12 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.edc.participantcontext.spi.types.ParticipantContext; import org.eclipse.edc.spi.security.Vault; +import org.eclipse.tractusx.edc.dataplane.tokenrefresh.core.RefreshToken; import org.junit.jupiter.api.Test; import java.util.Map; +import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; import static org.eclipse.tractusx.edc.dataplane.tokenrefresh.core.TestFunctions.createAccessToken; import static org.mockito.Mockito.mock; @@ -35,6 +37,7 @@ class RefreshTokenValidationRuleTest { private static final String TEST_TOKEN_ID = "test-jti"; private static final String TEST_REFRESH_TOKEN = "test-refresh-token"; + private static final String TEST_PREVIOUS_REFRESH_TOKEN = "test-previous-refresh-token"; private final Vault vault = mock(); private final String participantContextId = "participantContextId"; private final ParticipantContext participantContext = ParticipantContext.Builder.newInstance() @@ -77,11 +80,12 @@ void checkRule_refreshTokenNotString() { } @Test - void checkRule_refreshTokenDoesNotMatch() { + void checkRule_refreshTokenDoesNotMatch_shouldNotFlagReplay() { when(vault.resolveSecret(participantContextId, TEST_TOKEN_ID)).thenReturn( """ { - "refreshToken": "someRefreshToken" + "refreshToken": "someRefreshToken", + "previousRefreshToken": "someOtherRefreshToken" } """); @@ -89,19 +93,44 @@ void checkRule_refreshTokenDoesNotMatch() { .isFailed() .detail() .isEqualTo("Provided refresh token does not match the stored refresh token."); + assertThat(rule.replayedToken()).isNull(); } @Test - void checkRule_success() { + void checkRule_success_currentTokenMatches_shouldNotFlagReplay() { when(vault.resolveSecret(participantContextId, TEST_TOKEN_ID)).thenReturn( """ { - "refreshToken": "%s" + "refreshToken": "%s", + "expiresIn": 3600, + "refreshEndpoint": "http://foo.bar/refresh", + "previousRefreshToken": "%s" } - """.formatted(TEST_REFRESH_TOKEN)); + """.formatted(TEST_REFRESH_TOKEN, TEST_PREVIOUS_REFRESH_TOKEN)); assertThat(rule.checkRule(createAccessToken(TEST_TOKEN_ID), Map.of())) .isSucceeded(); + assertThat(rule.replayedToken()).isNull(); + } + + @Test + void checkRule_success_previousTokenMatches_shouldFlagReplay() { + when(vault.resolveSecret(participantContextId, TEST_TOKEN_ID)).thenReturn( + """ + { + "refreshToken": "%s", + "expiresIn": 3600, + "refreshEndpoint": "http://foo.bar/refresh", + "previousRefreshToken": "%s" + } + """.formatted(TEST_REFRESH_TOKEN, TEST_PREVIOUS_REFRESH_TOKEN)); + + var replayRule = new RefreshTokenValidationRule(vault, TEST_PREVIOUS_REFRESH_TOKEN, new ObjectMapper(), participantContext); + + assertThat(replayRule.checkRule(createAccessToken(TEST_TOKEN_ID), Map.of())) + .isSucceeded(); + assertThat(replayRule.replayedToken()) + .isEqualTo(new RefreshToken(TEST_REFRESH_TOKEN, 3600L, "http://foo.bar/refresh", TEST_PREVIOUS_REFRESH_TOKEN)); } @Test diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/runtimes/ParticipantRuntimeExtension.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/runtimes/ParticipantRuntimeExtension.java index 3f762fb82f..f794ce93b1 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/runtimes/ParticipantRuntimeExtension.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/runtimes/ParticipantRuntimeExtension.java @@ -26,6 +26,7 @@ import org.eclipse.edc.iam.did.spi.resolution.DidPublicKeyResolver; import org.eclipse.edc.junit.extensions.EmbeddedRuntime; import org.eclipse.edc.junit.extensions.RuntimePerClassExtension; +import org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames; import org.eclipse.edc.keys.spi.PrivateKeyResolver; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Setting; @@ -42,6 +43,8 @@ import org.junit.jupiter.api.extension.ExtensionContext; import java.security.PrivateKey; +import java.time.Instant; +import java.util.Date; import java.util.concurrent.atomic.AtomicReference; /** @@ -93,7 +96,10 @@ public void initialize(ServiceExtensionContext context) { @Override public TokenParameters.Builder decorate(TokenParameters.Builder tokenParameters) { claims.forEach(tokenParameters::claims); - return tokenParameters; + var now = Instant.now(); + return tokenParameters + .claims(JwtRegisteredClaimNames.ISSUED_AT, Date.from(now)) + .claims(JwtRegisteredClaimNames.EXPIRATION_TIME, Date.from(now.plusSeconds(300))); } }; return jwtGenerationService.generate(participantContextId, privateAlias, new KeyIdDecorator(kid), decorator); diff --git a/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java b/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java index e7c9c7dee2..483614ea50 100644 --- a/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java +++ b/edc-tests/e2e/edc-dataplane-tokenrefresh-tests/src/test/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/e2e/DataPlaneTokenRefreshEndToEndTest.java @@ -53,6 +53,8 @@ import java.net.URI; import java.text.ParseException; +import java.time.Instant; +import java.util.Date; import java.util.Map; import static java.lang.String.format; @@ -278,6 +280,8 @@ void refresh_invalidAuthenticationToken_missingAccessToken() { .subject(CONSUMER_DID) .audience("did:web:bob") .jwtID(getJwtId(accessToken)) + .issueTime(Date.from(Instant.now())) + .expirationTime(Date.from(Instant.now().plusSeconds(60))) .build(); var authToken = createJwt(consumerKey, claims); @@ -311,6 +315,8 @@ void refresh_invalidAuthenticationToken_missingAudience() { .subject(CONSUMER_DID) /* missing: .audience("did:web:bob")*/ .jwtID(getJwtId(accessToken)) + .issueTime(Date.from(Instant.now())) + .expirationTime(Date.from(Instant.now().plusSeconds(60))) .build(); var authToken = createJwt(consumerKey, claims); @@ -347,6 +353,8 @@ void refresh_invalidTokenId() { .subject(CONSUMER_DID) .audience("did:web:bob") .jwtID(tokenId) + .issueTime(Date.from(Instant.now())) + .expirationTime(Date.from(Instant.now().plusSeconds(60))) .build(); var authToken = createJwt(consumerKey, claims); @@ -377,6 +385,8 @@ private String createAuthToken(String accessToken, ECKey signerKey) { .subject(CONSUMER_DID) .audience("did:web:bob") .jwtID(getJwtId(accessToken)) + .issueTime(Date.from(Instant.now())) + .expirationTime(Date.from(Instant.now().plusSeconds(60))) .build(); return createJwt(signerKey, claims); } From 729ec487f698805c9539b86583bf47a3b6c6a24f Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Mon, 24 Aug 2026 08:34:07 +0200 Subject: [PATCH 248/259] fix: kafka and tsk-dcp flaky tests (#3023) --- .../kafka-broker-extension/build.gradle.kts | 1 + ...KafkaAclServiceImplTestcontainersTest.java | 53 ++++++++++++------- .../edc/tests/kafka/KafkaExtension.java | 7 ++- .../transfer/AbstractDcpConsumerPullTest.java | 17 ++++-- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/build.gradle.kts b/edc-extensions/dataplane/kafka/kafka-broker-extension/build.gradle.kts index c89111eaf0..f63d90a807 100644 --- a/edc-extensions/dataplane/kafka/kafka-broker-extension/build.gradle.kts +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/build.gradle.kts @@ -30,6 +30,7 @@ dependencies { implementation(project(":edc-extensions:dataplane:kafka:data-address-kafka")) testImplementation(libs.edc.junit) + testImplementation(libs.awaitility) testImplementation(libs.testcontainers.junit) testImplementation(libs.testcontainers.kafka) } diff --git a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTestcontainersTest.java b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTestcontainersTest.java index c3b78dddb9..7f75d75a44 100644 --- a/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTestcontainersTest.java +++ b/edc-extensions/dataplane/kafka/kafka-broker-extension/src/test/java/org/eclipse/tractusx/edc/dataplane/kafka/acl/KafkaAclServiceImplTestcontainersTest.java @@ -23,7 +23,6 @@ import org.apache.kafka.clients.admin.Admin; import org.apache.kafka.clients.admin.AdminClientConfig; import org.apache.kafka.clients.admin.CreateTopicsResult; -import org.apache.kafka.clients.admin.DescribeAclsResult; import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecords; @@ -59,9 +58,11 @@ import java.util.List; import java.util.Properties; import java.util.concurrent.ExecutionException; +import java.util.function.Predicate; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.awaitility.Awaitility.await; @Testcontainers class KafkaAclServiceImplTestcontainersTest { @@ -70,6 +71,8 @@ class KafkaAclServiceImplTestcontainersTest { private static final String TEST_TOPIC = "test-topic"; private static final TopicPartition TEST_PARTITION = new TopicPartition(TEST_TOPIC, 0); private static final Duration POLL_TIMEOUT = Duration.ofSeconds(2); + private static final Duration ACL_PROPAGATION_TIMEOUT = Duration.ofSeconds(30); + private static final Duration ACL_POLL_INTERVAL = Duration.ofMillis(200); private static final String TEST_OAUTH_SUBJECT = "test-user"; // Deliberately distinct from the OAuth subject: the GROUP ACL is named by the group prefix (PREFIXED), // while the ACL principal remains the subject. @@ -125,13 +128,12 @@ void tearDown() { } @Test - void createAclsForSubject_shouldCreateAclsSuccessfully() throws Exception { + void createAclsForSubject_shouldCreateAclsSuccessfully() { Result result = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); assertThat(result.succeeded()).isTrue(); - DescribeAclsResult describeResult = adminClient.describeAcls(AclBindingFilter.ANY); - Collection aclBindings = describeResult.values().get(); + Collection aclBindings = awaitAcls(acls -> acls.size() == 3); assertThat(aclBindings).hasSize(3); @@ -169,7 +171,7 @@ void topicAccess_withValidAcls_shouldBeAllowed() throws Exception { consumer.assign(List.of(TEST_PARTITION)); consumer.seekToBeginning(List.of(TEST_PARTITION)); - ConsumerRecords records = consumer.poll(POLL_TIMEOUT); + ConsumerRecords records = pollUntilRecords(consumer); assertThat(records.count()).isEqualTo(1); assertThat(records.iterator().next().value()).isEqualTo("test-value"); @@ -190,38 +192,34 @@ void topicAccess_withWrongUser_shouldBeBlocked() { } @Test - void revokeAclsForTransferProcess_shouldRemoveAclsSuccessfully() throws Exception { + void revokeAclsForTransferProcess_shouldRemoveAclsSuccessfully() { Result createResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); assertThat(createResult.succeeded()).isTrue(); - DescribeAclsResult describeResult = adminClient.describeAcls(AclBindingFilter.ANY); - Collection aclsBeforeRevoke = describeResult.values().get(); + Collection aclsBeforeRevoke = awaitAcls(acls -> acls.size() == 3); Result revokeResult = aclService.revokeAclsForTransferProcess(TEST_TRANSFER_PROCESS_ID); assertThat(revokeResult.succeeded()).isTrue(); - DescribeAclsResult describeAfterRevoke = adminClient.describeAcls(AclBindingFilter.ANY); - Collection aclsAfterRevoke = describeAfterRevoke.values().get(); + Collection aclsAfterRevoke = awaitAcls(Collection::isEmpty); assertThat(aclsBeforeRevoke).hasSize(3); assertThat(aclsAfterRevoke).isEmpty(); } @Test - void revokeAclsForSubject_shouldRemoveAclsSuccessfully() throws Exception { + void revokeAclsForSubject_shouldRemoveAclsSuccessfully() { Result createResult = aclService.createAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX, TEST_TRANSFER_PROCESS_ID); assertThat(createResult.succeeded()).isTrue(); - DescribeAclsResult describeResult = adminClient.describeAcls(AclBindingFilter.ANY); - Collection aclsBeforeRevoke = describeResult.values().get(); + Collection aclsBeforeRevoke = awaitAcls(acls -> acls.size() == 3); Result revokeResult = aclService.revokeAclsForSubject(TEST_OAUTH_SUBJECT, TEST_TOPIC, TEST_GROUP_PREFIX); assertThat(revokeResult.succeeded()).isTrue(); - DescribeAclsResult describeAfterRevoke = adminClient.describeAcls(AclBindingFilter.ANY); - Collection aclsAfterRevoke = describeAfterRevoke.values().get(); + Collection aclsAfterRevoke = awaitAcls(Collection::isEmpty); assertThat(aclsBeforeRevoke).hasSize(3); assertThat(aclsAfterRevoke).isEmpty(); @@ -238,7 +236,7 @@ void topicAccess_afterAclRevocation_shouldBeBlocked() throws Exception { try (KafkaConsumer consumer = new KafkaConsumer<>(consumerProps)) { consumer.assign(List.of(TEST_PARTITION)); consumer.seekToBeginning(List.of(TEST_PARTITION)); - ConsumerRecords records = consumer.poll(POLL_TIMEOUT); + ConsumerRecords records = pollUntilRecords(consumer); assertThat(records.count()).isEqualTo(1); } @@ -259,7 +257,7 @@ void revokeAclsForTransferProcess_withNonExistentId_shouldSucceed() { } @Test - void multipleTransferProcesses_shouldTrackAclsIndependently() throws Exception { + void multipleTransferProcesses_shouldTrackAclsIndependently() { String transferProcess1 = "transfer-1"; String transferProcess2 = "transfer-2"; String user1 = "user1"; @@ -274,8 +272,9 @@ void multipleTransferProcesses_shouldTrackAclsIndependently() throws Exception { Result revokeResult = aclService.revokeAclsForTransferProcess(transferProcess1); assertThat(revokeResult.succeeded()).isTrue(); - DescribeAclsResult describeResult = adminClient.describeAcls(AclBindingFilter.ANY); - Collection remainingAcls = describeResult.values().get(); + Collection remainingAcls = awaitAcls(acls -> + acls.stream().noneMatch(acl -> acl.entry().principal().equals("User:" + user1)) && + acls.stream().anyMatch(acl -> acl.entry().principal().equals("User:" + user2))); boolean user2AclsExist = remainingAcls.stream() .anyMatch(acl -> acl.entry().principal().equals("User:" + user2)); @@ -340,6 +339,22 @@ void consumerGroupJoin_withNonPrefixedGroup_shouldBeBlocked() throws Exception { } } + private Collection awaitAcls(Predicate> condition) { + return await() + .atMost(ACL_PROPAGATION_TIMEOUT) + .pollInterval(ACL_POLL_INTERVAL) + .until(() -> adminClient.describeAcls(AclBindingFilter.ANY).values().get(), condition); + } + + private ConsumerRecords pollUntilRecords(KafkaConsumer consumer) { + ConsumerRecords records = ConsumerRecords.empty(); + long deadline = System.currentTimeMillis() + ACL_PROPAGATION_TIMEOUT.toMillis(); + while (records.isEmpty() && System.currentTimeMillis() < deadline) { + records = consumer.poll(POLL_TIMEOUT); + } + return records; + } + private Properties createConsumerProperties(String username) { return createConsumerProperties(username, GROUP_ID); } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/kafka/KafkaExtension.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/kafka/KafkaExtension.java index 225e1454d2..cacda7262a 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/kafka/KafkaExtension.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/kafka/KafkaExtension.java @@ -115,8 +115,11 @@ public List> consume(String bootstrapServers, Str var collected = new ArrayList>(); try (var consumer = new KafkaConsumer(props)) { consumer.subscribe(Collections.singletonList(topic)); - ConsumerRecords records = consumer.poll(timeout); - records.forEach(collected::add); + var deadline = System.nanoTime() + timeout.toNanos(); + while (collected.isEmpty() && System.nanoTime() < deadline) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(500)); + records.forEach(collected::add); + } } return collected; } diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java index a4dadbff9c..e4f303a0fe 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java @@ -104,19 +104,26 @@ void transferData_whenContractPolicyFulfilled(JsonObject contractPolicy, String var accessPolicyId = provider().createPolicyDefinition(createAccessPolicy(consumer().getBpn())); var contractPolicyId = provider().createPolicyDefinition(contractPolicy); provider().createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); - var transferProcessId = consumer().requestAssetFrom(assetId, provider()) + + var initialTransferProcessId = consumer().requestAssetFrom(assetId, provider()) .withTransferType("HttpData-PULL") .withDestination(httpDataDestination()) .execute(); + var agreementId = consumer().getTransferProcessField(initialTransferProcessId, "contractId"); + + var transferProcessId = new AtomicReference<>(initialTransferProcessId); var edr = new AtomicReference(); - // wait until transfer process completes await().pollInterval(fibonacci()) .atMost(ASYNC_TIMEOUT) .untilAsserted(() -> { - var tpState = consumer().getTransferProcessState(transferProcessId); - assertThat(tpState).isNotNull().isEqualTo(TransferProcessStates.STARTED.toString()); + var current = transferProcessId.get(); + if (TransferProcessStates.TERMINATED.toString().equals(consumer().getTransferProcessState(current))) { + current = consumer().initiateTransfer(provider(), agreementId, null, httpDataDestination(), "HttpData-PULL"); + transferProcessId.set(current); + } + assertThat(consumer().getTransferProcessState(current)).isEqualTo(TransferProcessStates.STARTED.toString()); }); // wait until EDC is available on the consumer side @@ -124,7 +131,7 @@ void transferData_whenContractPolicyFulfilled(JsonObject contractPolicy, String await().pollInterval(fibonacci()) .atMost(ASYNC_TIMEOUT) .untilAsserted(() -> { - edr.set(consumer().edrs().getEdr(transferProcessId)); + edr.set(consumer().edrs().getEdr(transferProcessId.get())); assertThat(edr).isNotNull(); }); From 9347d784a5b6ba75735a7a187ac4d6e0c9b37cd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo?= <18561736+bmg13@users.noreply.github.com> Date: Mon, 24 Aug 2026 07:45:51 +0100 Subject: [PATCH 249/259] feat: include validation to Contract Definition Policies to version 0.13.0 (#3013) * Cd Policy Validations. * Cd Policy Validations. * Cd Policy Validations. * Fix Catalog Tests. * Fix DcpConsumerPull Tests. * Fix DcpConsumerPull Tests. * Fix NegotiateEdrTest Tests. * Fix NegotiateEdrTest Tests. * Fix ProviderPushBase Tests. * Fix CatalogTestDspV08 Tests. * Fix KafkaPullEndToEnd Tests. * Fix ContractDefinitionPoliciesValidators Tests. * Fix Small Checkstyle. * Fix PolicyHelperFunctions V4. * Fix AbstractDcpConsumerPull Tests. * Fix AbstractDcpConsumerPull Tests. --- .../edc-controlplane-base/build.gradle.kts | 1 + .../build.gradle.kts | 31 ++++ ...tDefinitionPoliciesValidatorExtension.java | 70 ++++++++ .../NotReferencedByContractDefinition.java | 74 ++++++++ .../PolicyActionMatchesExpected.java | 88 ++++++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 +++ ...NotReferencedByContractDefinitionTest.java | 104 +++++++++++ .../PolicyActionMatchesExpectedTest.java | 158 +++++++++++++++++ .../tests/helpers/PolicyHelperFunctions.java | 162 +++++++++++++----- .../participant/TractusxParticipantBase.java | 26 ++- .../tests/transfer/ConsumerPullBaseTest.java | 12 +- .../tests/transfer/ProviderPushBaseTest.java | 38 +++- .../edc/tests/catalog/CatalogTest.java | 13 +- .../edc/tests/catalog/CatalogTestDspV08.java | 10 +- .../transfer/AbstractDcpConsumerPullTest.java | 6 +- .../tests/transfer/CredentialSpoofTest.java | 14 +- .../edc/tests/edrv2/NegotiateEdrTest.java | 3 +- .../transfer/AzureToAzureEndToEndTest.java | 17 +- .../tests/transfer/S3ToS3EndToEndTest.java | 12 +- .../tests/transfer/KafkaPullEndToEndTest.java | 7 +- ...tractDefinitionPoliciesValidatorsTest.java | 149 ++++++++++++++++ .../EmptyAssetSelectorValidatorTest.java | 30 ++-- .../policy/PolicyDefinitionEndToEndTest.java | 6 +- .../tests/transfer/RetireAgreementTest.java | 3 +- .../transfer/TransferPullEndToEndTest.java | 2 +- .../TransferWithTokenRefreshTest.java | 12 +- settings.gradle.kts | 1 + 27 files changed, 961 insertions(+), 108 deletions(-) create mode 100644 edc-extensions/validators/contract-definition-policies/build.gradle.kts create mode 100644 edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/ContractDefinitionPoliciesValidatorExtension.java create mode 100644 edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/NotReferencedByContractDefinition.java create mode 100644 edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/PolicyActionMatchesExpected.java create mode 100644 edc-extensions/validators/contract-definition-policies/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/validators/contract-definition-policies/src/test/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/NotReferencedByContractDefinitionTest.java create mode 100644 edc-extensions/validators/contract-definition-policies/src/test/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/PolicyActionMatchesExpectedTest.java create mode 100644 edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/ContractDefinitionPoliciesValidatorsTest.java diff --git a/edc-controlplane/edc-controlplane-base/build.gradle.kts b/edc-controlplane/edc-controlplane-base/build.gradle.kts index 8e1d6e10a3..d7b3ee03cd 100644 --- a/edc-controlplane/edc-controlplane-base/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-base/build.gradle.kts @@ -65,6 +65,7 @@ dependencies { implementation(project(":edc-extensions:edr:edr-api-v2")) implementation(project(":edc-extensions:edr:edr-callback")) implementation(project(":edc-extensions:tokenrefresh-handler")) + implementation(project(":edc-extensions:validators:contract-definition-policies")) implementation(project(":edc-extensions:validators:empty-asset-selector")) implementation(project(":edc-extensions:connector-discovery:connector-discovery-api")) implementation(project(":edc-extensions:connector-discovery:cx-connector-discovery")) diff --git a/edc-extensions/validators/contract-definition-policies/build.gradle.kts b/edc-extensions/validators/contract-definition-policies/build.gradle.kts new file mode 100644 index 0000000000..2d4b3d31ec --- /dev/null +++ b/edc-extensions/validators/contract-definition-policies/build.gradle.kts @@ -0,0 +1,31 @@ +/******************************************************************************** + * Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + implementation(libs.edc.spi.controlplane) + implementation(libs.edc.lib.validator) + implementation(project(":edc-extensions:cx-policy")) + + testImplementation(libs.edc.junit) +} diff --git a/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/ContractDefinitionPoliciesValidatorExtension.java b/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/ContractDefinitionPoliciesValidatorExtension.java new file mode 100644 index 0000000000..10598b1b21 --- /dev/null +++ b/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/ContractDefinitionPoliciesValidatorExtension.java @@ -0,0 +1,70 @@ +/******************************************************************************** + * Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.validators.contractdefinitionpolicies; + +import org.eclipse.edc.connector.controlplane.services.spi.contractdefinition.ContractDefinitionService; +import org.eclipse.edc.connector.controlplane.services.spi.policydefinition.PolicyDefinitionService; +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.validator.jsonobject.JsonObjectValidator; +import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; + +import static org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition.CONTRACT_DEFINITION_ACCESSPOLICY_ID; +import static org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition.CONTRACT_DEFINITION_CONTRACTPOLICY_ID; +import static org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition.CONTRACT_DEFINITION_TYPE; +import static org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE; +import static org.eclipse.tractusx.edc.policy.cx.validator.PolicyValidationConstants.ACTION_ACCESS; +import static org.eclipse.tractusx.edc.policy.cx.validator.PolicyValidationConstants.ACTION_USAGE; + +@Extension(ContractDefinitionPoliciesValidatorExtension.NAME) +public class ContractDefinitionPoliciesValidatorExtension implements ServiceExtension { + + public static final String NAME = "Contract Definition Policies Validator Extension"; + + @Inject + private JsonObjectValidatorRegistry validatorRegistry; + + @Inject + private PolicyDefinitionService policyDefinitionService; + + @Inject + private ContractDefinitionService contractDefinitionService; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + var contractDefinitionsValidator = JsonObjectValidator.newValidator() + .verify(CONTRACT_DEFINITION_ACCESSPOLICY_ID, path -> new PolicyActionMatchesExpected(path, policyDefinitionService, ACTION_ACCESS)) + .verify(CONTRACT_DEFINITION_CONTRACTPOLICY_ID, path -> new PolicyActionMatchesExpected(path, policyDefinitionService, ACTION_USAGE)) + .build(); + validatorRegistry.register(CONTRACT_DEFINITION_TYPE, contractDefinitionsValidator); + + var policyDefinitionsValidator = JsonObjectValidator.newValidator() + .verifyId(path -> new NotReferencedByContractDefinition(path, contractDefinitionService)) + .build(); + validatorRegistry.register(EDC_POLICY_DEFINITION_TYPE, policyDefinitionsValidator); + } +} diff --git a/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/NotReferencedByContractDefinition.java b/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/NotReferencedByContractDefinition.java new file mode 100644 index 0000000000..3b8bab5b8f --- /dev/null +++ b/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/NotReferencedByContractDefinition.java @@ -0,0 +1,74 @@ +/******************************************************************************** + * Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.validators.contractdefinitionpolicies; + +import jakarta.json.JsonString; +import org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition; +import org.eclipse.edc.connector.controlplane.services.spi.contractdefinition.ContractDefinitionService; +import org.eclipse.edc.spi.query.QuerySpec; +import org.eclipse.edc.spi.result.ServiceResult; +import org.eclipse.edc.validator.jsonobject.JsonLdPath; +import org.eclipse.edc.validator.spi.ValidationResult; +import org.eclipse.edc.validator.spi.Validator; + +import java.util.List; +import java.util.stream.Stream; + +import static org.eclipse.edc.spi.query.Criterion.criterion; +import static org.eclipse.edc.spi.query.CriterionOperatorRegistry.EQUAL; +import static org.eclipse.edc.spi.result.ServiceResult.conflict; +import static org.eclipse.edc.spi.result.ServiceResult.success; +import static org.eclipse.edc.validator.spi.Violation.violation; + +public class NotReferencedByContractDefinition implements Validator { + + private final JsonLdPath path; + private final ContractDefinitionService contractDefinitionService; + + public NotReferencedByContractDefinition(JsonLdPath path, ContractDefinitionService contractDefinitionService) { + this.path = path; + this.contractDefinitionService = contractDefinitionService; + } + + @Override + public ValidationResult validate(JsonString id) { + var queryAccessPolicy = QuerySpec.Builder.newInstance() + .filter(criterion("accessPolicyId", EQUAL, id.getString())) + .build(); + + var queryContractPolicy = QuerySpec.Builder.newInstance() + .filter(criterion("contractPolicyId", EQUAL, id.getString())) + .build(); + + var referencedContractDefinitions = contractDefinitionService.search(queryAccessPolicy) + .compose(accessPolicyMatches -> contractDefinitionService.search(queryContractPolicy) + .compose(contractPolicyMatches -> ServiceResult.success( + Stream.concat(accessPolicyMatches.stream(), contractPolicyMatches.stream()).toList()))); + + return referencedContractDefinitions + .compose(this::isListEmpty) + .map(v -> ValidationResult.success()) + .orElse(failure -> ValidationResult.failure(violation(failure.getFailureDetail(), path.toString()))); + } + + private ServiceResult isListEmpty(List list) { + return list.isEmpty() ? success() : conflict("Policy Definition is referenced by a Contract Definition"); + } +} diff --git a/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/PolicyActionMatchesExpected.java b/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/PolicyActionMatchesExpected.java new file mode 100644 index 0000000000..d918bc6030 --- /dev/null +++ b/edc-extensions/validators/contract-definition-policies/src/main/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/PolicyActionMatchesExpected.java @@ -0,0 +1,88 @@ +/******************************************************************************** + * Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.validators.contractdefinitionpolicies; + +import jakarta.json.JsonObject; +import org.eclipse.edc.connector.controlplane.services.spi.policydefinition.PolicyDefinitionService; +import org.eclipse.edc.policy.model.Action; +import org.eclipse.edc.policy.model.Permission; +import org.eclipse.edc.validator.jsonobject.JsonLdPath; +import org.eclipse.edc.validator.spi.ValidationResult; +import org.eclipse.edc.validator.spi.Validator; + +import java.util.Optional; + +import static java.lang.String.format; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VALUE; +import static org.eclipse.edc.validator.spi.Violation.violation; + +public class PolicyActionMatchesExpected implements Validator { + + private final JsonLdPath path; + private final PolicyDefinitionService policyDefinitionService; + private final String expectedAction; + + public PolicyActionMatchesExpected( + JsonLdPath path, + PolicyDefinitionService policyDefinitionService, + String expectedAction) { + this.path = path; + this.policyDefinitionService = policyDefinitionService; + this.expectedAction = expectedAction; + } + + @Override + public ValidationResult validate(JsonObject input) { + var policyId = getPolicyId(input); + if (policyId == null) { + return ValidationResult.failure( + violation(format("Could not get value for path '%s' in '%s'", path, input), path.toString())); + } + + var policyDefinition = policyDefinitionService.findById(policyId); + if (policyDefinition == null) { + return ValidationResult.failure( + violation(format("Policy with ID '%s' does not exist", policyId), path.toString())); + } + + var hasExpectedAction = policyDefinition.getPolicy().getPermissions().stream() + .map(Permission::getAction) + .map(Action::getType) + .allMatch(expectedAction::equals); + + return hasExpectedAction + ? ValidationResult.success() + : ValidationResult.failure( + violation(format("Policy '%s' does not have the expected permission action '%s'", + policyId, expectedAction), path.toString())); + } + + private String getPolicyId(JsonObject input) { + try { + return Optional.ofNullable(input.getJsonArray(path.last())) + .filter(it -> !it.isEmpty()) + .map(it -> it.getJsonObject(0)) + .map(it -> it.getString(VALUE)) + .orElse(null); + } catch (ClassCastException e) { + return null; + } + } +} diff --git a/edc-extensions/validators/contract-definition-policies/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/validators/contract-definition-policies/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..2c73ba36df --- /dev/null +++ b/edc-extensions/validators/contract-definition-policies/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +org.eclipse.tractusx.edc.validators.contractdefinitionpolicies.ContractDefinitionPoliciesValidatorExtension diff --git a/edc-extensions/validators/contract-definition-policies/src/test/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/NotReferencedByContractDefinitionTest.java b/edc-extensions/validators/contract-definition-policies/src/test/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/NotReferencedByContractDefinitionTest.java new file mode 100644 index 0000000000..3023114dc5 --- /dev/null +++ b/edc-extensions/validators/contract-definition-policies/src/test/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/NotReferencedByContractDefinitionTest.java @@ -0,0 +1,104 @@ +/******************************************************************************** + * Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.validators.contractdefinitionpolicies; + +import jakarta.json.Json; +import jakarta.json.JsonString; +import org.assertj.core.api.Assertions; +import org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition; +import org.eclipse.edc.connector.controlplane.services.spi.contractdefinition.ContractDefinitionService; +import org.eclipse.edc.spi.query.QuerySpec; +import org.eclipse.edc.spi.result.ServiceResult; +import org.eclipse.edc.validator.jsonobject.JsonLdPath; +import org.eclipse.edc.validator.spi.ValidationFailure; +import org.eclipse.edc.validator.spi.Violation; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.InstanceOfAssertFactories.list; +import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class NotReferencedByContractDefinitionTest { + + private final JsonLdPath path = new JsonLdPath("@id"); + private final ContractDefinitionService contractDefinitionService = mock(); + private final NotReferencedByContractDefinition validator = new NotReferencedByContractDefinition(path, contractDefinitionService); + private final JsonString policyId = Json.createValue("policy-id"); + + @Test + void shouldFail_whenSearchAccessPolicyFails() { + when(contractDefinitionService.search(any(QuerySpec.class))) + .thenReturn(ServiceResult.conflict("accessPolicy search failed")); + + var result = validator.validate(policyId); + + assertThat(result).isFailed() + .extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .anySatisfy(violation -> Assertions.assertThat(violation.path()).isEqualTo(path.toString())) + .anySatisfy(violation -> Assertions.assertThat(violation.message()).isEqualTo("accessPolicy search failed")); + } + + @Test + void shouldFail_whenSearchContractPolicyFails() { + when(contractDefinitionService.search(any(QuerySpec.class))) + .thenReturn(ServiceResult.success(List.of())) + .thenReturn(ServiceResult.conflict("contractPolicy search failed")); + + var result = validator.validate(policyId); + + assertThat(result).isFailed() + .extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .anySatisfy(violation -> Assertions.assertThat(violation.path()).isEqualTo(path.toString())) + .anySatisfy(violation -> Assertions.assertThat(violation.message()).isEqualTo("contractPolicy search failed")); + } + + @Test + void shouldFail_whenPolicyIsReferencedByContractDefinition() { + when(contractDefinitionService.search(any(QuerySpec.class))) + .thenReturn(ServiceResult.success(List.of(mock(ContractDefinition.class)))) + .thenReturn(ServiceResult.success(List.of())); + + var result = validator.validate(policyId); + + assertThat(result).isFailed() + .extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .anySatisfy(violation -> Assertions.assertThat(violation.path()).isEqualTo(path.toString())) + .anySatisfy(violation -> Assertions.assertThat(violation.message()) + .isEqualTo("Policy Definition is referenced by a Contract Definition")); + } + + @Test + void shouldPass_whenPolicyIsNotReferencedByContractDefinition() { + when(contractDefinitionService.search(any(QuerySpec.class))) + .thenReturn(ServiceResult.success(List.of())) + .thenReturn(ServiceResult.success(List.of())); + + var result = validator.validate(policyId); + + assertThat(result).isSucceeded(); + } +} diff --git a/edc-extensions/validators/contract-definition-policies/src/test/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/PolicyActionMatchesExpectedTest.java b/edc-extensions/validators/contract-definition-policies/src/test/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/PolicyActionMatchesExpectedTest.java new file mode 100644 index 0000000000..1c91af91ab --- /dev/null +++ b/edc-extensions/validators/contract-definition-policies/src/test/java/org/eclipse/tractusx/edc/validators/contractdefinitionpolicies/PolicyActionMatchesExpectedTest.java @@ -0,0 +1,158 @@ +/******************************************************************************** + * Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.validators.contractdefinitionpolicies; + +import jakarta.json.JsonObject; +import org.assertj.core.api.Assertions; +import org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition; +import org.eclipse.edc.connector.controlplane.services.spi.policydefinition.PolicyDefinitionService; +import org.eclipse.edc.policy.model.Action; +import org.eclipse.edc.policy.model.Permission; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.validator.jsonobject.JsonLdPath; +import org.eclipse.edc.validator.spi.ValidationFailure; +import org.eclipse.edc.validator.spi.Violation; +import org.junit.jupiter.api.Test; + +import static jakarta.json.Json.createArrayBuilder; +import static jakarta.json.Json.createObjectBuilder; +import static org.assertj.core.api.InstanceOfAssertFactories.list; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VALUE; +import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class PolicyActionMatchesExpectedTest { + + private final JsonLdPath path = new JsonLdPath("contractPolicyId"); + private final PolicyDefinitionService policyDefinitionService = mock(); + private static final String EXPECTED_ACTION = "use"; + private final PolicyActionMatchesExpected policyActionMatchesExpected = new PolicyActionMatchesExpected( + path, + policyDefinitionService, + EXPECTED_ACTION); + + private JsonObject createInput() { + // Simplified input for testing purposes. + // Real input is a Contract Definition in expanded JsonLD + return createObjectBuilder() + .add("@id", "id") + .add("accessPolicyId", createArrayBuilder().add(createObjectBuilder().add(VALUE, "policy-id"))) + .add("contractPolicyId", createArrayBuilder().add(createObjectBuilder().add(VALUE, "policy-id"))) + .build(); + } + + private PolicyDefinition createPolicyDefinitionWithAction(String actionType) { + var action = Action.Builder.newInstance() + .type(actionType) + .build(); + var permission = Permission.Builder.newInstance() + .action(action) + .build(); + var policy = Policy.Builder.newInstance() + .permission(permission) + .build(); + + return PolicyDefinition.Builder.newInstance() + .id("policy-id") + .policy(policy) + .build(); + } + + @Test + void shouldFail_whenJsonLdPathIsNotFound() { + var input = createObjectBuilder().build(); + + var result = policyActionMatchesExpected.validate(input); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .anySatisfy(violation -> Assertions.assertThat(violation.path()).isEqualTo(path.toString())) + .anySatisfy(violation -> Assertions.assertThat(violation.message()) + .isEqualTo("Could not get value for path 'contractPolicyId' in '{}'")); + } + + @Test + void shouldFail_whenJsonLdPathIsNotJsonArray() { + var input = createObjectBuilder() + .add("contractPolicyId", 123) + .build(); + + var result = policyActionMatchesExpected.validate(input); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .anySatisfy(violation -> Assertions.assertThat(violation.path()).isEqualTo(path.toString())) + .anySatisfy(violation -> Assertions.assertThat(violation.message()) + .isEqualTo("Could not get value for path 'contractPolicyId' in '{\"contractPolicyId\":123}'")); + } + + @Test + void shouldFail_whenJsonLdPathIsNotJsonLdValue() { + var input = createObjectBuilder() + .add("contractPolicyId", createArrayBuilder()) + .build(); + + var result = policyActionMatchesExpected.validate(input); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .anySatisfy(violation -> Assertions.assertThat(violation.path()).isEqualTo(path.toString())) + .anySatisfy(violation -> Assertions.assertThat(violation.message()) + .isEqualTo("Could not get value for path 'contractPolicyId' in '{\"contractPolicyId\":[]}'")); + } + + @Test + void shouldFail_whenPolicyDoesNotExist() { + when(policyDefinitionService.findById("policy-id")).thenReturn(null); + + var result = policyActionMatchesExpected.validate(createInput()); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .anySatisfy(violation -> Assertions.assertThat(violation.path()).isEqualTo(path.toString())) + .anySatisfy(violation -> Assertions.assertThat(violation.message()) + .isEqualTo("Policy with ID 'policy-id' does not exist")); + } + + @Test + void shouldFail_whenExpectedActionDoesNotMatchActualAction() { + var policyDefinition = createPolicyDefinitionWithAction("access"); + when(policyDefinitionService.findById("policy-id")).thenReturn(policyDefinition); + + var result = policyActionMatchesExpected.validate(createInput()); + + assertThat(result).isFailed().extracting(ValidationFailure::getViolations).asInstanceOf(list(Violation.class)) + .isNotEmpty() + .anySatisfy(violation -> Assertions.assertThat(violation.path()).isEqualTo(path.toString())) + .anySatisfy(violation -> Assertions.assertThat(violation.message()) + .isEqualTo("Policy 'policy-id' does not have the expected permission action 'use'")); + } + + @Test + void shouldPass_whenExpectedActionMatchesActualAction() { + var policyDefinition = createPolicyDefinitionWithAction(EXPECTED_ACTION); + when(policyDefinitionService.findById("policy-id")).thenReturn(policyDefinition); + + var result = policyActionMatchesExpected.validate(createInput()); + + assertThat(result).isSucceeded(); + } +} diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/helpers/PolicyHelperFunctions.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/helpers/PolicyHelperFunctions.java index 08e100b995..bdb1fe6eca 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/helpers/PolicyHelperFunctions.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/helpers/PolicyHelperFunctions.java @@ -25,27 +25,36 @@ import jakarta.json.Json; import jakarta.json.JsonArrayBuilder; import jakarta.json.JsonObject; +import jakarta.json.JsonObjectBuilder; +import org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition; +import org.eclipse.edc.policy.model.AtomicConstraint; import org.eclipse.edc.policy.model.Operator; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.eclipse.edc.connector.controlplane.test.system.utils.PolicyFixtures.policy; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; 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.ODRL_LOGICAL_CONSTRAINT_TYPE; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.eclipse.tractusx.edc.cx.CxJsonLdExtension.CX_POLICY_2025_09_CONTEXT; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_NS; public class PolicyHelperFunctions { public static final String ODRL_CONTEXT = "https://w3id.org/dspace/2025/1/odrl-profile.jsonld"; private static final String FRAMEWORK_AGREEMENT_KEY = "FrameworkAgreement"; + public static final String FRAMEWORK_AGREEMENT_LITERAL = CX_POLICY_2025_09_NS + "FrameworkAgreement"; private static final String USAGE_PURPOSE_KEY = "UsagePurpose"; + private static final String USAGE_PURPOSE_LITERAL = CX_POLICY_2025_09_NS + "UsagePurpose"; public static final String DATA_USAGE_END_DATE_KEY = "DataUsageEndDate"; public static final String DATA_USAGE_END_DURATION_KEY = "DataUsageEndDurationDays"; @@ -60,22 +69,34 @@ public static JsonObject emptyPolicy() { .build(); } - public static JsonObject bpnPolicy(Operator operator, String... bpns) { - JsonArrayBuilder bpnArray = Json.createArrayBuilder(); - Stream.of(bpns).forEach(bpnArray::add); + /** + * Creates a {@link PolicyDefinition} using the given ID, that contains equality constraints for each of the given BusinessPartnerNumbers: + * each BPN is converted into an {@link AtomicConstraint} {@code BusinessPartnerNumber EQ [BPN]}. + */ - var bpnConstraint = Json.createObjectBuilder() - .add("leftOperand", "BusinessPartnerNumber") - .add("operator", operatorValueWithoutNamespace(operator)) - .add("rightOperand", bpnArray) + public static JsonObject frameworkPolicy(String id, Map permissions, String action) { + return policyDefinitionBuilder(frameworkPolicy(permissions, action)) + .add(ID, id) .build(); + } - var permission = Json.createObjectBuilder() - .add("action", "access") - .add("constraint", Json.createArrayBuilder() - .add(bpnConstraint) - .build()) + public static JsonObject frameworkPolicy(Map permissions, String action) { + return Json.createObjectBuilder() + .add(CONTEXT, Json.createArrayBuilder() + .add(ODRL_CONTEXT) + .add(CX_POLICY_2025_09_CONTEXT)) + .add(TYPE, "Set") + .add(ID, "id") + .add("permission", Json.createArrayBuilder() + .add(frameworkConstraint(new HashMap<>(permissions), action, Operator.EQ, false))) .build(); + } + + public static JsonObject frameworkPolicy(Map permissions, String action, String operator) { + return frameworkPolicy(permissions, action, Operator.valueOf(operator)); + } + + public static JsonObject frameworkPolicy(Map permissions, String action, Operator operator) { return Json.createObjectBuilder() .add(CONTEXT, Json.createArrayBuilder() .add(ODRL_CONTEXT) @@ -83,7 +104,7 @@ public static JsonObject bpnPolicy(Operator operator, String... bpns) { .add(TYPE, "Set") .add(ID, "id") .add("permission", Json.createArrayBuilder() - .add(permission)) + .add(frameworkConstraint(new HashMap<>(permissions), action, operator, false))) .build(); } @@ -109,6 +130,10 @@ public static JsonObject bpnGroupPolicy(String operator, boolean rightOperandAsA .build(); } + public static JsonObject frameworkPolicy(String leftOperand, Operator operator, Object rightOperand, String action) { + return frameworkPolicy(leftOperand, operator, rightOperand, action, false); + } + public static JsonObject frameworkPolicy(String leftOperand, Operator operator, Object rightOperand, String action, boolean createRightOperandsAsArray) { var constraint = atomicConstraint(leftOperand, operatorValueWithoutNamespace(operator), rightOperand, createRightOperandsAsArray); @@ -158,28 +183,27 @@ private static JsonObject usagePurposeConstraint() { .build(); } - public static JsonObject frameworkConstraint(Map operandMappings, String action, Operator operator, boolean createRightOperandsAsArray) { - var constraints = operandMappings.entrySet().stream() - .map(constraint -> atomicConstraint(constraint.getKey(), operatorValueWithoutNamespace(operator), constraint.getValue(), createRightOperandsAsArray)) - .collect(Json::createArrayBuilder, JsonArrayBuilder::add, JsonArrayBuilder::add); + public static JsonObject legacyFrameworkPolicy() { + var constraint1 = atomicConstraint(CX_POLICY_NS + "FrameworkAgreement", Operator.EQ.getOdrlRepresentation(), "DataExchangeGovernance:1.0", false); + var constraint2 = atomicConstraint(CX_POLICY_NS + "UsagePurpose", Operator.EQ.getOdrlRepresentation(), "cx.core.digitalTwinRegistry:1", false); - if (action.contains("use")) { - if (!operandMappings.containsKey(FRAMEWORK_AGREEMENT_KEY)) { - constraints.add(frameworkAgreementConstraint()); - } - if (!operandMappings.containsKey(USAGE_PURPOSE_KEY)) { - constraints.add(usagePurposeConstraint()); - } - } + var constraintsBuilder = Json.createArrayBuilder() + .add(constraint1) + .add(constraint2); - return Json.createObjectBuilder() - .add("action", action) - .add("constraint", Json.createArrayBuilder() - .add(Json.createObjectBuilder() - .add("and", constraints) - .build()) + var permission = Json.createObjectBuilder() + .add("action", "use") + .add("constraint", Json.createObjectBuilder() + .add(TYPE, ODRL_LOGICAL_CONSTRAINT_TYPE) + .add("and", constraintsBuilder.build()) .build()) .build(); + + return Json.createObjectBuilder() + .add(CONTEXT, ODRL_CONTEXT) + .add(TYPE, "Set") + .add("permission", Json.createArrayBuilder().add(permission)) + .build(); } private static JsonObject atomicConstraint(String leftOperand, String operator, Object rightOperand, boolean createRightOperandsAsArray) { @@ -231,6 +255,10 @@ public static JsonObject dataUsageEndDurationDays(Integer duration) { .build(); } + public static JsonObject bpnPolicy(String... bpns) { + return bpnPolicy(Operator.IS_ANY_OF, bpns); + } + public static JsonObject dataUsageEndDate(String endDate) { var constraint = Json.createObjectBuilder() .add("and", Json.createArrayBuilder() @@ -260,6 +288,43 @@ public static JsonObject dataUsageEndDate(String endDate) { .build(); } + public static JsonObjectBuilder policyDefinitionBuilder() { + return Json.createObjectBuilder() + .add(TYPE, EDC_NAMESPACE + "PolicyDefinitionDto"); + } + + public static JsonObjectBuilder policyDefinitionBuilder(JsonObject policy) { + return policyDefinitionBuilder() + .add(EDC_NAMESPACE + "policy", policy); + } + + public static JsonObject bpnPolicy(Operator operator, String... bpns) { + JsonArrayBuilder bpnArray = Json.createArrayBuilder(); + Stream.of(bpns).forEach(bpnArray::add); + + var bpnConstraint = Json.createObjectBuilder() + .add("leftOperand", "BusinessPartnerNumber") + .add("operator", operatorValueWithoutNamespace(operator)) + .add("rightOperand", bpnArray) + .build(); + + var permission = Json.createObjectBuilder() + .add("action", "access") + .add("constraint", Json.createArrayBuilder() + .add(bpnConstraint) + .build()) + .build(); + return Json.createObjectBuilder() + .add(CONTEXT, Json.createArrayBuilder() + .add(ODRL_CONTEXT) + .add(CX_POLICY_2025_09_CONTEXT)) + .add(TYPE, "Set") + .add(ID, "id") + .add("permission", Json.createArrayBuilder() + .add(permission)) + .build(); + } + public static JsonObject dataProvisioningEndDate(String endDate) { var requiredUsagePermissionConstraints = Json.createObjectBuilder() .add("and", Json.createArrayBuilder() @@ -292,20 +357,29 @@ public static JsonObject dataProvisioningEndDate(String endDate) { )).build(); } - public static JsonObject inForceDatePolicyLegacy(String operatorStart, Object startDate, String operatorEnd, Object endDate) { - var constraint = Json.createObjectBuilder() - .add("@type", "LogicalConstraint") - .add("and", Json.createArrayBuilder() - .add(atomicConstraint("https://w3id.org/edc/v0.0.1/ns/inForceDate", operatorStart, startDate, false)) - .add(atomicConstraint("https://w3id.org/edc/v0.0.1/ns/inForceDate", operatorEnd, endDate, false)) - .add(atomicConstraint("https://w3id.org/catenax/policy/Membership", "eq", "active", false)) + public static JsonObject frameworkConstraint(Map operandMappings, String action, Operator operator, boolean createRightOperandsAsArray) { + var constraints = operandMappings.entrySet().stream() + .map(constraint -> atomicConstraint(constraint.getKey(), operatorValueWithoutNamespace(operator), constraint.getValue(), createRightOperandsAsArray)) + .collect(Json::createArrayBuilder, JsonArrayBuilder::add, JsonArrayBuilder::add); + + if (action.contains("use")) { + if (!operandMappings.containsKey(FRAMEWORK_AGREEMENT_KEY)) { + constraints.add(frameworkAgreementConstraint()); + } + if (!operandMappings.containsKey(USAGE_PURPOSE_KEY)) { + constraints.add(usagePurposeConstraint()); + } + } + + return Json.createObjectBuilder() + .add("action", action) + .add("constraint", Json.createArrayBuilder() + .add(Json.createObjectBuilder() + .add(TYPE, ODRL_LOGICAL_CONSTRAINT_TYPE) + .add("and", constraints) + .build()) .build()) .build(); - - return policy(List.of(Json.createObjectBuilder() - .add("action", "use") - .add("constraint", constraint) - .build())); } private static String operatorValueWithoutNamespace(Operator operator) { diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java index 1c62a7fee3..bd61423843 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/participant/TractusxParticipantBase.java @@ -88,7 +88,31 @@ public abstract class TractusxParticipantBase extends IdentityParticipant { public void createAsset(String id) { createAsset(id, new HashMap<>(), Map.of("type", "test-type")); } - + + /** + * Overrides the upstream variant to set an id with a random UUID + */ + @Override + public String createPolicyDefinition(JsonObject policy) { + var body = createObjectBuilder() + .add(CONTEXT, createObjectBuilder().add(VOCAB, EDC_NAMESPACE)) + .add(TYPE, "PolicyDefinition") + .add(ID, UUID.randomUUID().toString()) + .add("policy", policy) + .build(); + + return baseManagementRequest() + .contentType(JSON) + .body(body) + .when() + .post("/policydefinitions") + .then() + .log().ifValidationFails() + .statusCode(200) + .contentType(JSON) + .extract().jsonPath().getString("@id"); + } + @NotNull public String getBpn() { return bpn; diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ConsumerPullBaseTest.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ConsumerPullBaseTest.java index 5fb3fdf0f7..67c72a975e 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ConsumerPullBaseTest.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ConsumerPullBaseTest.java @@ -22,7 +22,6 @@ import com.github.tomakehurst.wiremock.junit5.WireMockExtension; import jakarta.json.JsonObject; import org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates; -import org.eclipse.edc.policy.model.Operator; import org.eclipse.tractusx.edc.tests.ParticipantAwareTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -45,6 +44,7 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; /** @@ -79,7 +79,7 @@ void transferData_privateBackend() { provider().createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = provider().createPolicyDefinition(createAccessPolicy(consumer().getBpn())); - var contractPolicyId = provider().createPolicyDefinition(createContractPolicy(consumer().getBpn())); + var contractPolicyId = provider().createPolicyDefinition(createContractPolicy()); provider().createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = consumer().requestAssetFrom(assetId, provider()).withTransferType("HttpData-PULL") .withDestination(httpDataDestination()).execute(); @@ -125,7 +125,7 @@ void transferData_privateBackend_withConsumerDataPlane() { provider().createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = provider().createPolicyDefinition(createAccessPolicy(consumer().getBpn())); - var contractPolicyId = provider().createPolicyDefinition(createContractPolicy(consumer().getBpn())); + var contractPolicyId = provider().createPolicyDefinition(createContractPolicy()); provider().createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = consumer().requestAssetFrom(assetId, provider()).withTransferType("HttpData-PULL") .withDestination(httpDataDestination()).execute(); @@ -168,10 +168,10 @@ protected JsonObject httpDataDestination() { } protected JsonObject createAccessPolicy(String bpn) { - return bpnPolicy(Operator.IS_ANY_OF, bpn); + return bpnPolicy(bpn); } - protected JsonObject createContractPolicy(String bpn) { - return bpnPolicy(Operator.IS_ANY_OF, bpn); + protected JsonObject createContractPolicy() { + return frameworkPolicy(Map.of(), "use"); } } diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java index 2cb6430398..203f3020f1 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/transfer/ProviderPushBaseTest.java @@ -47,8 +47,10 @@ import static org.eclipse.edc.connector.controlplane.transfer.spi.types.TransferProcessStates.COMPLETED; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.FRAMEWORK_AGREEMENT_LITERAL; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.legacyFrameworkPolicy; import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; /** @@ -94,6 +96,34 @@ void httpPushDataTransfer() { server.verify(anyRequestedFor(urlPathEqualTo(MOCK_BACKEND_DESTINATION_PATH))); } + @Test + void httpPushDataTransfer_withLegacyUsagePolicy() { + var sourceUrl = createMockHttpDataUrl(MOCK_BACKEND_SOURCE_PATH); + var destinationUrl = createMockHttpDataUrl(MOCK_BACKEND_DESTINATION_PATH); + + var assetId = UUID.randomUUID().toString(); + Map dataAddress = Map.of( + "name", "transfer-test", + "baseUrl", sourceUrl, + "type", "HttpData", + "contentType", "application/json"); + provider().createAsset(assetId, Map.of(), dataAddress); + var accessPolicyId = provider().createPolicyDefinition(bpnPolicy(Operator.IS_ANY_OF, consumer().getBpn())); + var policyId = provider().createPolicyDefinition(frameworkPolicy("FrameworkAgreement", Operator.EQ, "DataExchangeGovernance:1.0", "use", false)); + provider().createContractDefinition(assetId, "def-1", accessPolicyId, policyId); + + var destination = httpDataAddress(destinationUrl); + var transferProcessId = consumer() + .requestAssetFrom(assetId, provider()) + .withDestination(destination) + .withTransferType("HttpData-PUSH") + .execute(); + + await().atMost(ASYNC_TIMEOUT).untilAsserted(() -> transferProcessIsInState(transferProcessId, COMPLETED)); + server.verify(anyRequestedFor(urlPathEqualTo(MOCK_BACKEND_SOURCE_PATH))); + server.verify(anyRequestedFor(urlPathEqualTo(MOCK_BACKEND_DESTINATION_PATH))); + } + @Test void httpPushNonFiniteDataTransfer() { var sourceUrl = createMockHttpDataUrl(MOCK_BACKEND_SOURCE_PATH); @@ -107,8 +137,9 @@ void httpPushNonFiniteDataTransfer() { "contentType", "application/json", "isNonFinite", "true"); provider().createAsset(assetId, Map.of(), dataAddress); - var policyId = provider().createPolicyDefinition(bpnPolicy(Operator.IS_ANY_OF, consumer().getBpn())); - provider().createContractDefinition(assetId, "def-1", policyId, policyId); + var accessPolicyId = provider().createPolicyDefinition(bpnPolicy(consumer().getBpn())); + var contractPolicyId = provider().createPolicyDefinition(frameworkPolicy(Map.of(), "use")); + provider().createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var destination = httpDataAddress(destinationUrl); var consumerTransferProcessId = consumer() @@ -140,7 +171,8 @@ void httpPushNonFiniteDataTransfer() { consumer().terminateTransfer(consumerTransferProcessId); consumer().awaitTransferToBeInState(consumerTransferProcessId, TransferProcessStates.TERMINATED); - await().untilAsserted(() -> dataFlowIsInState(providerTransferProcessId, DataFlowStates.TERMINATED)); + await().atMost(ASYNC_TIMEOUT) + .untilAsserted(() -> dataFlowIsInState(providerTransferProcessId, DataFlowStates.TERMINATED)); } private void waitAndAssert(Duration duration, Runnable... assertions) { diff --git a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java index 00d7e14c12..b4584dad50 100644 --- a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java +++ b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTest.java @@ -20,6 +20,8 @@ package org.eclipse.tractusx.edc.tests.catalog; +import org.eclipse.edc.connector.controlplane.contract.spi.offer.store.ContractDefinitionStore; +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.policy.spi.store.PolicyDefinitionStore; import org.eclipse.edc.jsonld.spi.JsonLd; @@ -32,6 +34,7 @@ import org.eclipse.edc.policy.model.Permission; import org.eclipse.edc.policy.model.Policy; import org.eclipse.edc.policy.model.PolicyType; +import org.eclipse.edc.spi.query.Criterion; import org.eclipse.tractusx.edc.tests.participant.TransferParticipant; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; import org.junit.jupiter.api.BeforeEach; @@ -212,11 +215,19 @@ void requestCatalog_filteredByBpn_UsingLegacyCxPolicy_shouldReject() { var id = "philosopher-policy"; PROVIDER_RUNTIME.getService(PolicyDefinitionStore.class) .create(buildLegacyPolicyDefinition(id, "greek_customer", Operator.EQ, "philosopher")); + var contractPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createAsset("test-asset1"); PROVIDER.createAsset("test-asset2"); - PROVIDER.createContractDefinition("test-asset2", "def1", id, id); + PROVIDER_RUNTIME.getService(ContractDefinitionStore.class) + .save(ContractDefinition.Builder.newInstance() + .id("def1") + .participantContextId(PROVIDER.getParticipantContextId()) + .accessPolicyId(id) + .contractPolicyId(contractPolicyId) + .assetsSelectorCriterion(new Criterion("https://w3id.org/edc/v0.0.1/ns/id", "=", "test-asset2")) + .build()); // act var catalog = CONSUMER.getCatalogDatasets(PROVIDER); diff --git a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java index 7ecc876885..c50c215710 100644 --- a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java +++ b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/CatalogTestDspV08.java @@ -41,6 +41,7 @@ import org.junit.jupiter.api.extension.RegisterExtension; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_2025_09_NS; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; @@ -188,14 +189,15 @@ void requestCatalog_filteredByBpn_shouldReject() { @DisplayName("Verify that the consumer receives only the offers he is permitted to (using the legacy CX policy)") void requestCatalog_filteredByBpn_UsingLegacyCxPolicy_shouldReject() { PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "greek_customer", "philosopher"); - var id = "philosopher-policy"; + var ap = "philosopher-policy"; PROVIDER_RUNTIME.getService(PolicyDefinitionStore.class) - .create(buildLegacyPolicyDefinition(id, "greek_customer", Operator.EQ, "philosopher")); + .create(buildLegacyPolicyDefinition(ap, "greek_customer", Operator.EQ, "philosopher")); + var cp = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createAsset("test-asset1"); PROVIDER.createAsset("test-asset2"); - PROVIDER.createContractDefinition("test-asset2", "def1", id, id); + PROVIDER.createContractDefinition("test-asset2", "def1", ap, cp); // act var catalog = CONSUMER.getCatalogDatasets(PROVIDER); @@ -208,7 +210,7 @@ void requestCatalog_filteredByBpn_UsingLegacyCxPolicy_shouldReject() { private PolicyDefinition buildLegacyPolicyDefinition(String id, String leftExpression, Operator operator, Object rightExpression) { var action = Action.Builder.newInstance() - .type("access") + .type(CX_POLICY_2025_09_NS + "access") .build(); var constraint = AtomicConstraint.Builder.newInstance() diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java index e4f303a0fe..034ee3aac6 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/AbstractDcpConsumerPullTest.java @@ -342,8 +342,8 @@ void catalogRequest_whenRequestedCredentialMissing() { } @Override - protected JsonObject createContractPolicy(String bpn) { - return frameworkPolicy("Membership", Operator.EQ, "active", "access", false); + protected JsonObject createContractPolicy() { + return frameworkPolicy("Membership", Operator.EQ, "active", "use", false); } protected abstract RuntimeExtension credentialStoreRuntime(); @@ -354,7 +354,7 @@ private static class ValidContractPolicyProvider implements ArgumentsProvider { @Override public Stream provideArguments(ExtensionContext extensionContext) { return Stream.of( - Arguments.of(frameworkPolicy("Membership", Operator.EQ, "active", "access", false), "MembershipCredential"), + Arguments.of(frameworkPolicy("Membership", Operator.EQ, "active", "use", false), "MembershipCredential"), Arguments.of(frameworkPolicy("FrameworkAgreement", Operator.EQ, "DataExchangeGovernance:1.0", "use", false), "DataExchangeGovernance use case") ); } diff --git a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java index 305a4aac93..b618a9574a 100644 --- a/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java +++ b/edc-tests/e2e/dcp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java @@ -32,7 +32,6 @@ import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; import org.eclipse.edc.junit.utils.LazySupplier; -import org.eclipse.edc.policy.model.Operator; import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.edc.spi.result.Result; @@ -62,6 +61,7 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.emptyPolicy; import static org.eclipse.tractusx.edc.tests.transfer.dcp.runtime.Runtimes.dcpRuntime; import static org.eclipse.tractusx.edc.tests.transfer.dcp.runtime.Runtimes.stsRuntime; @@ -147,9 +147,8 @@ void shouldNotImpersonateConsumer_withWrappedConsumerCredential() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); - var policy = createAccessPolicy(CONSUMER.getBpn()); - var accessPolicyId = PROVIDER.createPolicyDefinition(policy); - var contractPolicyId = PROVIDER.createPolicyDefinition(policy); + var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); + var contractPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); MALICIOUS_ACTOR.getCatalog(PROVIDER) @@ -173,9 +172,8 @@ void shouldNotImpersonateConsumer_withConsumerPresentation() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); - var policy = createAccessPolicy(CONSUMER.getBpn()); - var accessPolicyId = PROVIDER.createPolicyDefinition(policy); - var contractPolicyId = PROVIDER.createPolicyDefinition(policy); + var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); + var contractPolicyId = PROVIDER.createPolicyDefinition(emptyPolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); MALICIOUS_ACTOR.getCatalog(PROVIDER) @@ -222,7 +220,7 @@ void withMock(Function dataAddress) { PROVIDER.createAsset(assetId, Map.of(), dataAddress); - var policyId = PROVIDER.createPolicyDefinition(bpnPolicy(Operator.IS_ANY_OF, CONSUMER.getBpn())); - PROVIDER.createContractDefinition(assetId, contractDefinitionId, policyId, policyId); + var accessPolicyId = PROVIDER.createPolicyDefinition(bpnPolicy(CONSUMER.getBpn())); + var contractPolicyId = PROVIDER.createPolicyDefinition(frameworkPolicy(Map.of(), "use")); + PROVIDER.createContractDefinition(assetId, contractDefinitionId, accessPolicyId, contractPolicyId); return CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("KafkaBroker-PULL") diff --git a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/ContractDefinitionPoliciesValidatorsTest.java b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/ContractDefinitionPoliciesValidatorsTest.java new file mode 100644 index 0000000000..88a27e9e55 --- /dev/null +++ b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/ContractDefinitionPoliciesValidatorsTest.java @@ -0,0 +1,149 @@ +/******************************************************************************** + * Copyright (c) 2026 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +package org.eclipse.tractusx.edc.tests.validators; + +import jakarta.json.JsonObject; +import org.eclipse.edc.junit.annotations.EndToEndTest; +import org.eclipse.edc.junit.extensions.RuntimeExtension; +import org.eclipse.tractusx.edc.tests.participant.TransferParticipant; +import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.Map; + +import static io.restassured.http.ContentType.JSON; +import static jakarta.json.Json.createArrayBuilder; +import static jakarta.json.Json.createObjectBuilder; +import static org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition.CONTRACT_DEFINITION_ACCESSPOLICY_ID; +import static org.eclipse.edc.connector.controlplane.contract.spi.types.offer.ContractDefinition.CONTRACT_DEFINITION_CONTRACTPOLICY_ID; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; +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.JsonLdKeywords.VOCAB; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; +import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; +import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; +import static org.hamcrest.Matchers.equalTo; + +@EndToEndTest +public class ContractDefinitionPoliciesValidatorsTest { + + private static final TransferParticipant PROVIDER = TransferParticipant.Builder.newInstance() + .name(PROVIDER_NAME) + .id(PROVIDER_DID) + .bpn(PROVIDER_BPN) + .build(); + + @RegisterExtension + @Order(0) + private static final PostgresExtension POSTGRES = new PostgresExtension(PROVIDER.getName()); + + @RegisterExtension + private static final RuntimeExtension PROVIDER_RUNTIME = pgRuntime(PROVIDER, POSTGRES); + + @Test + void shouldFail_whenAccessPolicyDefinedAsContractPolicy() { + var contractPolicyId = PROVIDER.createPolicyDefinition(frameworkPolicy(Map.of(), "use")); + var contractDefinition = contractDefinition("contract-definition", contractPolicyId, contractPolicyId); + PROVIDER.baseManagementRequest() + .basePath("/v3") + .contentType(JSON) + .body(contractDefinition) + .when() + .post("/contractdefinitions") + .then().assertThat() + .log().ifValidationFails() + .statusCode(400) + .body("[0].message", equalTo( + "Policy '%s' does not have the expected permission action 'https://w3id.org/catenax/2025/9/policy/access'" + .formatted(contractPolicyId))); + } + + @Test + void shouldFail_whenContractPolicyDefinedAsAccessPolicy() { + var accessPolicyId = PROVIDER.createPolicyDefinition(bpnPolicy(PROVIDER_BPN)); + + var contractDefinition = contractDefinition("contract-definition", accessPolicyId, accessPolicyId); + PROVIDER.baseManagementRequest() + .basePath("/v3") + .contentType(JSON) + .body(contractDefinition) + .when() + .post("/contractdefinitions") + .then().assertThat() + .statusCode(400) + .body("[0].message", + equalTo("Policy '%s' does not have the expected permission action 'http://www.w3.org/ns/odrl/2/use'" + .formatted(accessPolicyId))); + } + + @Test + void shouldPass_whenContractDefinitionHasCorrectPolicies() { + var accessPolicyId = PROVIDER.createPolicyDefinition(bpnPolicy(PROVIDER_BPN)); + var contractPolicyId = PROVIDER.createPolicyDefinition(frameworkPolicy(Map.of(), "use")); + + PROVIDER.createContractDefinition("assetId", "contract-definition", accessPolicyId, contractPolicyId); + } + + @Test + void shouldFail_whenUpdatingPolicyThatIsReferencedByContractDefinition() { + var accessPolicyId = PROVIDER.createPolicyDefinition(bpnPolicy(PROVIDER_BPN)); + var contractPolicyId = PROVIDER.createPolicyDefinition(frameworkPolicy(Map.of(), "use")); + PROVIDER.createContractDefinition("assetId", "contract-definition", accessPolicyId, contractPolicyId); + + var policyDefinition = createObjectBuilder() + .add(CONTEXT, createObjectBuilder().add(VOCAB, EDC_NAMESPACE)) + .add(TYPE, "PolicyDefinition") + .add(ID, contractPolicyId) + .add("policy", bpnPolicy(PROVIDER_BPN)) + .build(); + + PROVIDER.baseManagementRequest() + .basePath("/v3") + .contentType(JSON) + .body(policyDefinition) + .when() + .put("/policydefinitions/" + contractPolicyId) + .then().assertThat() + .statusCode(400) + .body("[0].message", equalTo("Policy Definition is referenced by a Contract Definition")); + } + + private JsonObject contractDefinition(String id, String accessPolicyId, String contractPolicyId) { + return createObjectBuilder() + .add(CONTEXT, createObjectBuilder()) + .add(ID, id) + .add(TYPE, EDC_NAMESPACE + "ContractDefinition") + .add(CONTRACT_DEFINITION_ACCESSPOLICY_ID, accessPolicyId) + .add(CONTRACT_DEFINITION_CONTRACTPOLICY_ID, contractPolicyId) + .add("assetsSelector", createArrayBuilder().add(createObjectBuilder() + .add("@type", "CriterionDto") + .add("operandLeft", "https://w3id.org/edc/v0.0.1/ns/id") + .add("operator", "=") + .add("operandRight", "asset"))) + .build(); + } +} diff --git a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java index a8dd179416..7f9c9dc883 100644 --- a/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java +++ b/edc-tests/e2e/management-tests/src/test/java/org/eclipse/tractusx/edc/tests/validators/EmptyAssetSelectorValidatorTest.java @@ -48,6 +48,8 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; import static org.hamcrest.Matchers.contains; @@ -74,27 +76,32 @@ public class EmptyAssetSelectorValidatorTest { @Test @DisplayName("Provider gets 400 when no asset selector is used") void shouldFail_whenContractDefinitionHasNoAssetSelector() { + var accessPolicyId = PROVIDER.createPolicyDefinition(bpnPolicy(PROVIDER_BPN)); + var contractPolicyId = PROVIDER.createPolicyDefinition(frameworkPolicy(Map.of(), "use")); - var requestResponse = createContractDefinitionRequest("definitionId", "accessPolicyId", "contractPolicy", null); - - requestResponse.statusCode(400) - .body("message", contains("mandatory array '%s' is missing".formatted(CONTRACT_DEFINITION_ASSETS_SELECTOR))); - + createContractDefinitionRequest("definitionId", accessPolicyId, contractPolicyId, null) + .statusCode(400) + .body("message", contains("mandatory array '%s' is missing" + .formatted(CONTRACT_DEFINITION_ASSETS_SELECTOR))); } @Test @DisplayName("Provider gets 400 when empty asset selector is used") void shouldFail_whenContractDefinitionHasEmptyAssetSelector() { + var accessPolicyId = PROVIDER.createPolicyDefinition(bpnPolicy(PROVIDER_BPN)); + var contractPolicyId = PROVIDER.createPolicyDefinition(frameworkPolicy(Map.of(), "use")); - var requestResponse = createContractDefinitionRequest("definitionId", "accessPolicyId", "contractPolicy", createArrayBuilder().build()); - - requestResponse.statusCode(400) - .body("message", contains("array '%s' should at least contains '1' elements".formatted(CONTRACT_DEFINITION_ASSETS_SELECTOR))); + createContractDefinitionRequest("definitionId", accessPolicyId, contractPolicyId, createArrayBuilder().build()) + .statusCode(400) + .body("message", contains("array '%s' should at least contains '1' elements" + .formatted(CONTRACT_DEFINITION_ASSETS_SELECTOR))); } @Test @DisplayName("Provider gets 200 when asset selector has a valid criterion") void shouldPass_whenContractDefinitionHasCorrectAssetSelector() { + var accessPolicyId = PROVIDER.createPolicyDefinition(bpnPolicy(PROVIDER_BPN)); + var contractPolicyId = PROVIDER.createPolicyDefinition(frameworkPolicy(Map.of(), "use")); var assetSelector = Json.createArrayBuilder() .add(createObjectBuilder() .add(TYPE, "Criterion") @@ -104,9 +111,8 @@ void shouldPass_whenContractDefinitionHasCorrectAssetSelector() { .build()) .build(); - var requestResponse = createContractDefinitionRequest("definitionId", "accessPolicyId", "contractPolicy", assetSelector); - - requestResponse.statusCode(200); + createContractDefinitionRequest("definitionId", accessPolicyId, contractPolicyId, assetSelector) + .statusCode(200); } private ValidatableResponse createContractDefinitionRequest(String definitionId, String accessPolicyId, String contractPolicyId, JsonArray criterionArray) { diff --git a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java index 3622a70c08..d120cf1c2f 100644 --- a/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java +++ b/edc-tests/e2e/policy-tests/src/test/java/org/eclipse/tractusx/edc/tests/policy/PolicyDefinitionEndToEndTest.java @@ -46,13 +46,16 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.stream.Stream; import static com.apicatalog.jsonld.lang.Keywords.ID; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; +import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VOCAB; import static org.eclipse.edc.spi.constants.CoreConstants.EDC_CONNECTOR_MANAGEMENT_CONTEXT_V2; +import static org.eclipse.edc.spi.constants.CoreConstants.EDC_NAMESPACE; import static org.eclipse.tractusx.edc.cx.CxJsonLdExtension.CX_POLICY_2025_09_CONTEXT; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_BPN; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_DID; @@ -244,7 +247,7 @@ private Response createPolicyDefinition(ManagementApiVersion apiVersion, JsonObj JsonValue context; switch (apiVersion) { case V3 -> context = Json.createObjectBuilder() - .add("@vocab", "https://w3id.org/edc/v0.0.1/ns/") + .add(VOCAB, EDC_NAMESPACE) .build(); case V4 -> context = Json.createValue(EDC_CONNECTOR_MANAGEMENT_CONTEXT_V2); default -> context = null; @@ -253,6 +256,7 @@ private Response createPolicyDefinition(ManagementApiVersion apiVersion, JsonObj var requestBody = Json.createObjectBuilder() .add(CONTEXT, context) .add(TYPE, "PolicyDefinition") + .add(ID, UUID.randomUUID().toString()) .add("policy", policy) .build(); return (Response) PROVIDER.baseManagementRequest() diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java index fec936b1d0..0aa42e22cb 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/RetireAgreementTest.java @@ -26,7 +26,6 @@ import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; -import org.eclipse.edc.policy.model.Operator; import org.eclipse.tractusx.edc.tests.participant.TransferParticipant; import org.eclipse.tractusx.edc.tests.runtimes.PostgresExtension; import org.junit.jupiter.api.BeforeEach; @@ -109,7 +108,7 @@ void retireAgreement_shouldCloseTransferProcesses() { PROVIDER.storeBusinessPartner(CONSUMER.getBpn(), "test-group1"); var accessPolicy = PROVIDER.createPolicyDefinition(bpnGroupPolicy("isAnyOf", true, "test-group1")); - var policy = frameworkPolicy("Membership", Operator.EQ, "active", "use", false); + var policy = frameworkPolicy(Map.of(), "use"); var contractPolicy = PROVIDER.createPolicyDefinition(policy); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicy, contractPolicy); diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java index 787855cfe5..18a2be33de 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java @@ -97,7 +97,7 @@ void transferData_withSuspendResume() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(createContractPolicy(CONSUMER.getBpn())); + var contractPolicyId = PROVIDER.createPolicyDefinition(createContractPolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("HttpData-PULL") diff --git a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java index b98c7d63e3..2257c1102e 100644 --- a/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java +++ b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferWithTokenRefreshTest.java @@ -25,7 +25,6 @@ import org.eclipse.edc.jsonld.spi.JsonLd; import org.eclipse.edc.junit.annotations.EndToEndTest; import org.eclipse.edc.junit.extensions.RuntimeExtension; -import org.eclipse.edc.policy.model.Operator; import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.eclipse.tractusx.edc.spi.identity.mapper.BdrsClient; import org.eclipse.tractusx.edc.tests.MockBdrsClient; @@ -61,6 +60,7 @@ import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_DID; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.PROVIDER_NAME; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.bpnPolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkPolicy; import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; @@ -130,7 +130,7 @@ void transferData_withExpiredEdr_shouldReturn4xx() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(createContractPolicy(CONSUMER.getBpn())); + var contractPolicyId = PROVIDER.createPolicyDefinition(createContractPolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER).withTransferType("HttpData-PULL") .withDestination(httpDataDestination()).execute(); @@ -190,7 +190,7 @@ void transferData_withAutomaticRefresh() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(createContractPolicy(CONSUMER.getBpn())); + var contractPolicyId = PROVIDER.createPolicyDefinition(createContractPolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER).withTransferType("HttpData-PULL") .withDestination(httpDataDestination()).execute(); @@ -248,10 +248,10 @@ private JsonObject httpDataDestination() { } protected JsonObject createAccessPolicy(String bpn) { - return bpnPolicy(Operator.IS_ANY_OF, bpn); + return bpnPolicy(bpn); } - protected JsonObject createContractPolicy(String bpn) { - return bpnPolicy(Operator.IS_ANY_OF, bpn); + protected JsonObject createContractPolicy() { + return frameworkPolicy(Map.of(), "use"); } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 62d0178c7c..351151c62e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -91,6 +91,7 @@ include(":edc-extensions:dsp:dsp-transfer-process-08") include(":edc-extensions:dsp:dsp-transfer-process-08:dsp-transfer-process-http-api-08") include(":edc-extensions:dsp:dsp-transfer-process-08:dsp-transfer-process-transform-08") include(":edc-extensions:data-flow-properties-provider") +include(":edc-extensions:validators:contract-definition-policies") include(":edc-extensions:validators:empty-asset-selector") include(":edc-extensions:log4j2-monitor") include(":edc-extensions:connector-discovery:connector-discovery-api") From 8f1ce79ca678cd20301c39ffe9963b3603312835 Mon Sep 17 00:00:00 2001 From: eclipse-tractusx-bot Date: Mon, 24 Aug 2026 07:22:25 +0000 Subject: [PATCH 250/259] Prepare release 0.13.0-rc4 --- charts/tractusx-connector-memory/Chart.yaml | 4 ++-- charts/tractusx-connector-memory/README.md | 4 ++-- charts/tractusx-connector/Chart.yaml | 4 ++-- charts/tractusx-connector/README.md | 4 ++-- gradle.properties | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/charts/tractusx-connector-memory/Chart.yaml b/charts/tractusx-connector-memory/Chart.yaml index 5c2ee996f0..4ffc44acce 100644 --- a/charts/tractusx-connector-memory/Chart.yaml +++ b/charts/tractusx-connector-memory/Chart.yaml @@ -35,12 +35,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.13.0-SNAPSHOT +version: 0.13.0-rc4 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.13.0-SNAPSHOT" +appVersion: "0.13.0-rc4" home: https://github.com/eclipse-tractusx/tractusx-edc/tree/main/charts/tractusx-connector-memory sources: - https://github.com/eclipse-tractusx/tractusx-edc/tree/main/charts/tractusx-connector-memory diff --git a/charts/tractusx-connector-memory/README.md b/charts/tractusx-connector-memory/README.md index 33c40a36d4..8ad0728c11 100644 --- a/charts/tractusx-connector-memory/README.md +++ b/charts/tractusx-connector-memory/README.md @@ -1,6 +1,6 @@ # tractusx-connector-memory -![Version: 0.13.0-SNAPSHOT](https://img.shields.io/badge/Version-0.13.0--SNAPSHOT-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.13.0-SNAPSHOT](https://img.shields.io/badge/AppVersion-0.13.0--SNAPSHOT-informational?style=flat-square) +![Version: 0.13.0-rc4](https://img.shields.io/badge/Version-0.13.0--rc4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.13.0-rc4](https://img.shields.io/badge/AppVersion-0.13.0--rc4-informational?style=flat-square) A Helm chart for Tractus-X Eclipse Data Space Connector based on memory. Please only use this for development or testing purposes, never in production workloads! @@ -41,7 +41,7 @@ Combined, run this shell command to start the in-memory Tractus-X EDC runtime: ```shell helm repo add tractusx-edc https://eclipse-tractusx.github.io/charts/dev -helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0-SNAPSHOT \ +helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0-rc4 \ -f /tractusx-connector-memory-test.yaml \ --set vault.secrets="client-secret:$YOUR_CLIENT_SECRET" ``` diff --git a/charts/tractusx-connector/Chart.yaml b/charts/tractusx-connector/Chart.yaml index e5a42226c9..35312c6a16 100644 --- a/charts/tractusx-connector/Chart.yaml +++ b/charts/tractusx-connector/Chart.yaml @@ -41,12 +41,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.13.0-SNAPSHOT +version: 0.13.0-rc4 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.13.0-SNAPSHOT" +appVersion: "0.13.0-rc4" home: https://github.com/eclipse-tractusx/tractusx-edc/tree/main/charts/tractusx-connector sources: - https://github.com/eclipse-tractusx/tractusx-edc/tree/main/charts/tractusx-connector diff --git a/charts/tractusx-connector/README.md b/charts/tractusx-connector/README.md index 7965a38775..ba55d65c8a 100644 --- a/charts/tractusx-connector/README.md +++ b/charts/tractusx-connector/README.md @@ -1,6 +1,6 @@ # tractusx-connector -![Version: 0.13.0-SNAPSHOT](https://img.shields.io/badge/Version-0.13.0--SNAPSHOT-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.13.0-SNAPSHOT](https://img.shields.io/badge/AppVersion-0.13.0--SNAPSHOT-informational?style=flat-square) +![Version: 0.13.0-rc4](https://img.shields.io/badge/Version-0.13.0--rc4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.13.0-rc4](https://img.shields.io/badge/AppVersion-0.13.0--rc4-informational?style=flat-square) A Helm chart for Tractus-X Eclipse Data Space Connector. The connector deployment consists of two runtime consists of a Control Plane and a Data Plane. Note that _no_ external dependencies such as a PostgreSQL database and HashiCorp Vault are included. @@ -102,7 +102,7 @@ Combined, run this shell command to start the in-memory Tractus-X EDC runtime: ```shell helm repo add tractusx-edc https://eclipse-tractusx.github.io/charts/dev -helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHOT \ +helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-rc4 \ -f /tractusx-connector-test.yaml ``` diff --git a/gradle.properties b/gradle.properties index 89f9507794..32814c9fcd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group=org.eclipse.tractusx.edc -version=0.13.0-SNAPSHOT +version=0.13.0-rc4 # configure the build: txScmConnection=scm:git:git@github.com:eclipse-tractusx/tractusx-edc.git txWebsiteUrl=https://github.com/eclipse-tractusx/tractusx-edc.git From 871fc97600d8f35c63dbf2c14b0d5565cb208f3d Mon Sep 17 00:00:00 2001 From: eclipse-tractusx-bot Date: Mon, 24 Aug 2026 07:24:28 +0000 Subject: [PATCH 251/259] Update DEPENDENCIES file --- DEPENDENCIES | 466 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 466 insertions(+) diff --git a/DEPENDENCIES b/DEPENDENCIES index e69de29bb2..5d4ebb514f 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -0,0 +1,466 @@ +maven/mavencentral/com.apicatalog/carbon-did/0.3.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.apicatalog/copper-multibase/0.5.0, Apache-2.0, approved, #14501 +maven/mavencentral/com.apicatalog/copper-multicodec/0.1.1, Apache-2.0, approved, #14500 +maven/mavencentral/com.apicatalog/iron-ed25519-cryptosuite-2020/0.14.0, Apache-2.0, approved, #14503 +maven/mavencentral/com.apicatalog/iron-verifiable-credentials/0.14.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.apicatalog/titanium-jcs/1.1.1, Apache-2.0, approved, #25093 +maven/mavencentral/com.apicatalog/titanium-json-ld/1.0.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.apicatalog/titanium-json-ld/1.4.0, Apache-2.0, approved, #15200 +maven/mavencentral/com.apicatalog/titanium-json-ld/1.7.0, Apache-2.0, approved, #25089 +maven/mavencentral/com.apicatalog/titanium-rdf-api/1.0.0, Apache-2.0, approved, #20245 +maven/mavencentral/com.apicatalog/titanium-rdf-n-quads/1.0.2, Apache-2.0, approved, #20243 +maven/mavencentral/com.azure/azure-core-http-netty/1.15.11, MIT AND Apache-2.0, approved, #16697 +maven/mavencentral/com.azure/azure-core-http-netty/1.16.3, MIT AND Apache-2.0, approved, #29562 +maven/mavencentral/com.azure/azure-core/1.55.3, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-core/1.57.1, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-identity/1.18.2, MIT, approved, #29561 +maven/mavencentral/com.azure/azure-json/1.4.0, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-json/1.5.1, MIT AND Apache-2.0, approved, #26444 +maven/mavencentral/com.azure/azure-storage-blob/12.30.0, MIT, approved, #20441 +maven/mavencentral/com.azure/azure-storage-common/12.29.0, MIT, approved, #20440 +maven/mavencentral/com.azure/azure-storage-internal-avro/12.15.0, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-xml/1.2.0, Apache-2.0, approved, #26447 +maven/mavencentral/com.azure/azure-xml/1.2.1, Apache-2.0, approved, #26447 +maven/mavencentral/com.ethlo.time/itu/1.14.0, Apache-2.0, approved, #19505 +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.18.4, Apache-2.0, approved, #16364 +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.19.1, Apache-2.0, approved, #21911 +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.19.2, Apache-2.0, approved, #21911 +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.21, Apache-2.0, approved, #25587 +maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.18.4.1, Apache-2.0 AND MIT, approved, #16371 +maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.21.2, Apache-2.0 AND MIT, approved, #25590 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.18.3, Apache-2.0, approved, #16372 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.18.4, Apache-2.0, approved, #16372 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.19.1, Apache-2.0, approved, #21909 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.19.2, Apache-2.0, approved, #21909 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.21.2, Apache-2.0, approved, #25591 +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.18.3, Apache-2.0, approved, #16370 +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.19.2, Apache-2.0, approved, #21912 +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.21.2, Apache-2.0, approved, #25589 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jakarta-jsonp/2.21.2, Apache-2.0, approved, #26448 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.18.4, Apache-2.0, approved, #16625 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.19.2, Apache-2.0, approved, #23299 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.21.2, Apache-2.0, approved, #26441 +maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-base/2.21.2, Apache-2.0, approved, #26442 +maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.19.2, Apache-2.0, approved, #20839 +maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.21.2, Apache-2.0, approved, #26443 +maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.19.1, Apache-2.0, approved, #21910 +maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.21.2, Apache-2.0, approved, #25588 +maven/mavencentral/com.fasterxml.jackson/jackson-bom/2.21.2, Apache-2.0, approved, #26451 +maven/mavencentral/com.google.code.findbugs/jsr305/3.0.2, Apache-2.0 and CC-BY-2.5, approved, #15220 +maven/mavencentral/com.google.code.gson/gson/2.13.2, Apache-2.0, approved, #20656 +maven/mavencentral/com.google.crypto.tink/tink/1.20.0, Apache-2.0, approved, #28384 +maven/mavencentral/com.google.errorprone/error_prone_annotations/2.41.0, Apache-2.0, approved, #22631 +maven/mavencentral/com.google.protobuf/protobuf-java/4.33.0, BSD-3-Clause, approved, #29831 +maven/mavencentral/com.microsoft.azure/msal4j-persistence-extension/1.3.0, MIT, approved, #14411 +maven/mavencentral/com.microsoft.azure/msal4j/1.15.0, MIT, approved, clearlydefined +maven/mavencentral/com.microsoft.azure/msal4j/1.23.1, MIT, approved, clearlydefined +maven/mavencentral/com.networknt/json-schema-validator/2.0.0, Apache-2.0 AND Unicode-TOU, approved, #25988 +maven/mavencentral/com.nimbusds/nimbus-jose-jwt/10.8, Apache-2.0, approved, #26455 +maven/mavencentral/com.nimbusds/nimbus-jose-jwt/10.9.1, Apache-2.0, approved, #29000 +maven/mavencentral/com.squareup.okhttp3/okhttp-dnsoverhttps/5.3.2, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okhttp3/okhttp-jvm/5.3.2, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okhttp3/okhttp-jvm/5.4.0, Apache-2.0, approved, #29005 +maven/mavencentral/com.squareup.okhttp3/okhttp/4.9.3, Apache-2.0 AND MPL-2.0, approved, #3225 +maven/mavencentral/com.squareup.okhttp3/okhttp/5.3.2, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okhttp3/okhttp/5.4.0, Apache-2.0, approved, #29015 +maven/mavencentral/com.squareup.okio/okio-jvm/3.16.4, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okio/okio-jvm/3.17.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okio/okio/3.16.4, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okio/okio/3.17.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/commons-codec/commons-codec/1.11, Apache-2.0 AND BSD-3-Clause, approved, CQ15971 +maven/mavencentral/commons-codec/commons-codec/1.17.1, Apache-2.0 AND (Apache-2.0 AND BSD-3-Clause), approved, #14583 +maven/mavencentral/commons-logging/commons-logging/1.2, Apache-2.0, approved, CQ10162 +maven/mavencentral/dev.failsafe/failsafe-okhttp/3.3.2, Apache-2.0, approved, #15208 +maven/mavencentral/dev.failsafe/failsafe/3.3.2, Apache-2.0, approved, #9268 +maven/mavencentral/io.github.classgraph/classgraph/4.8.184, MIT, approved, CQ22530 +maven/mavencentral/io.micrometer/micrometer-commons/1.16.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #24726 +maven/mavencentral/io.micrometer/micrometer-core/1.16.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #24722 +maven/mavencentral/io.micrometer/micrometer-observation/1.16.4, Apache-2.0, approved, #24713 +maven/mavencentral/io.netty/netty-buffer/4.1.128.Final, Apache-2.0, approved, CQ21842 +maven/mavencentral/io.netty/netty-buffer/4.1.130.Final, Apache-2.0, approved, CQ21842 +maven/mavencentral/io.netty/netty-buffer/4.1.132.Final, Apache-2.0, approved, CQ21842 +maven/mavencentral/io.netty/netty-codec-dns/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-socks/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-common/4.1.128.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-common/4.1.130.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-common/4.1.132.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-handler-proxy/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler-proxy/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver-dns-classes-macos/4.1.128.Final, Apache-2.0, approved, #6367 +maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.128.Final, Apache-2.0, approved, #7004 +maven/mavencentral/io.netty/netty-resolver-dns/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.74.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 +maven/mavencentral/io.netty/netty-tcnative-classes/2.0.74.Final, Apache-2.0, approved, #23398 +maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.130.Final, Apache-2.0, approved, #6366 +maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.132.Final, Apache-2.0, approved, #6366 +maven/mavencentral/io.netty/netty-transport-classes-kqueue/4.1.130.Final, Apache-2.0, approved, #4107 +maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-annotations/1.32.0, Apache-2.0, approved, #11684 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-annotations/2.30.0, Apache-2.0, approved, #30125 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-api-incubator/2.30.0-alpha, , restricted, clearlydefined +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-api/2.30.0, , restricted, clearlydefined +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-log4j-appender-2.17/2.30.0-alpha, , restricted, clearlydefined +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/2.30.0-alpha, , restricted, clearlydefined +maven/mavencentral/io.opentelemetry.semconv/opentelemetry-semconv/1.43.0, , restricted, clearlydefined +maven/mavencentral/io.opentelemetry/opentelemetry-api-incubator/1.64.0-alpha, , restricted, clearlydefined +maven/mavencentral/io.opentelemetry/opentelemetry-api/1.32.0, Apache-2.0, approved, #11682 +maven/mavencentral/io.opentelemetry/opentelemetry-api/1.61.0, Apache-2.0, approved, #29641 +maven/mavencentral/io.opentelemetry/opentelemetry-api/1.64.0, Apache-2.0, approved, #29872 +maven/mavencentral/io.opentelemetry/opentelemetry-common/1.64.0, Apache-2.0, approved, #29870 +maven/mavencentral/io.opentelemetry/opentelemetry-context/1.64.0, Apache-2.0, approved, #29871 +maven/mavencentral/io.projectreactor.netty/reactor-netty-core/1.2.13, Apache-2.0, approved, #23393 +maven/mavencentral/io.projectreactor.netty/reactor-netty-http/1.2.13, Apache-2.0, approved, #23394 +maven/mavencentral/io.projectreactor/reactor-core/3.7.14, Apache-2.0, approved, #17529 +maven/mavencentral/io.setl/rdf-urdna/1.1, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.42, Apache-2.0, approved, #5947 +maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.42, Apache-2.0, approved, #5929 +maven/mavencentral/io.swagger.core.v3/swagger-integration-jakarta/2.2.42, Apache-2.0, approved, #11475 +maven/mavencentral/io.swagger.core.v3/swagger-jaxrs2-jakarta/2.2.42, Apache-2.0, approved, #11477 +maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.42, Apache-2.0, approved, #5919 +maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.3, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf +maven/mavencentral/jakarta.annotation/jakarta.annotation-api/3.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca +maven/mavencentral/jakarta.inject/jakarta.inject-api/2.0.1, Apache-2.0, approved, ee4j.cdi +maven/mavencentral/jakarta.json/jakarta.json-api/2.1.3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp +maven/mavencentral/jakarta.servlet/jakarta.servlet-api/6.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.servlet +maven/mavencentral/jakarta.servlet/jakarta.servlet-api/6.1.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.servlet +maven/mavencentral/jakarta.validation/jakarta.validation-api/3.0.2, Apache-2.0, approved, ee4j.validation +maven/mavencentral/jakarta.validation/jakarta.validation-api/3.1.0, Apache-2.0, approved, ee4j.validation +maven/mavencentral/jakarta.ws.rs/jakarta.ws.rs-api/4.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.rest +maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/3.0.1, BSD-3-Clause, approved, ee4j.jaxb +maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/4.0.2, BSD-3-Clause, approved, ee4j.jaxb +maven/mavencentral/net.java.dev.jna/jna-platform/5.13.0, Apache-2.0 OR LGPL-2.1-or-later, approved, #6707 +maven/mavencentral/net.java.dev.jna/jna-platform/5.17.0, Apache-2.0 OR LGPL-2.1-or-later, approved, #20116 +maven/mavencentral/net.java.dev.jna/jna/5.13.0, Apache-2.0 AND LGPL-2.1-or-later, approved, #15196 +maven/mavencentral/net.java.dev.jna/jna/5.17.0, Apache-2.0 AND LGPL-2.1-or-later, approved, #20112 +maven/mavencentral/org.apache.commons/commons-lang3/3.18.0, Apache-2.0, approved, #22470 +maven/mavencentral/org.apache.commons/commons-pool2/2.13.1, Apache-2.0 AND CC-PDDC, approved, #25941 +maven/mavencentral/org.apache.httpcomponents/httpclient/4.5.13, Apache-2.0, approved, #15248 +maven/mavencentral/org.apache.httpcomponents/httpcore/4.4.13, Apache-2.0, approved, CQ23528 +maven/mavencentral/org.apache.httpcomponents/httpcore/4.4.16, Apache-2.0, approved, CQ23528 +maven/mavencentral/org.apache.logging.log4j/log4j-api/2.26.1, Apache-2.0, approved, #27998 +maven/mavencentral/org.apache.logging.log4j/log4j-core/2.26.1, Apache-2.0 AND (Apache-2.0 AND LGPL-2.0-or-later), approved, #28001 +maven/mavencentral/org.apache.logging.log4j/log4j-layout-template-json/2.26.1, Apache-2.0, approved, clearlydefined +maven/mavencentral/org.bouncycastle/bcpkix-jdk18on/1.84, MIT, approved, #27142 +maven/mavencentral/org.bouncycastle/bcprov-jdk18on/1.84, MIT AND CC0-1.0, approved, #27143 +maven/mavencentral/org.bouncycastle/bcutil-jdk18on/1.84, MIT, approved, #27144 +maven/mavencentral/org.checkerframework/checker-qual/3.55.1, MIT, approved, #29939 +maven/mavencentral/org.eclipse.edc.aws/aws-s3-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.aws/aws-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.aws/data-plane-aws-s3/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.aws/data-plane-provision-aws-s3/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.aws/validator-data-address-s3/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.azure/azure-blob-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.azure/data-plane-azure-storage/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.azure/data-plane-provision-blob/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/accesstokendata-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/api-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/api-observability/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/asset-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/asset-index-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/asset-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-delegated/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-tokenbased/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/boot-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/boot-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/boot/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/callback-event-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/callback-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/callback-static-endpoint/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/catalog-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/catalog-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/cel-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/configuration-filesystem/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/connector-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/connector-participant-context-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/console-monitor/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-agreement-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-definition-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-definition-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-negotiation-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-negotiation-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-api-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-aggregate-services/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-api-client/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-catalog/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-contract-manager/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-contract/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-policies-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-transfer-manager/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-transfer-provision-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-transfer/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-transform/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/controlplane-base-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/controlplane-dcp-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/controlplane-feature-sql-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/core-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/crawler-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/crypto-common-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-address-http-data-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http-oauth2-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http-oauth2/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-iam/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-instance-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-client/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-control-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-self-registration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-signaling-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-signaling-client/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-signaling-transform/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dataplane-base-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dataplane-feature-sql-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-issuers-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-service/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-sts-remote-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-transform/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-identity/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-transform-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-validation-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-api-base-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-api-configuration-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-dispatcher-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-transform-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-validation-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-spi-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-transform-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-validation-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-version-http-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-version-transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-version/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/edr-index-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/edr-store-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/edr-store-receiver/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/edr-store-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/encryption-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/encryption-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/federated-catalog-cache-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/federated-catalog-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/holder-credential-request-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/http-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/http-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/http/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/identity-did-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/identity-did-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/identity-did-web/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jersey-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jersey-micrometer/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jersey-providers-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jetty-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jetty-micrometer/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/json-ld-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/json-ld-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/json-ld/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/json-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jti-validation-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jws2020-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jwt-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jwt-verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/keys-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/keys-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/ldp-verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/management-api-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/management-api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/management-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/micrometer-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/oauth2-client/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/oauth2-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-config-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-config-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-connector-classic-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-connector-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-single-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-definition-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-definition-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-engine-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-engine-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-evaluator-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-model/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-monitor-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-monitor-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-monitor-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/protocol-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/query-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/request-policy-context-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/runtime-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/runtime-metamodel/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/secrets-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-bootstrapper/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-lease-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-lease-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-lease/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-pool-apache-commons/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/state-machine-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/store-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/token-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/token-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/token-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-datasource-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-local/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-data-plane-signaling/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-process-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-process-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transform-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/util-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/validator-data-address-http-data/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/validator-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/validator-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/vault-hashicorp-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/vault-hashicorp/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/verifiable-credential-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/verifiable-credentials-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/verifiable-credentials-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/version-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/web-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.jetty.ee10/jetty-ee10-servlet/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty.websocket/jetty-websocket/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-http/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-io/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-security/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-server/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-session/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-util/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.parsson/parsson/1.1.7, EPL-2.0, approved, ee4j.parsson +maven/mavencentral/org.flywaydb/flyway-core/13.3.0, , restricted, clearlydefined +maven/mavencentral/org.flywaydb/flyway-database-cockroachdb/13.3.0, , restricted, clearlydefined +maven/mavencentral/org.flywaydb/flyway-database-postgresql/13.3.0, , restricted, clearlydefined +maven/mavencentral/org.glassfish.hk2.external/aopalliance-repackaged/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.hk2/hk2-api/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.hk2/hk2-locator/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.hk2/hk2-utils/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.hk2/osgi-resource-locator/3.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.jersey.containers/jersey-container-servlet/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.core/jersey-client/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.core/jersey-common/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.core/jersey-server/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.ext/jersey-entity-filtering/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.inject/jersey-hk2/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.media/jersey-media-json-jackson/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.media/jersey-media-multipart/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish/jakarta.json/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp +maven/mavencentral/org.hdrhistogram/HdrHistogram/2.2.2, BSD-2-Clause AND CC0-1.0 AND CC0-1.0, approved, #14828 +maven/mavencentral/org.javassist/javassist/3.30.2-GA, Apache-2.0 AND LGPL-2.1-or-later AND MPL-1.1, approved, #12108 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.1.21, Apache-2.0, approved, #17634 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.2.20, Apache-2.0, approved, #22410 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.2.21, Apache-2.0, approved, #22410 +maven/mavencentral/org.jetbrains/annotations/13.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/org.jetbrains/annotations/26.1.0, Apache-2.0, approved, #26477 +maven/mavencentral/org.jspecify/jspecify/1.0.0, Apache-2.0, approved, #21897 +maven/mavencentral/org.jvnet.mimepull/mimepull/1.9.15, CDDL-1.1 OR GPL-2.0-only WITH Classpath-exception-2.0, approved, CQ21484 +maven/mavencentral/org.latencyutils/LatencyUtils/2.0.3, CC0-1.0, approved, #15280 +maven/mavencentral/org.postgresql/postgresql/42.7.10, BSD-2-Clause AND Apache-2.0, approved, #11681 +maven/mavencentral/org.postgresql/postgresql/42.7.13, BSD-2-Clause AND Apache-2.0, approved, #11681 +maven/mavencentral/org.reactivestreams/reactive-streams/1.0.4, CC0-1.0, approved, CQ16332 +maven/mavencentral/org.slf4j/slf4j-api/1.7.36, MIT, approved, CQ13368 +maven/mavencentral/org.slf4j/slf4j-api/1.7.7, MIT, approved, CQ9827 +maven/mavencentral/org.slf4j/slf4j-api/2.0.17, MIT, approved, #5915 +maven/mavencentral/org.slf4j/slf4j-api/2.0.18, MIT, approved, #5915 +maven/mavencentral/org.slf4j/slf4j-api/2.0.9, MIT, approved, #5915 +maven/mavencentral/org.yaml/snakeyaml/2.3, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #16046 +maven/mavencentral/org.yaml/snakeyaml/2.5, Apache-2.0, approved, #23100 +maven/mavencentral/software.amazon.awssdk/annotations/2.42.34, Apache-2.0, approved, #26484 +maven/mavencentral/software.amazon.awssdk/apache-client/2.42.34, Apache-2.0, approved, #26485 +maven/mavencentral/software.amazon.awssdk/arns/2.42.34, Apache-2.0, approved, #26486 +maven/mavencentral/software.amazon.awssdk/auth/2.42.34, Apache-2.0, approved, #26487 +maven/mavencentral/software.amazon.awssdk/aws-core/2.42.34, Apache-2.0, approved, #26488 +maven/mavencentral/software.amazon.awssdk/aws-query-protocol/2.42.34, Apache-2.0, approved, #26489 +maven/mavencentral/software.amazon.awssdk/aws-xml-protocol/2.42.34, Apache-2.0, approved, #26490 +maven/mavencentral/software.amazon.awssdk/checksums-spi/2.42.34, Apache-2.0, approved, #26491 +maven/mavencentral/software.amazon.awssdk/checksums/2.42.34, Apache-2.0, approved, #26492 +maven/mavencentral/software.amazon.awssdk/crt-core/2.42.34, Apache-2.0, approved, #26493 +maven/mavencentral/software.amazon.awssdk/endpoints-spi/2.42.34, Apache-2.0, approved, #26494 +maven/mavencentral/software.amazon.awssdk/http-auth-aws-eventstream/2.42.34, Apache-2.0, approved, #26495 +maven/mavencentral/software.amazon.awssdk/http-auth-aws/2.42.34, Apache-2.0, approved, #26496 +maven/mavencentral/software.amazon.awssdk/http-auth-spi/2.42.34, Apache-2.0, approved, #26497 +maven/mavencentral/software.amazon.awssdk/http-auth/2.42.34, Apache-2.0, approved, #26498 +maven/mavencentral/software.amazon.awssdk/http-client-spi/2.42.34, Apache-2.0, approved, #26499 +maven/mavencentral/software.amazon.awssdk/iam/2.42.34, , restricted, clearlydefined +maven/mavencentral/software.amazon.awssdk/identity-spi/2.42.34, Apache-2.0, approved, #26500 +maven/mavencentral/software.amazon.awssdk/json-utils/2.42.34, Apache-2.0, approved, #26501 +maven/mavencentral/software.amazon.awssdk/metrics-spi/2.42.34, Apache-2.0, approved, #26502 +maven/mavencentral/software.amazon.awssdk/netty-nio-client/2.42.34, Apache-2.0, approved, #26503 +maven/mavencentral/software.amazon.awssdk/profiles/2.42.34, Apache-2.0, approved, #26504 +maven/mavencentral/software.amazon.awssdk/protocol-core/2.42.34, Apache-2.0, approved, #26505 +maven/mavencentral/software.amazon.awssdk/regions/2.42.34, Apache-2.0, approved, #26506 +maven/mavencentral/software.amazon.awssdk/retries-spi/2.42.34, Apache-2.0, approved, #26507 +maven/mavencentral/software.amazon.awssdk/retries/2.42.34, Apache-2.0, approved, #26508 +maven/mavencentral/software.amazon.awssdk/s3/2.42.34, Apache-2.0, approved, #26510 +maven/mavencentral/software.amazon.awssdk/sdk-core/2.42.34, Apache-2.0, approved, #26511 +maven/mavencentral/software.amazon.awssdk/sts/2.42.34, Apache-2.0, approved, #27697 +maven/mavencentral/software.amazon.awssdk/third-party-jackson-core/2.42.34, Apache-2.0, approved, #26512 +maven/mavencentral/software.amazon.awssdk/utils-lite/2.42.34, Apache-2.0, approved, #26513 +maven/mavencentral/software.amazon.awssdk/utils/2.42.34, Apache-2.0, approved, #26514 +maven/mavencentral/software.amazon.eventstream/eventstream/1.0.1, Apache-2.0, approved, #19691 +maven/mavencentral/tools.jackson.core/jackson-core/3.1.5, Apache-2.0 AND MIT, approved, #26415 +maven/mavencentral/tools.jackson.core/jackson-databind/3.1.5, Apache-2.0, approved, #26439 +maven/mavencentral/tools.jackson/jackson-bom/3.1.5, Apache-2.0, approved, #26520 From 0c41a745d399c5b312ae509f75b684401205d25e Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Tue, 25 Aug 2026 08:35:30 +0200 Subject: [PATCH 252/259] feat: fix security vulnerabilities (#3025) --- build.gradle.kts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index bf726da413..363aeff0b4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -65,8 +65,24 @@ allprojects { dependencies { implementation("org.slf4j:slf4j-api:2.0.18") + implementation(enforcedPlatform("io.netty:netty-bom:4.1.136.Final")) { + because("CVE-2026-56819/56745/55833/55831/59901/50010/47691/45674/45416/44249/42587/42584/42579/42583: netty fixed in 4.1.136") + } + implementation(enforcedPlatform("org.eclipse.jetty:jetty-bom:12.1.10")) { + because("CVE-2026-10050: jetty-security Digest auth bypass, fixed in 12.1.10") + } + implementation(enforcedPlatform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.1.10")) { + because("CVE-2026-10050: aligns Jetty ee10 modules with jetty-bom 12.1.10") + } + implementation(enforcedPlatform("com.fasterxml.jackson:jackson-bom:2.21.4")) { + because("CVE-2026-54513/54512 + GHSA-r7wm-3cxj-wff9: jackson-databind/core fixed in 2.21.4") + } + constraints { plugins.apply("org.gradle.java-test-fixtures") + implementation("org.eclipse.jetty.websocket:jetty-websocket:12.1.10") { + because("CVE-2026-10050: align jetty-websocket aggregator (not in jetty-bom) with jetty 12.1.10") + } } } From 116e6d1f9df768b10bb46cc08b51f4211384ca6c Mon Sep 17 00:00:00 2001 From: eclipse-tractusx-bot Date: Tue, 25 Aug 2026 06:37:09 +0000 Subject: [PATCH 253/259] Update DEPENDENCIES file --- DEPENDENCIES | 68 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index 5d4ebb514f..a583da3c08 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,3 +1,7 @@ +Invalid: com.fasterxml.jackson:jackson-bom:{strictly, unknown, restricted, none +Invalid: io.netty:netty-bom:{strictly, unknown, restricted, none +Invalid: org.eclipse.jetty.ee10:jetty-ee10-bom:{strictly, unknown, restricted, none +Invalid: org.eclipse.jetty:jetty-bom:{strictly, unknown, restricted, none maven/mavencentral/com.apicatalog/carbon-did/0.3.0, Apache-2.0, approved, clearlydefined maven/mavencentral/com.apicatalog/copper-multibase/0.5.0, Apache-2.0, approved, #14501 maven/mavencentral/com.apicatalog/copper-multicodec/0.1.1, Apache-2.0, approved, #14500 @@ -27,25 +31,28 @@ maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.19.1, Apache maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.19.2, Apache-2.0, approved, #21911 maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.21, Apache-2.0, approved, #25587 maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.18.4.1, Apache-2.0 AND MIT, approved, #16371 -maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.21.2, Apache-2.0 AND MIT, approved, #25590 +maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.21.4, Apache-2.0 AND MIT, approved, #25590 maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.18.3, Apache-2.0, approved, #16372 maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.18.4, Apache-2.0, approved, #16372 maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.19.1, Apache-2.0, approved, #21909 maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.19.2, Apache-2.0, approved, #21909 maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.21.2, Apache-2.0, approved, #25591 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.21.4, Apache-2.0, approved, #25591 maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.18.3, Apache-2.0, approved, #16370 maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.19.2, Apache-2.0, approved, #21912 -maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.21.2, Apache-2.0, approved, #25589 +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.21.4, Apache-2.0, approved, #25589 maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jakarta-jsonp/2.21.2, Apache-2.0, approved, #26448 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jakarta-jsonp/2.21.4, Apache-2.0, approved, #26448 maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.18.4, Apache-2.0, approved, #16625 maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.19.2, Apache-2.0, approved, #23299 maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.21.2, Apache-2.0, approved, #26441 -maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-base/2.21.2, Apache-2.0, approved, #26442 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.21.4, Apache-2.0, approved, #26441 +maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-base/2.21.4, Apache-2.0, approved, #26442 maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.19.2, Apache-2.0, approved, #20839 -maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.21.2, Apache-2.0, approved, #26443 +maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.21.4, Apache-2.0, approved, #26443 maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.19.1, Apache-2.0, approved, #21910 -maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.21.2, Apache-2.0, approved, #25588 -maven/mavencentral/com.fasterxml.jackson/jackson-bom/2.21.2, Apache-2.0, approved, #26451 +maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.21.4, Apache-2.0, approved, #25588 +maven/mavencentral/com.fasterxml.jackson/jackson-bom/2.21.4, Apache-2.0, approved, #26451 maven/mavencentral/com.google.code.findbugs/jsr305/3.0.2, Apache-2.0 and CC-BY-2.5, approved, #15220 maven/mavencentral/com.google.code.gson/gson/2.13.2, Apache-2.0, approved, #20656 maven/mavencentral/com.google.crypto.tink/tink/1.20.0, Apache-2.0, approved, #28384 @@ -76,54 +83,61 @@ maven/mavencentral/io.github.classgraph/classgraph/4.8.184, MIT, approved, CQ225 maven/mavencentral/io.micrometer/micrometer-commons/1.16.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #24726 maven/mavencentral/io.micrometer/micrometer-core/1.16.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #24722 maven/mavencentral/io.micrometer/micrometer-observation/1.16.4, Apache-2.0, approved, #24713 -maven/mavencentral/io.netty/netty-buffer/4.1.128.Final, Apache-2.0, approved, CQ21842 maven/mavencentral/io.netty/netty-buffer/4.1.130.Final, Apache-2.0, approved, CQ21842 maven/mavencentral/io.netty/netty-buffer/4.1.132.Final, Apache-2.0, approved, CQ21842 -maven/mavencentral/io.netty/netty-codec-dns/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-buffer/4.1.136.Final, Apache-2.0, approved, CQ21842 +maven/mavencentral/io.netty/netty-codec-dns/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-codec-http/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-codec-http/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-codec-http/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-codec-http2/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-codec-http2/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-codec-http2/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-socks/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-socks/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-codec/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-codec/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-common/4.1.128.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-codec/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-common/4.1.130.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 maven/mavencentral/io.netty/netty-common/4.1.132.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-common/4.1.136.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 maven/mavencentral/io.netty/netty-handler-proxy/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-handler-proxy/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler-proxy/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-handler/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-handler/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-handler/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-resolver-dns-classes-macos/4.1.128.Final, Apache-2.0, approved, #6367 +maven/mavencentral/io.netty/netty-handler/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver-dns-classes-macos/4.1.136.Final, Apache-2.0, approved, #6367 maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.128.Final, Apache-2.0, approved, #7004 +maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.136.Final, Apache-2.0, approved, #7004 maven/mavencentral/io.netty/netty-resolver-dns/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-resolver/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver-dns/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-resolver/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.74.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 -maven/mavencentral/io.netty/netty-tcnative-classes/2.0.74.Final, Apache-2.0, approved, #23398 -maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.130.Final, Apache-2.0, approved, #6366 +maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.78.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 +maven/mavencentral/io.netty/netty-tcnative-classes/2.0.78.Final, Apache-2.0, approved, #23398 maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.132.Final, Apache-2.0, approved, #6366 -maven/mavencentral/io.netty/netty-transport-classes-kqueue/4.1.130.Final, Apache-2.0, approved, #4107 +maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.136.Final, Apache-2.0, approved, #6366 +maven/mavencentral/io.netty/netty-transport-classes-kqueue/4.1.136.Final, Apache-2.0, approved, #4107 maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.netty/netty-transport/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-annotations/1.32.0, Apache-2.0, approved, #11684 maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-annotations/2.30.0, Apache-2.0, approved, #30125 maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-api-incubator/2.30.0-alpha, , restricted, clearlydefined maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-api/2.30.0, , restricted, clearlydefined maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-log4j-appender-2.17/2.30.0-alpha, , restricted, clearlydefined maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/2.30.0-alpha, , restricted, clearlydefined -maven/mavencentral/io.opentelemetry.semconv/opentelemetry-semconv/1.43.0, , restricted, clearlydefined +maven/mavencentral/io.opentelemetry.semconv/opentelemetry-semconv/1.43.0, Apache-2.0, approved, #30446 maven/mavencentral/io.opentelemetry/opentelemetry-api-incubator/1.64.0-alpha, , restricted, clearlydefined maven/mavencentral/io.opentelemetry/opentelemetry-api/1.32.0, Apache-2.0, approved, #11682 maven/mavencentral/io.opentelemetry/opentelemetry-api/1.61.0, Apache-2.0, approved, #29641 @@ -382,14 +396,18 @@ maven/mavencentral/org.eclipse.edc/verifiable-credentials-spi/0.17.0, Apache-2.0 maven/mavencentral/org.eclipse.edc/verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc maven/mavencentral/org.eclipse.edc/version-api/0.17.0, Apache-2.0, approved, technology.edc maven/mavencentral/org.eclipse.edc/web-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.jetty.ee10/jetty-ee10-servlet/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty maven/mavencentral/org.eclipse.jetty.ee10/jetty-ee10-servlet/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty.websocket/jetty-websocket/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty maven/mavencentral/org.eclipse.jetty.websocket/jetty-websocket/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-http/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty maven/mavencentral/org.eclipse.jetty/jetty-http/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-io/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-security/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-io/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-security/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-server/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty maven/mavencentral/org.eclipse.jetty/jetty-server/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-session/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-util/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-session/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-util/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty maven/mavencentral/org.eclipse.parsson/parsson/1.1.7, EPL-2.0, approved, ee4j.parsson maven/mavencentral/org.flywaydb/flyway-core/13.3.0, , restricted, clearlydefined maven/mavencentral/org.flywaydb/flyway-database-cockroachdb/13.3.0, , restricted, clearlydefined From 4fde370902de5487d8dd330458e3029a790cb036 Mon Sep 17 00:00:00 2001 From: Andrii Yurkevych Date: Tue, 25 Aug 2026 10:35:26 +0200 Subject: [PATCH 254/259] fix : enforcedPlatform is not allowed for published component (#3029) --- build.gradle.kts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 363aeff0b4..79272dad2e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -65,16 +65,16 @@ allprojects { dependencies { implementation("org.slf4j:slf4j-api:2.0.18") - implementation(enforcedPlatform("io.netty:netty-bom:4.1.136.Final")) { - because("CVE-2026-56819/56745/55833/55831/59901/50010/47691/45674/45416/44249/42587/42584/42579/42583: netty fixed in 4.1.136") + implementation(platform("io.netty:netty-bom:4.1.137.Final")) { + because("CVE-2026-56819/56745/55833/55831/59901/50010/47691/45674/45416/44249/42587/42584/42579/42583: netty fixed in 4.1.136; CVE-2026-59903 (CorsHandler Vary header cache poisoning) backported to 4.1.137") } - implementation(enforcedPlatform("org.eclipse.jetty:jetty-bom:12.1.10")) { + implementation(platform("org.eclipse.jetty:jetty-bom:12.1.10")) { because("CVE-2026-10050: jetty-security Digest auth bypass, fixed in 12.1.10") } - implementation(enforcedPlatform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.1.10")) { + implementation(platform("org.eclipse.jetty.ee10:jetty-ee10-bom:12.1.10")) { because("CVE-2026-10050: aligns Jetty ee10 modules with jetty-bom 12.1.10") } - implementation(enforcedPlatform("com.fasterxml.jackson:jackson-bom:2.21.4")) { + implementation(platform("com.fasterxml.jackson:jackson-bom:2.21.4")) { because("CVE-2026-54513/54512 + GHSA-r7wm-3cxj-wff9: jackson-databind/core fixed in 2.21.4") } From ed1952035553cdcf4b283d72b270beb0c847c5fd Mon Sep 17 00:00:00 2001 From: eclipse-tractusx-bot Date: Tue, 25 Aug 2026 08:38:41 +0000 Subject: [PATCH 255/259] Update DEPENDENCIES file --- DEPENDENCIES | 484 --------------------------------------------------- 1 file changed, 484 deletions(-) diff --git a/DEPENDENCIES b/DEPENDENCIES index a583da3c08..e69de29bb2 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,484 +0,0 @@ -Invalid: com.fasterxml.jackson:jackson-bom:{strictly, unknown, restricted, none -Invalid: io.netty:netty-bom:{strictly, unknown, restricted, none -Invalid: org.eclipse.jetty.ee10:jetty-ee10-bom:{strictly, unknown, restricted, none -Invalid: org.eclipse.jetty:jetty-bom:{strictly, unknown, restricted, none -maven/mavencentral/com.apicatalog/carbon-did/0.3.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.apicatalog/copper-multibase/0.5.0, Apache-2.0, approved, #14501 -maven/mavencentral/com.apicatalog/copper-multicodec/0.1.1, Apache-2.0, approved, #14500 -maven/mavencentral/com.apicatalog/iron-ed25519-cryptosuite-2020/0.14.0, Apache-2.0, approved, #14503 -maven/mavencentral/com.apicatalog/iron-verifiable-credentials/0.14.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.apicatalog/titanium-jcs/1.1.1, Apache-2.0, approved, #25093 -maven/mavencentral/com.apicatalog/titanium-json-ld/1.0.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.apicatalog/titanium-json-ld/1.4.0, Apache-2.0, approved, #15200 -maven/mavencentral/com.apicatalog/titanium-json-ld/1.7.0, Apache-2.0, approved, #25089 -maven/mavencentral/com.apicatalog/titanium-rdf-api/1.0.0, Apache-2.0, approved, #20245 -maven/mavencentral/com.apicatalog/titanium-rdf-n-quads/1.0.2, Apache-2.0, approved, #20243 -maven/mavencentral/com.azure/azure-core-http-netty/1.15.11, MIT AND Apache-2.0, approved, #16697 -maven/mavencentral/com.azure/azure-core-http-netty/1.16.3, MIT AND Apache-2.0, approved, #29562 -maven/mavencentral/com.azure/azure-core/1.55.3, MIT, approved, clearlydefined -maven/mavencentral/com.azure/azure-core/1.57.1, MIT, approved, clearlydefined -maven/mavencentral/com.azure/azure-identity/1.18.2, MIT, approved, #29561 -maven/mavencentral/com.azure/azure-json/1.4.0, MIT, approved, clearlydefined -maven/mavencentral/com.azure/azure-json/1.5.1, MIT AND Apache-2.0, approved, #26444 -maven/mavencentral/com.azure/azure-storage-blob/12.30.0, MIT, approved, #20441 -maven/mavencentral/com.azure/azure-storage-common/12.29.0, MIT, approved, #20440 -maven/mavencentral/com.azure/azure-storage-internal-avro/12.15.0, MIT, approved, clearlydefined -maven/mavencentral/com.azure/azure-xml/1.2.0, Apache-2.0, approved, #26447 -maven/mavencentral/com.azure/azure-xml/1.2.1, Apache-2.0, approved, #26447 -maven/mavencentral/com.ethlo.time/itu/1.14.0, Apache-2.0, approved, #19505 -maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.18.4, Apache-2.0, approved, #16364 -maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.19.1, Apache-2.0, approved, #21911 -maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.19.2, Apache-2.0, approved, #21911 -maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.21, Apache-2.0, approved, #25587 -maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.18.4.1, Apache-2.0 AND MIT, approved, #16371 -maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.21.4, Apache-2.0 AND MIT, approved, #25590 -maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.18.3, Apache-2.0, approved, #16372 -maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.18.4, Apache-2.0, approved, #16372 -maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.19.1, Apache-2.0, approved, #21909 -maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.19.2, Apache-2.0, approved, #21909 -maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.21.2, Apache-2.0, approved, #25591 -maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.21.4, Apache-2.0, approved, #25591 -maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.18.3, Apache-2.0, approved, #16370 -maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.19.2, Apache-2.0, approved, #21912 -maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.21.4, Apache-2.0, approved, #25589 -maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jakarta-jsonp/2.21.2, Apache-2.0, approved, #26448 -maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jakarta-jsonp/2.21.4, Apache-2.0, approved, #26448 -maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.18.4, Apache-2.0, approved, #16625 -maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.19.2, Apache-2.0, approved, #23299 -maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.21.2, Apache-2.0, approved, #26441 -maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.21.4, Apache-2.0, approved, #26441 -maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-base/2.21.4, Apache-2.0, approved, #26442 -maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.19.2, Apache-2.0, approved, #20839 -maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.21.4, Apache-2.0, approved, #26443 -maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.19.1, Apache-2.0, approved, #21910 -maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.21.4, Apache-2.0, approved, #25588 -maven/mavencentral/com.fasterxml.jackson/jackson-bom/2.21.4, Apache-2.0, approved, #26451 -maven/mavencentral/com.google.code.findbugs/jsr305/3.0.2, Apache-2.0 and CC-BY-2.5, approved, #15220 -maven/mavencentral/com.google.code.gson/gson/2.13.2, Apache-2.0, approved, #20656 -maven/mavencentral/com.google.crypto.tink/tink/1.20.0, Apache-2.0, approved, #28384 -maven/mavencentral/com.google.errorprone/error_prone_annotations/2.41.0, Apache-2.0, approved, #22631 -maven/mavencentral/com.google.protobuf/protobuf-java/4.33.0, BSD-3-Clause, approved, #29831 -maven/mavencentral/com.microsoft.azure/msal4j-persistence-extension/1.3.0, MIT, approved, #14411 -maven/mavencentral/com.microsoft.azure/msal4j/1.15.0, MIT, approved, clearlydefined -maven/mavencentral/com.microsoft.azure/msal4j/1.23.1, MIT, approved, clearlydefined -maven/mavencentral/com.networknt/json-schema-validator/2.0.0, Apache-2.0 AND Unicode-TOU, approved, #25988 -maven/mavencentral/com.nimbusds/nimbus-jose-jwt/10.8, Apache-2.0, approved, #26455 -maven/mavencentral/com.nimbusds/nimbus-jose-jwt/10.9.1, Apache-2.0, approved, #29000 -maven/mavencentral/com.squareup.okhttp3/okhttp-dnsoverhttps/5.3.2, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.squareup.okhttp3/okhttp-jvm/5.3.2, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.squareup.okhttp3/okhttp-jvm/5.4.0, Apache-2.0, approved, #29005 -maven/mavencentral/com.squareup.okhttp3/okhttp/4.9.3, Apache-2.0 AND MPL-2.0, approved, #3225 -maven/mavencentral/com.squareup.okhttp3/okhttp/5.3.2, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.squareup.okhttp3/okhttp/5.4.0, Apache-2.0, approved, #29015 -maven/mavencentral/com.squareup.okio/okio-jvm/3.16.4, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.squareup.okio/okio-jvm/3.17.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.squareup.okio/okio/3.16.4, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.squareup.okio/okio/3.17.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/commons-codec/commons-codec/1.11, Apache-2.0 AND BSD-3-Clause, approved, CQ15971 -maven/mavencentral/commons-codec/commons-codec/1.17.1, Apache-2.0 AND (Apache-2.0 AND BSD-3-Clause), approved, #14583 -maven/mavencentral/commons-logging/commons-logging/1.2, Apache-2.0, approved, CQ10162 -maven/mavencentral/dev.failsafe/failsafe-okhttp/3.3.2, Apache-2.0, approved, #15208 -maven/mavencentral/dev.failsafe/failsafe/3.3.2, Apache-2.0, approved, #9268 -maven/mavencentral/io.github.classgraph/classgraph/4.8.184, MIT, approved, CQ22530 -maven/mavencentral/io.micrometer/micrometer-commons/1.16.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #24726 -maven/mavencentral/io.micrometer/micrometer-core/1.16.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #24722 -maven/mavencentral/io.micrometer/micrometer-observation/1.16.4, Apache-2.0, approved, #24713 -maven/mavencentral/io.netty/netty-buffer/4.1.130.Final, Apache-2.0, approved, CQ21842 -maven/mavencentral/io.netty/netty-buffer/4.1.132.Final, Apache-2.0, approved, CQ21842 -maven/mavencentral/io.netty/netty-buffer/4.1.136.Final, Apache-2.0, approved, CQ21842 -maven/mavencentral/io.netty/netty-codec-dns/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http2/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http2/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http2/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http2/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-socks/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-common/4.1.130.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 -maven/mavencentral/io.netty/netty-common/4.1.132.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 -maven/mavencentral/io.netty/netty-common/4.1.136.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 -maven/mavencentral/io.netty/netty-handler-proxy/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-handler-proxy/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-handler-proxy/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-handler/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-handler/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-handler/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-handler/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-resolver-dns-classes-macos/4.1.136.Final, Apache-2.0, approved, #6367 -maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.128.Final, Apache-2.0, approved, #7004 -maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.136.Final, Apache-2.0, approved, #7004 -maven/mavencentral/io.netty/netty-resolver-dns/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-resolver-dns/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-resolver/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-resolver/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.74.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 -maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.78.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 -maven/mavencentral/io.netty/netty-tcnative-classes/2.0.78.Final, Apache-2.0, approved, #23398 -maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.132.Final, Apache-2.0, approved, #6366 -maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.136.Final, Apache-2.0, approved, #6366 -maven/mavencentral/io.netty/netty-transport-classes-kqueue/4.1.136.Final, Apache-2.0, approved, #4107 -maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport/4.1.136.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-annotations/1.32.0, Apache-2.0, approved, #11684 -maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-annotations/2.30.0, Apache-2.0, approved, #30125 -maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-api-incubator/2.30.0-alpha, , restricted, clearlydefined -maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-api/2.30.0, , restricted, clearlydefined -maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-log4j-appender-2.17/2.30.0-alpha, , restricted, clearlydefined -maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/2.30.0-alpha, , restricted, clearlydefined -maven/mavencentral/io.opentelemetry.semconv/opentelemetry-semconv/1.43.0, Apache-2.0, approved, #30446 -maven/mavencentral/io.opentelemetry/opentelemetry-api-incubator/1.64.0-alpha, , restricted, clearlydefined -maven/mavencentral/io.opentelemetry/opentelemetry-api/1.32.0, Apache-2.0, approved, #11682 -maven/mavencentral/io.opentelemetry/opentelemetry-api/1.61.0, Apache-2.0, approved, #29641 -maven/mavencentral/io.opentelemetry/opentelemetry-api/1.64.0, Apache-2.0, approved, #29872 -maven/mavencentral/io.opentelemetry/opentelemetry-common/1.64.0, Apache-2.0, approved, #29870 -maven/mavencentral/io.opentelemetry/opentelemetry-context/1.64.0, Apache-2.0, approved, #29871 -maven/mavencentral/io.projectreactor.netty/reactor-netty-core/1.2.13, Apache-2.0, approved, #23393 -maven/mavencentral/io.projectreactor.netty/reactor-netty-http/1.2.13, Apache-2.0, approved, #23394 -maven/mavencentral/io.projectreactor/reactor-core/3.7.14, Apache-2.0, approved, #17529 -maven/mavencentral/io.setl/rdf-urdna/1.1, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.42, Apache-2.0, approved, #5947 -maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.42, Apache-2.0, approved, #5929 -maven/mavencentral/io.swagger.core.v3/swagger-integration-jakarta/2.2.42, Apache-2.0, approved, #11475 -maven/mavencentral/io.swagger.core.v3/swagger-jaxrs2-jakarta/2.2.42, Apache-2.0, approved, #11477 -maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.42, Apache-2.0, approved, #5919 -maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.3, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf -maven/mavencentral/jakarta.annotation/jakarta.annotation-api/3.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca -maven/mavencentral/jakarta.inject/jakarta.inject-api/2.0.1, Apache-2.0, approved, ee4j.cdi -maven/mavencentral/jakarta.json/jakarta.json-api/2.1.3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp -maven/mavencentral/jakarta.servlet/jakarta.servlet-api/6.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.servlet -maven/mavencentral/jakarta.servlet/jakarta.servlet-api/6.1.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.servlet -maven/mavencentral/jakarta.validation/jakarta.validation-api/3.0.2, Apache-2.0, approved, ee4j.validation -maven/mavencentral/jakarta.validation/jakarta.validation-api/3.1.0, Apache-2.0, approved, ee4j.validation -maven/mavencentral/jakarta.ws.rs/jakarta.ws.rs-api/4.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.rest -maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/3.0.1, BSD-3-Clause, approved, ee4j.jaxb -maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/4.0.2, BSD-3-Clause, approved, ee4j.jaxb -maven/mavencentral/net.java.dev.jna/jna-platform/5.13.0, Apache-2.0 OR LGPL-2.1-or-later, approved, #6707 -maven/mavencentral/net.java.dev.jna/jna-platform/5.17.0, Apache-2.0 OR LGPL-2.1-or-later, approved, #20116 -maven/mavencentral/net.java.dev.jna/jna/5.13.0, Apache-2.0 AND LGPL-2.1-or-later, approved, #15196 -maven/mavencentral/net.java.dev.jna/jna/5.17.0, Apache-2.0 AND LGPL-2.1-or-later, approved, #20112 -maven/mavencentral/org.apache.commons/commons-lang3/3.18.0, Apache-2.0, approved, #22470 -maven/mavencentral/org.apache.commons/commons-pool2/2.13.1, Apache-2.0 AND CC-PDDC, approved, #25941 -maven/mavencentral/org.apache.httpcomponents/httpclient/4.5.13, Apache-2.0, approved, #15248 -maven/mavencentral/org.apache.httpcomponents/httpcore/4.4.13, Apache-2.0, approved, CQ23528 -maven/mavencentral/org.apache.httpcomponents/httpcore/4.4.16, Apache-2.0, approved, CQ23528 -maven/mavencentral/org.apache.logging.log4j/log4j-api/2.26.1, Apache-2.0, approved, #27998 -maven/mavencentral/org.apache.logging.log4j/log4j-core/2.26.1, Apache-2.0 AND (Apache-2.0 AND LGPL-2.0-or-later), approved, #28001 -maven/mavencentral/org.apache.logging.log4j/log4j-layout-template-json/2.26.1, Apache-2.0, approved, clearlydefined -maven/mavencentral/org.bouncycastle/bcpkix-jdk18on/1.84, MIT, approved, #27142 -maven/mavencentral/org.bouncycastle/bcprov-jdk18on/1.84, MIT AND CC0-1.0, approved, #27143 -maven/mavencentral/org.bouncycastle/bcutil-jdk18on/1.84, MIT, approved, #27144 -maven/mavencentral/org.checkerframework/checker-qual/3.55.1, MIT, approved, #29939 -maven/mavencentral/org.eclipse.edc.aws/aws-s3-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc.aws/aws-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc.aws/data-plane-aws-s3/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc.aws/data-plane-provision-aws-s3/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc.aws/validator-data-address-s3/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc.azure/azure-blob-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc.azure/data-plane-azure-storage/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc.azure/data-plane-provision-blob/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/accesstokendata-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/api-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/api-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/api-observability/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/asset-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/asset-index-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/asset-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/auth-configuration/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/auth-delegated/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/auth-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/auth-tokenbased/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/boot-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/boot-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/boot/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/callback-event-dispatcher/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/callback-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/callback-static-endpoint/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/catalog-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/catalog-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/cel-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/configuration-filesystem/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/connector-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/connector-participant-context-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/console-monitor/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/contract-agreement-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/contract-definition-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/contract-definition-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/contract-negotiation-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/contract-negotiation-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/contract-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-api-configuration/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-aggregate-services/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-api-client/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-catalog/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-contract-manager/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-contract/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-policies-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-transfer-manager/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-transfer-provision-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-transfer/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/control-plane-transform/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/controlplane-base-bom/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/controlplane-dcp-bom/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/controlplane-feature-sql-bom/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/core-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/crawler-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/crypto-common-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-address-http-data-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-http-oauth2-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-http-oauth2/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-http-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-http/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-iam/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-instance-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-selector-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-selector-client/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-selector-control-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-selector-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-selector-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-self-registration/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-signaling-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-signaling-client/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-signaling-transform/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/data-plane-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dataplane-base-bom/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dataplane-feature-sql-bom/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/decentralized-claims-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/decentralized-claims-issuers-configuration/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/decentralized-claims-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/decentralized-claims-service/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/decentralized-claims-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/decentralized-claims-sts-remote-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/decentralized-claims-transform/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/decentralized-identity/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-catalog-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-catalog-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-catalog-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-catalog-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-catalog-transform-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-catalog-transform-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-catalog-validation-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-http-api-base-configuration/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-http-api-configuration-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-http-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-http-dispatcher-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-http-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-negotiation-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-negotiation-transform-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-negotiation-transform-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-negotiation-validation-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-spi-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-transfer-process-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-transfer-process-transform-2025/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-transfer-process-transform-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-transfer-process-validation-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-version-http-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-version-transform-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp-version/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/dsp/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/edr-index-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/edr-store-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/edr-store-receiver/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/edr-store-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/encryption-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/encryption-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/federated-catalog-cache-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/federated-catalog-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/holder-credential-request-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/http-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/http-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/http/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/identity-did-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/identity-did-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/identity-did-web/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jersey-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jersey-micrometer/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jersey-providers-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jetty-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jetty-micrometer/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/json-ld-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/json-ld-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/json-ld/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/json-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jti-validation-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jws2020-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jwt-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/jwt-verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/keys-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/keys-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/ldp-verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/management-api-configuration/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/management-api-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/management-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/micrometer-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/oauth2-client/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/oauth2-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/participant-context-config-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/participant-context-config-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/participant-context-connector-classic-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/participant-context-connector-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/participant-context-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/participant-context-single-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/participant-context-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/participant-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-definition-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-definition-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-engine-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-engine-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-evaluator-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-model/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-monitor-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-monitor-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-monitor-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/policy-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/protocol-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/query-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/request-policy-context-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/runtime-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/runtime-metamodel/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/secrets-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/sql-bootstrapper/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/sql-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/sql-lease-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/sql-lease-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/sql-lease/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/sql-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/sql-pool-apache-commons/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/state-machine-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/store-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/token-core/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/token-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/token-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transaction-datasource-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transaction-local/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transaction-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transfer-data-plane-signaling/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transfer-process-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transfer-process-store-sql/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transfer-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transform-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/transform-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/util-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/validator-data-address-http-data/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/validator-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/validator-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/vault-hashicorp-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/vault-hashicorp/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/verifiable-credential-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/verifiable-credentials-lib/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/verifiable-credentials-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/version-api/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.edc/web-spi/0.17.0, Apache-2.0, approved, technology.edc -maven/mavencentral/org.eclipse.jetty.ee10/jetty-ee10-servlet/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty.ee10/jetty-ee10-servlet/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty.websocket/jetty-websocket/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty.websocket/jetty-websocket/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-http/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-http/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-io/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-security/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-server/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-server/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-session/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.jetty/jetty-util/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty -maven/mavencentral/org.eclipse.parsson/parsson/1.1.7, EPL-2.0, approved, ee4j.parsson -maven/mavencentral/org.flywaydb/flyway-core/13.3.0, , restricted, clearlydefined -maven/mavencentral/org.flywaydb/flyway-database-cockroachdb/13.3.0, , restricted, clearlydefined -maven/mavencentral/org.flywaydb/flyway-database-postgresql/13.3.0, , restricted, clearlydefined -maven/mavencentral/org.glassfish.hk2.external/aopalliance-repackaged/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish -maven/mavencentral/org.glassfish.hk2/hk2-api/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish -maven/mavencentral/org.glassfish.hk2/hk2-locator/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish -maven/mavencentral/org.glassfish.hk2/hk2-utils/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish -maven/mavencentral/org.glassfish.hk2/osgi-resource-locator/3.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish -maven/mavencentral/org.glassfish.jersey.containers/jersey-container-servlet/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey -maven/mavencentral/org.glassfish.jersey.core/jersey-client/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey -maven/mavencentral/org.glassfish.jersey.core/jersey-common/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey -maven/mavencentral/org.glassfish.jersey.core/jersey-server/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey -maven/mavencentral/org.glassfish.jersey.ext/jersey-entity-filtering/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey -maven/mavencentral/org.glassfish.jersey.inject/jersey-hk2/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey -maven/mavencentral/org.glassfish.jersey.media/jersey-media-json-jackson/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey -maven/mavencentral/org.glassfish.jersey.media/jersey-media-multipart/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey -maven/mavencentral/org.glassfish/jakarta.json/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp -maven/mavencentral/org.hdrhistogram/HdrHistogram/2.2.2, BSD-2-Clause AND CC0-1.0 AND CC0-1.0, approved, #14828 -maven/mavencentral/org.javassist/javassist/3.30.2-GA, Apache-2.0 AND LGPL-2.1-or-later AND MPL-1.1, approved, #12108 -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.1.21, Apache-2.0, approved, #17634 -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.2.20, Apache-2.0, approved, #22410 -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.2.21, Apache-2.0, approved, #22410 -maven/mavencentral/org.jetbrains/annotations/13.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/org.jetbrains/annotations/26.1.0, Apache-2.0, approved, #26477 -maven/mavencentral/org.jspecify/jspecify/1.0.0, Apache-2.0, approved, #21897 -maven/mavencentral/org.jvnet.mimepull/mimepull/1.9.15, CDDL-1.1 OR GPL-2.0-only WITH Classpath-exception-2.0, approved, CQ21484 -maven/mavencentral/org.latencyutils/LatencyUtils/2.0.3, CC0-1.0, approved, #15280 -maven/mavencentral/org.postgresql/postgresql/42.7.10, BSD-2-Clause AND Apache-2.0, approved, #11681 -maven/mavencentral/org.postgresql/postgresql/42.7.13, BSD-2-Clause AND Apache-2.0, approved, #11681 -maven/mavencentral/org.reactivestreams/reactive-streams/1.0.4, CC0-1.0, approved, CQ16332 -maven/mavencentral/org.slf4j/slf4j-api/1.7.36, MIT, approved, CQ13368 -maven/mavencentral/org.slf4j/slf4j-api/1.7.7, MIT, approved, CQ9827 -maven/mavencentral/org.slf4j/slf4j-api/2.0.17, MIT, approved, #5915 -maven/mavencentral/org.slf4j/slf4j-api/2.0.18, MIT, approved, #5915 -maven/mavencentral/org.slf4j/slf4j-api/2.0.9, MIT, approved, #5915 -maven/mavencentral/org.yaml/snakeyaml/2.3, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #16046 -maven/mavencentral/org.yaml/snakeyaml/2.5, Apache-2.0, approved, #23100 -maven/mavencentral/software.amazon.awssdk/annotations/2.42.34, Apache-2.0, approved, #26484 -maven/mavencentral/software.amazon.awssdk/apache-client/2.42.34, Apache-2.0, approved, #26485 -maven/mavencentral/software.amazon.awssdk/arns/2.42.34, Apache-2.0, approved, #26486 -maven/mavencentral/software.amazon.awssdk/auth/2.42.34, Apache-2.0, approved, #26487 -maven/mavencentral/software.amazon.awssdk/aws-core/2.42.34, Apache-2.0, approved, #26488 -maven/mavencentral/software.amazon.awssdk/aws-query-protocol/2.42.34, Apache-2.0, approved, #26489 -maven/mavencentral/software.amazon.awssdk/aws-xml-protocol/2.42.34, Apache-2.0, approved, #26490 -maven/mavencentral/software.amazon.awssdk/checksums-spi/2.42.34, Apache-2.0, approved, #26491 -maven/mavencentral/software.amazon.awssdk/checksums/2.42.34, Apache-2.0, approved, #26492 -maven/mavencentral/software.amazon.awssdk/crt-core/2.42.34, Apache-2.0, approved, #26493 -maven/mavencentral/software.amazon.awssdk/endpoints-spi/2.42.34, Apache-2.0, approved, #26494 -maven/mavencentral/software.amazon.awssdk/http-auth-aws-eventstream/2.42.34, Apache-2.0, approved, #26495 -maven/mavencentral/software.amazon.awssdk/http-auth-aws/2.42.34, Apache-2.0, approved, #26496 -maven/mavencentral/software.amazon.awssdk/http-auth-spi/2.42.34, Apache-2.0, approved, #26497 -maven/mavencentral/software.amazon.awssdk/http-auth/2.42.34, Apache-2.0, approved, #26498 -maven/mavencentral/software.amazon.awssdk/http-client-spi/2.42.34, Apache-2.0, approved, #26499 -maven/mavencentral/software.amazon.awssdk/iam/2.42.34, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/identity-spi/2.42.34, Apache-2.0, approved, #26500 -maven/mavencentral/software.amazon.awssdk/json-utils/2.42.34, Apache-2.0, approved, #26501 -maven/mavencentral/software.amazon.awssdk/metrics-spi/2.42.34, Apache-2.0, approved, #26502 -maven/mavencentral/software.amazon.awssdk/netty-nio-client/2.42.34, Apache-2.0, approved, #26503 -maven/mavencentral/software.amazon.awssdk/profiles/2.42.34, Apache-2.0, approved, #26504 -maven/mavencentral/software.amazon.awssdk/protocol-core/2.42.34, Apache-2.0, approved, #26505 -maven/mavencentral/software.amazon.awssdk/regions/2.42.34, Apache-2.0, approved, #26506 -maven/mavencentral/software.amazon.awssdk/retries-spi/2.42.34, Apache-2.0, approved, #26507 -maven/mavencentral/software.amazon.awssdk/retries/2.42.34, Apache-2.0, approved, #26508 -maven/mavencentral/software.amazon.awssdk/s3/2.42.34, Apache-2.0, approved, #26510 -maven/mavencentral/software.amazon.awssdk/sdk-core/2.42.34, Apache-2.0, approved, #26511 -maven/mavencentral/software.amazon.awssdk/sts/2.42.34, Apache-2.0, approved, #27697 -maven/mavencentral/software.amazon.awssdk/third-party-jackson-core/2.42.34, Apache-2.0, approved, #26512 -maven/mavencentral/software.amazon.awssdk/utils-lite/2.42.34, Apache-2.0, approved, #26513 -maven/mavencentral/software.amazon.awssdk/utils/2.42.34, Apache-2.0, approved, #26514 -maven/mavencentral/software.amazon.eventstream/eventstream/1.0.1, Apache-2.0, approved, #19691 -maven/mavencentral/tools.jackson.core/jackson-core/3.1.5, Apache-2.0 AND MIT, approved, #26415 -maven/mavencentral/tools.jackson.core/jackson-databind/3.1.5, Apache-2.0, approved, #26439 -maven/mavencentral/tools.jackson/jackson-bom/3.1.5, Apache-2.0, approved, #26520 From c4a24a6f88ef8af04a1b12fc980f8e5867ff9082 Mon Sep 17 00:00:00 2001 From: eclipse-tractusx-bot Date: Thu, 27 Aug 2026 07:45:04 +0000 Subject: [PATCH 256/259] Prepare release 0.13.0 --- charts/tractusx-connector-memory/Chart.yaml | 4 ++-- charts/tractusx-connector-memory/README.md | 4 ++-- charts/tractusx-connector/Chart.yaml | 4 ++-- charts/tractusx-connector/README.md | 4 ++-- gradle.properties | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/charts/tractusx-connector-memory/Chart.yaml b/charts/tractusx-connector-memory/Chart.yaml index 4ffc44acce..66f45f6f9e 100644 --- a/charts/tractusx-connector-memory/Chart.yaml +++ b/charts/tractusx-connector-memory/Chart.yaml @@ -35,12 +35,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.13.0-rc4 +version: 0.13.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.13.0-rc4" +appVersion: "0.13.0" home: https://github.com/eclipse-tractusx/tractusx-edc/tree/main/charts/tractusx-connector-memory sources: - https://github.com/eclipse-tractusx/tractusx-edc/tree/main/charts/tractusx-connector-memory diff --git a/charts/tractusx-connector-memory/README.md b/charts/tractusx-connector-memory/README.md index 8ad0728c11..ea04bc239e 100644 --- a/charts/tractusx-connector-memory/README.md +++ b/charts/tractusx-connector-memory/README.md @@ -1,6 +1,6 @@ # tractusx-connector-memory -![Version: 0.13.0-rc4](https://img.shields.io/badge/Version-0.13.0--rc4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.13.0-rc4](https://img.shields.io/badge/AppVersion-0.13.0--rc4-informational?style=flat-square) +![Version: 0.13.0](https://img.shields.io/badge/Version-0.13.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.13.0](https://img.shields.io/badge/AppVersion-0.13.0-informational?style=flat-square) A Helm chart for Tractus-X Eclipse Data Space Connector based on memory. Please only use this for development or testing purposes, never in production workloads! @@ -41,7 +41,7 @@ Combined, run this shell command to start the in-memory Tractus-X EDC runtime: ```shell helm repo add tractusx-edc https://eclipse-tractusx.github.io/charts/dev -helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0-rc4 \ +helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0 \ -f /tractusx-connector-memory-test.yaml \ --set vault.secrets="client-secret:$YOUR_CLIENT_SECRET" ``` diff --git a/charts/tractusx-connector/Chart.yaml b/charts/tractusx-connector/Chart.yaml index 35312c6a16..730880e58e 100644 --- a/charts/tractusx-connector/Chart.yaml +++ b/charts/tractusx-connector/Chart.yaml @@ -41,12 +41,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.13.0-rc4 +version: 0.13.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.13.0-rc4" +appVersion: "0.13.0" home: https://github.com/eclipse-tractusx/tractusx-edc/tree/main/charts/tractusx-connector sources: - https://github.com/eclipse-tractusx/tractusx-edc/tree/main/charts/tractusx-connector diff --git a/charts/tractusx-connector/README.md b/charts/tractusx-connector/README.md index ba55d65c8a..cb60fbbcf3 100644 --- a/charts/tractusx-connector/README.md +++ b/charts/tractusx-connector/README.md @@ -1,6 +1,6 @@ # tractusx-connector -![Version: 0.13.0-rc4](https://img.shields.io/badge/Version-0.13.0--rc4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.13.0-rc4](https://img.shields.io/badge/AppVersion-0.13.0--rc4-informational?style=flat-square) +![Version: 0.13.0](https://img.shields.io/badge/Version-0.13.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.13.0](https://img.shields.io/badge/AppVersion-0.13.0-informational?style=flat-square) A Helm chart for Tractus-X Eclipse Data Space Connector. The connector deployment consists of two runtime consists of a Control Plane and a Data Plane. Note that _no_ external dependencies such as a PostgreSQL database and HashiCorp Vault are included. @@ -102,7 +102,7 @@ Combined, run this shell command to start the in-memory Tractus-X EDC runtime: ```shell helm repo add tractusx-edc https://eclipse-tractusx.github.io/charts/dev -helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-rc4 \ +helm install my-release tractusx-edc/tractusx-connector --version 0.13.0 \ -f /tractusx-connector-test.yaml ``` diff --git a/gradle.properties b/gradle.properties index 32814c9fcd..b8d3c55b90 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group=org.eclipse.tractusx.edc -version=0.13.0-rc4 +version=0.13.0 # configure the build: txScmConnection=scm:git:git@github.com:eclipse-tractusx/tractusx-edc.git txWebsiteUrl=https://github.com/eclipse-tractusx/tractusx-edc.git From 964d33d7ed942369f624aacbc45037a1f79fc7be Mon Sep 17 00:00:00 2001 From: eclipse-tractusx-bot Date: Thu, 27 Aug 2026 07:47:37 +0000 Subject: [PATCH 257/259] Update DEPENDENCIES file --- DEPENDENCIES | 483 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 483 insertions(+) diff --git a/DEPENDENCIES b/DEPENDENCIES index e69de29bb2..1ec6e531c6 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -0,0 +1,483 @@ +maven/mavencentral/com.apicatalog/carbon-did/0.3.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.apicatalog/copper-multibase/0.5.0, Apache-2.0, approved, #14501 +maven/mavencentral/com.apicatalog/copper-multicodec/0.1.1, Apache-2.0, approved, #14500 +maven/mavencentral/com.apicatalog/iron-ed25519-cryptosuite-2020/0.14.0, Apache-2.0, approved, #14503 +maven/mavencentral/com.apicatalog/iron-verifiable-credentials/0.14.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.apicatalog/titanium-jcs/1.1.1, Apache-2.0, approved, #25093 +maven/mavencentral/com.apicatalog/titanium-json-ld/1.0.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.apicatalog/titanium-json-ld/1.4.0, Apache-2.0, approved, #15200 +maven/mavencentral/com.apicatalog/titanium-json-ld/1.7.0, Apache-2.0, approved, #25089 +maven/mavencentral/com.apicatalog/titanium-rdf-api/1.0.0, Apache-2.0, approved, #20245 +maven/mavencentral/com.apicatalog/titanium-rdf-n-quads/1.0.2, Apache-2.0, approved, #20243 +maven/mavencentral/com.azure/azure-core-http-netty/1.15.11, MIT AND Apache-2.0, approved, #16697 +maven/mavencentral/com.azure/azure-core-http-netty/1.16.3, MIT AND Apache-2.0, approved, #29562 +maven/mavencentral/com.azure/azure-core/1.55.3, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-core/1.57.1, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-identity/1.18.2, MIT, approved, #29561 +maven/mavencentral/com.azure/azure-json/1.4.0, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-json/1.5.1, MIT AND Apache-2.0, approved, #26444 +maven/mavencentral/com.azure/azure-storage-blob/12.30.0, MIT, approved, #20441 +maven/mavencentral/com.azure/azure-storage-common/12.29.0, MIT, approved, #20440 +maven/mavencentral/com.azure/azure-storage-internal-avro/12.15.0, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-xml/1.2.0, Apache-2.0, approved, #26447 +maven/mavencentral/com.azure/azure-xml/1.2.1, Apache-2.0, approved, #26447 +maven/mavencentral/com.ethlo.time/itu/1.14.0, Apache-2.0, approved, #19505 +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.18.4, Apache-2.0, approved, #16364 +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.19.1, Apache-2.0, approved, #21911 +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.19.2, Apache-2.0, approved, #21911 +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.21, Apache-2.0, approved, #25587 +maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.18.4.1, Apache-2.0 AND MIT, approved, #16371 +maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.21.4, Apache-2.0 AND MIT, approved, #25590 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.18.3, Apache-2.0, approved, #16372 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.18.4, Apache-2.0, approved, #16372 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.19.1, Apache-2.0, approved, #21909 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.19.2, Apache-2.0, approved, #21909 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.21.2, Apache-2.0, approved, #25591 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.21.4, Apache-2.0, approved, #25591 +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.18.3, Apache-2.0, approved, #16370 +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.19.2, Apache-2.0, approved, #21912 +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml/2.21.4, Apache-2.0, approved, #25589 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jakarta-jsonp/2.21.2, Apache-2.0, approved, #26448 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jakarta-jsonp/2.21.4, Apache-2.0, approved, #26448 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.18.4, Apache-2.0, approved, #16625 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.19.2, Apache-2.0, approved, #23299 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.21.2, Apache-2.0, approved, #26441 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.21.4, Apache-2.0, approved, #26441 +maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-base/2.21.4, Apache-2.0, approved, #26442 +maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.19.2, Apache-2.0, approved, #20839 +maven/mavencentral/com.fasterxml.jackson.jakarta.rs/jackson-jakarta-rs-json-provider/2.21.4, Apache-2.0, approved, #26443 +maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.19.1, Apache-2.0, approved, #21910 +maven/mavencentral/com.fasterxml.jackson.module/jackson-module-jakarta-xmlbind-annotations/2.21.4, Apache-2.0, approved, #25588 +maven/mavencentral/com.fasterxml.jackson/jackson-bom/2.21.4, Apache-2.0, approved, #26451 +maven/mavencentral/com.google.code.findbugs/jsr305/3.0.2, Apache-2.0 and CC-BY-2.5, approved, #15220 +maven/mavencentral/com.google.code.gson/gson/2.13.2, Apache-2.0, approved, #20656 +maven/mavencentral/com.google.crypto.tink/tink/1.20.0, Apache-2.0, approved, #28384 +maven/mavencentral/com.google.errorprone/error_prone_annotations/2.41.0, Apache-2.0, approved, #22631 +maven/mavencentral/com.google.protobuf/protobuf-java/4.33.0, BSD-3-Clause, approved, #29831 +maven/mavencentral/com.microsoft.azure/msal4j-persistence-extension/1.3.0, MIT, approved, #14411 +maven/mavencentral/com.microsoft.azure/msal4j/1.15.0, MIT, approved, clearlydefined +maven/mavencentral/com.microsoft.azure/msal4j/1.23.1, MIT, approved, clearlydefined +maven/mavencentral/com.networknt/json-schema-validator/2.0.0, Apache-2.0 AND Unicode-TOU, approved, #25988 +maven/mavencentral/com.nimbusds/nimbus-jose-jwt/10.8, Apache-2.0, approved, #26455 +maven/mavencentral/com.nimbusds/nimbus-jose-jwt/10.9.1, Apache-2.0, approved, #29000 +maven/mavencentral/com.squareup.okhttp3/okhttp-dnsoverhttps/5.3.2, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okhttp3/okhttp-jvm/5.3.2, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okhttp3/okhttp-jvm/5.4.0, Apache-2.0, approved, #29005 +maven/mavencentral/com.squareup.okhttp3/okhttp/4.9.3, Apache-2.0 AND MPL-2.0, approved, #3225 +maven/mavencentral/com.squareup.okhttp3/okhttp/5.3.2, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okhttp3/okhttp/5.4.0, Apache-2.0, approved, #29015 +maven/mavencentral/com.squareup.okio/okio-jvm/3.16.4, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okio/okio-jvm/3.17.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okio/okio/3.16.4, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.squareup.okio/okio/3.17.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/commons-codec/commons-codec/1.11, Apache-2.0 AND BSD-3-Clause, approved, CQ15971 +maven/mavencentral/commons-codec/commons-codec/1.17.1, Apache-2.0 AND (Apache-2.0 AND BSD-3-Clause), approved, #14583 +maven/mavencentral/commons-logging/commons-logging/1.2, Apache-2.0, approved, CQ10162 +maven/mavencentral/dev.failsafe/failsafe-okhttp/3.3.2, Apache-2.0, approved, #15208 +maven/mavencentral/dev.failsafe/failsafe/3.3.2, Apache-2.0, approved, #9268 +maven/mavencentral/io.github.classgraph/classgraph/4.8.184, MIT, approved, CQ22530 +maven/mavencentral/io.micrometer/micrometer-commons/1.16.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #24726 +maven/mavencentral/io.micrometer/micrometer-core/1.16.4, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #24722 +maven/mavencentral/io.micrometer/micrometer-observation/1.16.4, Apache-2.0, approved, #24713 +maven/mavencentral/io.netty/netty-bom/4.1.137.Final, Apache-2.0, approved, #30531 +maven/mavencentral/io.netty/netty-buffer/4.1.130.Final, Apache-2.0, approved, CQ21842 +maven/mavencentral/io.netty/netty-buffer/4.1.132.Final, Apache-2.0, approved, CQ21842 +maven/mavencentral/io.netty/netty-buffer/4.1.137.Final, Apache-2.0, approved, CQ21842 +maven/mavencentral/io.netty/netty-codec-dns/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-socks/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-common/4.1.130.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-common/4.1.132.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-common/4.1.137.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-handler-proxy/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler-proxy/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler-proxy/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver-dns-classes-macos/4.1.137.Final, Apache-2.0, approved, #6367 +maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.128.Final, Apache-2.0, approved, #7004 +maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.137.Final, Apache-2.0, approved, #7004 +maven/mavencentral/io.netty/netty-resolver-dns/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver-dns/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.74.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 +maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.81.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 +maven/mavencentral/io.netty/netty-tcnative-classes/2.0.81.Final, Apache-2.0, approved, #23398 +maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.132.Final, Apache-2.0, approved, #6366 +maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.137.Final, Apache-2.0, approved, #6366 +maven/mavencentral/io.netty/netty-transport-classes-kqueue/4.1.137.Final, Apache-2.0, approved, #4107 +maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.128.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.130.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport/4.1.132.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport/4.1.137.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-annotations/1.32.0, Apache-2.0, approved, #11684 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-annotations/2.30.0, Apache-2.0, approved, #30125 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-api-incubator/2.30.0-alpha, Apache-2.0, approved, #30532 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-instrumentation-api/2.30.0, Apache-2.0, approved, #30533 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-log4j-appender-2.17/2.30.0-alpha, Apache-2.0, approved, #30534 +maven/mavencentral/io.opentelemetry.instrumentation/opentelemetry-log4j-context-data-2.17-autoconfigure/2.30.0-alpha, Apache-2.0, approved, #30535 +maven/mavencentral/io.opentelemetry.semconv/opentelemetry-semconv/1.43.0, Apache-2.0, approved, #30446 +maven/mavencentral/io.opentelemetry/opentelemetry-api-incubator/1.64.0-alpha, Apache-2.0, approved, #30536 +maven/mavencentral/io.opentelemetry/opentelemetry-api/1.32.0, Apache-2.0, approved, #11682 +maven/mavencentral/io.opentelemetry/opentelemetry-api/1.61.0, Apache-2.0, approved, #29641 +maven/mavencentral/io.opentelemetry/opentelemetry-api/1.64.0, Apache-2.0, approved, #29872 +maven/mavencentral/io.opentelemetry/opentelemetry-common/1.64.0, Apache-2.0, approved, #29870 +maven/mavencentral/io.opentelemetry/opentelemetry-context/1.64.0, Apache-2.0, approved, #29871 +maven/mavencentral/io.projectreactor.netty/reactor-netty-core/1.2.13, Apache-2.0, approved, #23393 +maven/mavencentral/io.projectreactor.netty/reactor-netty-http/1.2.13, Apache-2.0, approved, #23394 +maven/mavencentral/io.projectreactor/reactor-core/3.7.14, Apache-2.0, approved, #17529 +maven/mavencentral/io.setl/rdf-urdna/1.1, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.swagger.core.v3/swagger-annotations-jakarta/2.2.42, Apache-2.0, approved, #5947 +maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.42, Apache-2.0, approved, #5929 +maven/mavencentral/io.swagger.core.v3/swagger-integration-jakarta/2.2.42, Apache-2.0, approved, #11475 +maven/mavencentral/io.swagger.core.v3/swagger-jaxrs2-jakarta/2.2.42, Apache-2.0, approved, #11477 +maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.42, Apache-2.0, approved, #5919 +maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.3, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf +maven/mavencentral/jakarta.annotation/jakarta.annotation-api/3.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca +maven/mavencentral/jakarta.inject/jakarta.inject-api/2.0.1, Apache-2.0, approved, ee4j.cdi +maven/mavencentral/jakarta.json/jakarta.json-api/2.1.3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp +maven/mavencentral/jakarta.servlet/jakarta.servlet-api/6.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.servlet +maven/mavencentral/jakarta.servlet/jakarta.servlet-api/6.1.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.servlet +maven/mavencentral/jakarta.validation/jakarta.validation-api/3.0.2, Apache-2.0, approved, ee4j.validation +maven/mavencentral/jakarta.validation/jakarta.validation-api/3.1.0, Apache-2.0, approved, ee4j.validation +maven/mavencentral/jakarta.ws.rs/jakarta.ws.rs-api/4.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.rest +maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/3.0.1, BSD-3-Clause, approved, ee4j.jaxb +maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/4.0.2, BSD-3-Clause, approved, ee4j.jaxb +maven/mavencentral/net.java.dev.jna/jna-platform/5.13.0, Apache-2.0 OR LGPL-2.1-or-later, approved, #6707 +maven/mavencentral/net.java.dev.jna/jna-platform/5.17.0, Apache-2.0 OR LGPL-2.1-or-later, approved, #20116 +maven/mavencentral/net.java.dev.jna/jna/5.13.0, Apache-2.0 AND LGPL-2.1-or-later, approved, #15196 +maven/mavencentral/net.java.dev.jna/jna/5.17.0, Apache-2.0 AND LGPL-2.1-or-later, approved, #20112 +maven/mavencentral/org.apache.commons/commons-lang3/3.18.0, Apache-2.0, approved, #22470 +maven/mavencentral/org.apache.commons/commons-pool2/2.13.1, Apache-2.0 AND CC-PDDC, approved, #25941 +maven/mavencentral/org.apache.httpcomponents/httpclient/4.5.13, Apache-2.0, approved, #15248 +maven/mavencentral/org.apache.httpcomponents/httpcore/4.4.13, Apache-2.0, approved, CQ23528 +maven/mavencentral/org.apache.httpcomponents/httpcore/4.4.16, Apache-2.0, approved, CQ23528 +maven/mavencentral/org.apache.logging.log4j/log4j-api/2.26.1, Apache-2.0, approved, #27998 +maven/mavencentral/org.apache.logging.log4j/log4j-core/2.26.1, Apache-2.0 AND (Apache-2.0 AND LGPL-2.0-or-later), approved, #28001 +maven/mavencentral/org.apache.logging.log4j/log4j-layout-template-json/2.26.1, Apache-2.0, approved, clearlydefined +maven/mavencentral/org.bouncycastle/bcpkix-jdk18on/1.84, MIT, approved, #27142 +maven/mavencentral/org.bouncycastle/bcprov-jdk18on/1.84, MIT AND CC0-1.0, approved, #27143 +maven/mavencentral/org.bouncycastle/bcutil-jdk18on/1.84, MIT, approved, #27144 +maven/mavencentral/org.checkerframework/checker-qual/3.55.1, MIT, approved, #29939 +maven/mavencentral/org.eclipse.edc.aws/aws-s3-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.aws/aws-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.aws/data-plane-aws-s3/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.aws/data-plane-provision-aws-s3/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.aws/validator-data-address-s3/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.azure/azure-blob-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.azure/data-plane-azure-storage/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc.azure/data-plane-provision-blob/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/accesstokendata-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/api-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/api-observability/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/asset-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/asset-index-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/asset-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-delegated/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-tokenbased/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/boot-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/boot-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/boot/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/callback-event-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/callback-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/callback-static-endpoint/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/catalog-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/catalog-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/cel-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/configuration-filesystem/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/connector-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/connector-participant-context-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/console-monitor/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-agreement-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-definition-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-definition-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-negotiation-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-negotiation-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-api-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-aggregate-services/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-api-client/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-catalog/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-contract-manager/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-contract/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-policies-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-transfer-manager/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-transfer-provision-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-transfer/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-transform/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/controlplane-base-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/controlplane-dcp-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/controlplane-feature-sql-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/core-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/crawler-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/crypto-common-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-address-http-data-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http-oauth2-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http-oauth2/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-iam/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-instance-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-client/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-control-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-self-registration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-signaling-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-signaling-client/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-signaling-transform/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dataplane-base-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dataplane-feature-sql-bom/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-issuers-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-service/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-sts-remote-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-claims-transform/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/decentralized-identity/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-transform-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-catalog-validation-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-api-base-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-api-configuration-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-dispatcher-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-http-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-transform-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-negotiation-validation-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-spi-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-api-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-http-dispatcher/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-transform-2025/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-transfer-process-validation-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-version-http-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-version-transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp-version/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/dsp/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/edr-index-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/edr-store-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/edr-store-receiver/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/edr-store-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/encryption-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/encryption-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/federated-catalog-cache-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/federated-catalog-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/holder-credential-request-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/http-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/http-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/http/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/identity-did-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/identity-did-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/identity-did-web/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jersey-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jersey-micrometer/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jersey-providers-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jetty-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jetty-micrometer/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/json-ld-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/json-ld-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/json-ld/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/json-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jti-validation-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jws2020-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jwt-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jwt-verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/keys-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/keys-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/ldp-verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/management-api-configuration/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/management-api-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/management-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/micrometer-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/oauth2-client/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/oauth2-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-config-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-config-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-connector-classic-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-connector-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-single-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-context-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/participant-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-definition-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-definition-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-engine-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-engine-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-evaluator-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-model/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-monitor-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-monitor-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-monitor-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/protocol-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/query-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/request-policy-context-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/runtime-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/runtime-metamodel/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/secrets-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-bootstrapper/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-lease-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-lease-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-lease/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-pool-apache-commons/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/state-machine-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/store-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/token-core/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/token-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/token-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-datasource-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-local/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-data-plane-signaling/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-process-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-process-store-sql/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transform-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transform-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/util-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/validator-data-address-http-data/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/validator-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/validator-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/vault-hashicorp-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/vault-hashicorp/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/verifiable-credential-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/verifiable-credentials-lib/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/verifiable-credentials-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/verifiable-credentials/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/version-api/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/web-spi/0.17.0, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.jetty.ee10/jetty-ee10-bom/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty.ee10/jetty-ee10-servlet/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty.ee10/jetty-ee10-servlet/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty.websocket/jetty-websocket/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty.websocket/jetty-websocket/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-bom/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-http/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-http/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-io/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-security/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-server/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-server/12.1.7, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-session/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.jetty/jetty-util/12.1.10, EPL-2.0 OR Apache-2.0, approved, rt.jetty +maven/mavencentral/org.eclipse.parsson/parsson/1.1.7, EPL-2.0, approved, ee4j.parsson +maven/mavencentral/org.flywaydb/flyway-core/13.3.0, Apache-2.0, approved, #30537 +maven/mavencentral/org.flywaydb/flyway-database-cockroachdb/13.3.0, Apache-2.0, approved, #30538 +maven/mavencentral/org.flywaydb/flyway-database-postgresql/13.3.0, Apache-2.0, approved, #30539 +maven/mavencentral/org.glassfish.hk2.external/aopalliance-repackaged/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.hk2/hk2-api/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.hk2/hk2-locator/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.hk2/hk2-utils/4.0.0-M3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.hk2/osgi-resource-locator/3.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.glassfish +maven/mavencentral/org.glassfish.jersey.containers/jersey-container-servlet/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.core/jersey-client/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.core/jersey-common/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.core/jersey-server/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.ext/jersey-entity-filtering/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.inject/jersey-hk2/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.media/jersey-media-json-jackson/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish.jersey.media/jersey-media-multipart/4.0.2, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jersey +maven/mavencentral/org.glassfish/jakarta.json/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp +maven/mavencentral/org.hdrhistogram/HdrHistogram/2.2.2, BSD-2-Clause AND CC0-1.0 AND CC0-1.0, approved, #14828 +maven/mavencentral/org.javassist/javassist/3.30.2-GA, Apache-2.0 AND LGPL-2.1-or-later AND MPL-1.1, approved, #12108 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.1.21, Apache-2.0, approved, #17634 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.2.20, Apache-2.0, approved, #22410 +maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/2.2.21, Apache-2.0, approved, #22410 +maven/mavencentral/org.jetbrains/annotations/13.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/org.jetbrains/annotations/26.1.0, Apache-2.0, approved, #26477 +maven/mavencentral/org.jspecify/jspecify/1.0.0, Apache-2.0, approved, #21897 +maven/mavencentral/org.jvnet.mimepull/mimepull/1.9.15, CDDL-1.1 OR GPL-2.0-only WITH Classpath-exception-2.0, approved, CQ21484 +maven/mavencentral/org.latencyutils/LatencyUtils/2.0.3, CC0-1.0, approved, #15280 +maven/mavencentral/org.postgresql/postgresql/42.7.10, BSD-2-Clause AND Apache-2.0, approved, #11681 +maven/mavencentral/org.postgresql/postgresql/42.7.13, BSD-2-Clause AND Apache-2.0, approved, #11681 +maven/mavencentral/org.reactivestreams/reactive-streams/1.0.4, CC0-1.0, approved, CQ16332 +maven/mavencentral/org.slf4j/slf4j-api/1.7.36, MIT, approved, CQ13368 +maven/mavencentral/org.slf4j/slf4j-api/1.7.7, MIT, approved, CQ9827 +maven/mavencentral/org.slf4j/slf4j-api/2.0.17, MIT, approved, #5915 +maven/mavencentral/org.slf4j/slf4j-api/2.0.18, MIT, approved, #5915 +maven/mavencentral/org.slf4j/slf4j-api/2.0.9, MIT, approved, #5915 +maven/mavencentral/org.yaml/snakeyaml/2.3, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #16046 +maven/mavencentral/org.yaml/snakeyaml/2.5, Apache-2.0, approved, #23100 +maven/mavencentral/software.amazon.awssdk/annotations/2.42.34, Apache-2.0, approved, #26484 +maven/mavencentral/software.amazon.awssdk/apache-client/2.42.34, Apache-2.0, approved, #26485 +maven/mavencentral/software.amazon.awssdk/arns/2.42.34, Apache-2.0, approved, #26486 +maven/mavencentral/software.amazon.awssdk/auth/2.42.34, Apache-2.0, approved, #26487 +maven/mavencentral/software.amazon.awssdk/aws-core/2.42.34, Apache-2.0, approved, #26488 +maven/mavencentral/software.amazon.awssdk/aws-query-protocol/2.42.34, Apache-2.0, approved, #26489 +maven/mavencentral/software.amazon.awssdk/aws-xml-protocol/2.42.34, Apache-2.0, approved, #26490 +maven/mavencentral/software.amazon.awssdk/checksums-spi/2.42.34, Apache-2.0, approved, #26491 +maven/mavencentral/software.amazon.awssdk/checksums/2.42.34, Apache-2.0, approved, #26492 +maven/mavencentral/software.amazon.awssdk/crt-core/2.42.34, Apache-2.0, approved, #26493 +maven/mavencentral/software.amazon.awssdk/endpoints-spi/2.42.34, Apache-2.0, approved, #26494 +maven/mavencentral/software.amazon.awssdk/http-auth-aws-eventstream/2.42.34, Apache-2.0, approved, #26495 +maven/mavencentral/software.amazon.awssdk/http-auth-aws/2.42.34, Apache-2.0, approved, #26496 +maven/mavencentral/software.amazon.awssdk/http-auth-spi/2.42.34, Apache-2.0, approved, #26497 +maven/mavencentral/software.amazon.awssdk/http-auth/2.42.34, Apache-2.0, approved, #26498 +maven/mavencentral/software.amazon.awssdk/http-client-spi/2.42.34, Apache-2.0, approved, #26499 +maven/mavencentral/software.amazon.awssdk/iam/2.42.34, Apache-2.0, approved, #30540 +maven/mavencentral/software.amazon.awssdk/identity-spi/2.42.34, Apache-2.0, approved, #26500 +maven/mavencentral/software.amazon.awssdk/json-utils/2.42.34, Apache-2.0, approved, #26501 +maven/mavencentral/software.amazon.awssdk/metrics-spi/2.42.34, Apache-2.0, approved, #26502 +maven/mavencentral/software.amazon.awssdk/netty-nio-client/2.42.34, Apache-2.0, approved, #26503 +maven/mavencentral/software.amazon.awssdk/profiles/2.42.34, Apache-2.0, approved, #26504 +maven/mavencentral/software.amazon.awssdk/protocol-core/2.42.34, Apache-2.0, approved, #26505 +maven/mavencentral/software.amazon.awssdk/regions/2.42.34, Apache-2.0, approved, #26506 +maven/mavencentral/software.amazon.awssdk/retries-spi/2.42.34, Apache-2.0, approved, #26507 +maven/mavencentral/software.amazon.awssdk/retries/2.42.34, Apache-2.0, approved, #26508 +maven/mavencentral/software.amazon.awssdk/s3/2.42.34, Apache-2.0, approved, #26510 +maven/mavencentral/software.amazon.awssdk/sdk-core/2.42.34, Apache-2.0, approved, #26511 +maven/mavencentral/software.amazon.awssdk/sts/2.42.34, Apache-2.0, approved, #27697 +maven/mavencentral/software.amazon.awssdk/third-party-jackson-core/2.42.34, Apache-2.0, approved, #26512 +maven/mavencentral/software.amazon.awssdk/utils-lite/2.42.34, Apache-2.0, approved, #26513 +maven/mavencentral/software.amazon.awssdk/utils/2.42.34, Apache-2.0, approved, #26514 +maven/mavencentral/software.amazon.eventstream/eventstream/1.0.1, Apache-2.0, approved, #19691 +maven/mavencentral/tools.jackson.core/jackson-core/3.1.5, Apache-2.0 AND MIT, approved, #26415 +maven/mavencentral/tools.jackson.core/jackson-databind/3.1.5, Apache-2.0, approved, #26439 +maven/mavencentral/tools.jackson/jackson-bom/3.1.5, Apache-2.0, approved, #26520 From d0f5e35d426f553167c4d4812053de962bff5020 Mon Sep 17 00:00:00 2001 From: Ernst-Christoph Schrewe Date: Tue, 1 Sep 2026 12:45:25 +0200 Subject: [PATCH 258/259] chore: update tx 0.13.0 --- .../build.gradle.kts | 7 +-- .../build.gradle.kts | 7 +-- .../environments/local-con-x-env.bru | 30 ++++++------ .../local/docker-compose.yaml | 36 +++----------- .../build.gradle.kts | 5 +- .../build.gradle.kts | 5 +- .../README.md | 8 +++ .../build.gradle.kts | 37 ++++++++++++++ ...ementRetirementBootstrappingExtension.java | 49 +++++++++++++++++++ ...rg.eclipse.edc.spi.system.ServiceExtension | 20 ++++++++ ..._0_1__Init_ContractAgreementRetirement.sql | 22 +++++++++ .../src/test/java/SqlVaultTest.java | 22 +++++++++ edc-extensions/sql-vault/build.gradle.kts | 2 +- gradle.properties | 4 ++ settings.gradle.kts | 1 + 15 files changed, 199 insertions(+), 56 deletions(-) create mode 100644 edc-extensions/agreements/retirement-evaluation-bootstrapping/README.md create mode 100644 edc-extensions/agreements/retirement-evaluation-bootstrapping/build.gradle.kts create mode 100644 edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/java/de/fraunhofer/isst/edc/extension/retirement_bootstrapper/dev/AgreementRetirementBootstrappingExtension.java create mode 100644 edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/resources/V0_0_1__Init_ContractAgreementRetirement.sql create mode 100644 edc-extensions/agreements/retirement-evaluation-bootstrapping/src/test/java/SqlVaultTest.java diff --git a/edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-hashicorp-vault/build.gradle.kts b/edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-hashicorp-vault/build.gradle.kts index 8349f2fc7c..d134388293 100644 --- a/edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-hashicorp-vault/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-hashicorp-vault/build.gradle.kts @@ -25,9 +25,10 @@ plugins { alias(libs.plugins.shadow) } +val edcVersion = project.property("con-x-edcVersion") as String +val txVersion = project.property("version") as String + dependencies { - val edcVersion = "0.15.1" - val txVersion = "0.12.0" implementation("org.eclipse.edc:controlplane-dcp-bom:$edcVersion") implementation("org.eclipse.edc:controlplane-feature-sql-bom:$edcVersion") @@ -35,7 +36,7 @@ dependencies { implementation("org.eclipse.tractusx.edc:agreements:$txVersion") implementation("org.eclipse.tractusx.edc:retirement-evaluation-store-sql:$txVersion") - implementation("org.eclipse.tractusx.edc:control-plane-migration:$txVersion") + implementation(project(":edc-extensions:agreements:retirement-evaluation-bootstrapping")) implementation("org.eclipse.tractusx.edc:tx-dcp:$txVersion") } diff --git a/edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-vault/build.gradle.kts b/edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-vault/build.gradle.kts index d0cd959721..8817f7ff78 100644 --- a/edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-vault/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-vault/build.gradle.kts @@ -25,9 +25,10 @@ plugins { alias(libs.plugins.shadow) } +val edcVersion = project.property("con-x-edcVersion") as String +val txVersion = project.property("version") as String + dependencies { - val edcVersion = "0.15.1" - val txVersion = "0.12.0" implementation("org.eclipse.edc:controlplane-dcp-bom:$edcVersion") implementation("org.eclipse.edc:controlplane-feature-sql-bom:$edcVersion") @@ -35,7 +36,7 @@ dependencies { implementation("org.eclipse.tractusx.edc:agreements:$txVersion") implementation("org.eclipse.tractusx.edc:retirement-evaluation-store-sql:$txVersion") - implementation("org.eclipse.tractusx.edc:control-plane-migration:$txVersion") + implementation(project(":edc-extensions:agreements:retirement-evaluation-bootstrapping")) implementation("org.eclipse.tractusx.edc:tx-dcp:$txVersion") } diff --git a/edc-controlplane/edc-controlplane-construct-x/local/bruno/con-x-local-test/environments/local-con-x-env.bru b/edc-controlplane/edc-controlplane-construct-x/local/bruno/con-x-local-test/environments/local-con-x-env.bru index df66b443df..16365f6d63 100644 --- a/edc-controlplane/edc-controlplane-construct-x/local/bruno/con-x-local-test/environments/local-con-x-env.bru +++ b/edc-controlplane/edc-controlplane-construct-x/local/bruno/con-x-local-test/environments/local-con-x-env.bru @@ -6,12 +6,12 @@ vars { CONSUMER_IDHUB_ID_API: http://localhost:20100/api/identity CONSUMER_IDHUB_STS_API: http://localhost:20500/api/sts CONSUMER_IDHUB_CREDS_API: http://localhost:20600/api/credentials - ISSUER_APIKEY: ZGlkOndlYjpsb2NhbC1pc3N1ZXItc2VydmljZTpmeC1pc3N1ZXI=.CmYgVcuzneJXqzcbj7vmld5feejy6OguIylflSrz6WTjG1HNQRvO62EafFrQjS/lVlZAwiwz2rwwZgXrbpyhcg== - CONSUMER_IH_APIKEY: ZGlkOndlYjpsb2NhbC11c2VyLWlkaHViOnVzZXI6Y29uc3VtZXI=.ObFly02OtymUNRE43uH9SblWVtsZH0NMddgm1dFYQXRekO3qXX+rHFV7NvM+DUW3lcA2PbILt5rwWYEqm7WNgw== - PROVIDER_IH_APIKEY: ZGlkOndlYjpsb2NhbC11c2VyLWlkaHViOnVzZXI6cHJvdmlkZXI=.Knip+hedL63qedBQfOvZhhrF2ooSCfP2YgjONvtmehofor2ejdw/en0MAXDBZEcXrCwYNppDMNFDsRlG5rB/Mw== + ISSUER_APIKEY: Y29uLXgtaXNzdWVy.P3ROSh354pDFG8vOq4DB+lChxi4A6vIcbI/07UvwnKTIKl43pousUO0hu5fH28YnuQzbVF1meRBWjKU55/PT/g== + CONSUMER_IH_APIKEY: dXNlci1jb25zdW1lcg==.dMQICllhhPpgGtJBMWn2uKnH4+lkLAAD2PcPjn6iAIlMKBXUPmFHShj+HNYUDOY4zPQqwqBZ+cki4Mhtu7oyvw== + PROVIDER_IH_APIKEY: dXNlci1wcm92aWRlcg==.cdX1+2gWJtn9LKO/z2wkYwuybBhBRTQmFw5Se0CSvFq8ZEPSaDjskG15nmUx0iFKfXYEDase6yTEVlqQKoleQQ== VAULTURL: http://localhost:8200 - CONSUMER_STS_SECRET: VD0q6jOEyslSeFV2 - PROVIDER_STS_SECRET: XjDk9ncaJSrSfkQW + CONSUMER_STS_SECRET: fGznFfHH2skwmCJ4 + PROVIDER_STS_SECRET: DA9ujfJuoWgPPafQ PROVIDER_MANAGEMENT: http://localhost:39010/management CONSUMER_MANAGEMENT: http://localhost:29010/management PROVIDER_DATAPLANE_PUBLIC: http://localhost:9500/public @@ -22,14 +22,14 @@ vars { ISS_ID: did:web:local-issuer-wallet:con-x-issuer CONS_ID: did:web:consumer-wallet:user:consumer PROV_ID: did:web:provider-wallet:user:provider - cons_access_token: eyJraWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIja2V5LTEiLCJhbGciOiJFZDI1NTE5In0.eyJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIiLCJuYmYiOjE3NzAyNzg5NTQsInNjb3BlIjoib3JnLmVjbGlwc2UudHJhY3R1c3gudmMudHlwZTpNZW1iZXJzaGlwQ3JlZGVudGlhbDpyZWFkIiwiaXNzIjoiZGlkOndlYjpjb25zdW1lci1pZGh1Yjp1c2VyOmNvbnN1bWVyIiwiZXhwIjoxNzcwMjc5MjU0LCJpYXQiOjE3NzAyNzg5NTQsImp0aSI6ImFjY2Vzc3Rva2VuLTcxYThmNTA5LTgwYTktNDMwZC1iMjU0LTMxNGFiYTBkNjY5OSJ9.ipRpdi_Ekh7y4IIqhqLgHU35Fn7NNkv6e6hILXy8pZObdy33y3MKppI61424eyHwqzmh7X2kwV2S5gDy3aOKCQ - prov_access_token: eyJraWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIja2V5LTEiLCJhbGciOiJFZDI1NTE5In0.eyJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJuYmYiOjE3NzAyNzg5NTUsImlzcyI6ImRpZDp3ZWI6cHJvdmlkZXItaWRodWI6dXNlcjpwcm92aWRlciIsImV4cCI6MTc3MDI3OTI1NSwiaWF0IjoxNzcwMjc4OTU1LCJqdGkiOiJkNjA0MTVjOS1kMGM0LTRiNWQtYjI4My01ZmNmYjhlMDY2OGQiLCJ0b2tlbiI6ImV5SnJhV1FpT2lKa2FXUTZkMlZpT21OdmJuTjFiV1Z5TFdsa2FIVmlPblZ6WlhJNlkyOXVjM1Z0WlhJamEyVjVMVEVpTENKaGJHY2lPaUpGWkRJMU5URTVJbjAuZXlKaGRXUWlPaUprYVdRNmQyVmlPbU52Ym5OMWJXVnlMV2xrYUhWaU9uVnpaWEk2WTI5dWMzVnRaWElpTENKemRXSWlPaUprYVdRNmQyVmlPbkJ5YjNacFpHVnlMV2xrYUhWaU9uVnpaWEk2Y0hKdmRtbGtaWElpTENKdVltWWlPakUzTnpBeU56ZzVOVFFzSW5OamIzQmxJam9pYjNKbkxtVmpiR2x3YzJVdWRISmhZM1IxYzNndWRtTXVkSGx3WlRwTlpXMWlaWEp6YUdsd1EzSmxaR1Z1ZEdsaGJEcHlaV0ZrSWl3aWFYTnpJam9pWkdsa09uZGxZanBqYjI1emRXMWxjaTFwWkdoMVlqcDFjMlZ5T21OdmJuTjFiV1Z5SWl3aVpYaHdJam94Tnpjd01qYzVNalUwTENKcFlYUWlPakUzTnpBeU56ZzVOVFFzSW1wMGFTSTZJbUZqWTJWemMzUnZhMlZ1TFRjeFlUaG1OVEE1TFRnd1lUa3RORE13WkMxaU1qVTBMVE14TkdGaVlUQmtOalk1T1NKOS5pcFJwZGlfRWtoN3k0SUlxaHFMZ0hVMzVGbjdOTmt2NmU2aElMWHk4cFpPYmR5MzN5M01LcHBJNjE0MjRleUh3cXptaDdYMmt3VjJTNWdEeTNhT0tDUSJ9.42YDTnuzZ0RprqLjFw6hUoAXrgpPxyzKNFrqLdbWz6HXAiujkq32QAFU-M9gtQ0hMNcjshRZUX6DryBWxhGNDw - offerId: MQ==:YXNzZXRJZA==:MDFhN2ZjYWYtODgzOS00N2JmLTllZDAtM2Y0YjliMTFiOWM5 - negotiation-id: 3745ad50-6b99-4142-bf1a-509b3d0e313d - contractId: 3345f7f1-f735-4c92-8aa2-6e137203b2f9 - transferId: 3ebe55c6-900a-4c03-b213-20c5c3f0274d - pullSecret: eyJraWQiOiJwcm92X3B1YiIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJhbm9ueW1vdXMiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJzdWIiOiJhbm9ueW1vdXMiLCJpYXQiOjE3NzAyNzg5ODgsImp0aSI6IjUwYWQxMjk3LWZhN2QtNDI0ZC1hNjBhLTg5M2MwMGE4OTZhYyJ9.GkSz0qXhFmqPaLQpfPLkAvODX-iekoAQvLh3Kglhm7DApNF3PsGnv-Qzm7m8eNAqTUTWB9XXkRng_XqWmuAd-FWvzwG8d7ZaAahuykkOgX1W7vHWBMdJa-zvNm0cnzm-TQLWYCU-tDSKk_g_UrDUaFf9Jdq-avCoer3wcZrEmrf0K4o_WWs-l5hZEfDIOYHRsgoCY3P8pMcZYRjV57zdLUDl9SvLuCRR0ex0fKxJ2pb7mlaCL5ooD6fRaqWyrLvrIKZaDYfwKrX7IRJT9ePKyls9VKA9JBakh676L0jBr5-2TYG3uE9Xhyv4CZlqyck-_NyiL4Jao8-lL5FVCbPDVQ - ISS_PART_CONT: localissuer - CONS_PART_CONT: consumer - PROV_PART_CONT: provider + cons_access_token: eyJraWQiOiJkaWQ6d2ViOmNvbnN1bWVyLXdhbGxldDp1c2VyOmNvbnN1bWVyI2tleS0xIiwiYWxnIjoiRWQyNTUxOSJ9.eyJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLXdhbGxldDp1c2VyOmNvbnN1bWVyIiwic3ViIjoiZGlkOndlYjpwcm92aWRlci13YWxsZXQ6dXNlcjpwcm92aWRlciIsIm5iZiI6MTc4ODI1NzYxOCwic2NvcGUiOiJvcmcuZWNsaXBzZS5kc3BhY2UuZGNwLnZjLnR5cGU6TWVtYmVyc2hpcENyZWRlbnRpYWw6cmVhZCIsImlzcyI6ImRpZDp3ZWI6Y29uc3VtZXItd2FsbGV0OnVzZXI6Y29uc3VtZXIiLCJleHAiOjE3ODgyNTc5MTgsImlhdCI6MTc4ODI1NzYxOCwianRpIjoiYWNjZXNzdG9rZW4tNjc1NDk4Y2QtOTQ3ZC00NjZmLWI0OTMtZjgxZTRhMjNlMDg3In0.su14qdbmn1zgBAbhSeamzEOC8Gk66pdb9XUFTQKuLRG3Om7MefQUzUTyjcNNzpqbUCGC2DV6h1jK6RmHfFdYAA + prov_access_token: eyJraWQiOiJkaWQ6d2ViOnByb3ZpZGVyLXdhbGxldDp1c2VyOnByb3ZpZGVyI2tleS0xIiwiYWxnIjoiRWQyNTUxOSJ9.eyJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLXdhbGxldDp1c2VyOnByb3ZpZGVyIiwiYXVkIjoiZGlkOndlYjpjb25zdW1lci13YWxsZXQ6dXNlcjpjb25zdW1lciIsIm5iZiI6MTc4ODI1NzYxOSwiaXNzIjoiZGlkOndlYjpwcm92aWRlci13YWxsZXQ6dXNlcjpwcm92aWRlciIsImV4cCI6MTc4ODI1NzkxOSwiaWF0IjoxNzg4MjU3NjE5LCJqdGkiOiJhOTY5ODA4Zi1lZjU0LTRjNWEtOTE3YS05Mjk2NTc3YjQzYWUiLCJ0b2tlbiI6ImV5SnJhV1FpT2lKa2FXUTZkMlZpT21OdmJuTjFiV1Z5TFhkaGJHeGxkRHAxYzJWeU9tTnZibk4xYldWeUkydGxlUzB4SWl3aVlXeG5Jam9pUldReU5UVXhPU0o5LmV5SmhkV1FpT2lKa2FXUTZkMlZpT21OdmJuTjFiV1Z5TFhkaGJHeGxkRHAxYzJWeU9tTnZibk4xYldWeUlpd2ljM1ZpSWpvaVpHbGtPbmRsWWpwd2NtOTJhV1JsY2kxM1lXeHNaWFE2ZFhObGNqcHdjbTkyYVdSbGNpSXNJbTVpWmlJNk1UYzRPREkxTnpZeE9Dd2ljMk52Y0dVaU9pSnZjbWN1WldOc2FYQnpaUzVrYzNCaFkyVXVaR053TG5aakxuUjVjR1U2VFdWdFltVnljMmhwY0VOeVpXUmxiblJwWVd3NmNtVmhaQ0lzSW1semN5STZJbVJwWkRwM1pXSTZZMjl1YzNWdFpYSXRkMkZzYkdWME9uVnpaWEk2WTI5dWMzVnRaWElpTENKbGVIQWlPakUzT0RneU5UYzVNVGdzSW1saGRDSTZNVGM0T0RJMU56WXhPQ3dpYW5ScElqb2lZV05qWlhOemRHOXJaVzR0TmpjMU5EazRZMlF0T1RRM1pDMDBOalptTFdJME9UTXRaamd4WlRSaE1qTmxNRGczSW4wLnN1MTRxZGJtbjF6Z0JBYmhTZWFtekVPQzhHazY2cGRiOVhVRlRRS3VMUkczT203TWVmUVV6VVR5amNOTnpwcWJVQ0dDMkRWNmgxaks2Um1IZkZkWUFBIn0.-1wCoJjyw-KNOerivpCBmT0_hBV6wf2DySFScBKuN9HBt23AjckxNJ7NrQJNlfU5LlWf3RJr3jr6iXDlwryRDw + offerId: MQ==:YXNzZXRJZA==:N2RjZjc1OTktZTQzMy00NmY3LThlOTEtMWVjZTc3YzNlOWM1 + negotiation-id: 50dc06d7-bc96-40b1-9274-1eb7117d6dbb + transferId: 175f3962-2fc2-46ab-ba9e-1da78b7ad685 + pullSecret: eyJraWQiOiJwcm92X3B1YiIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJhbm9ueW1vdXMiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLXdhbGxldDp1c2VyOmNvbnN1bWVyIiwic3ViIjoiYW5vbnltb3VzIiwiaWF0IjoxNzg4MjU3NjQxLCJqdGkiOiIxMzQwZmI3YS1lNDhjLTQ5ODQtYTEwZi0yODI0NGIwOTc2NjkifQ.RmjZ_Ac5iUoWnbRWm3Lz3ylSka5qPGXtAS_Ono1vzE-qUGerYKthdfXMmI0Qa11RLas2ZPbzaYctoHYvIVHoQkv9dYkjjffb_I48QgSMNIJmxOF9snagBmo6ehwMpd0GSO_B2fjeh_qYcLuiHofz8bp6Ff7N1K1dsPKeM5KsPrr1ClBoSzxWB1uCVsh8zM7QIhdliGuVvkPLcWHqIrks4smj4PfNMgkpZTE3PwEu-1LKKPY95_5cbaqPD1F9yeqL1rkr39ZJ-P0hlmVs13a5oSThl1wdtqijfpNeDPvgX-h0TJ4UCSSnTqO8aKCxyjVMhqfBsaz_mCI7VFrC9HOHBQ + ISS_PART_CONT: con-x-issuer + CONS_PART_CONT: user-consumer + PROV_PART_CONT: user-provider + contractId: 6fba2299-5a7e-4bdf-b1b6-c0b609fde33c } diff --git a/edc-controlplane/edc-controlplane-construct-x/local/docker-compose.yaml b/edc-controlplane/edc-controlplane-construct-x/local/docker-compose.yaml index a31e8e50d5..5a1b5352df 100644 --- a/edc-controlplane/edc-controlplane-construct-x/local/docker-compose.yaml +++ b/edc-controlplane/edc-controlplane-construct-x/local/docker-compose.yaml @@ -207,18 +207,6 @@ services: pull_policy: never environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 - - tx.edc.postgresql.migration.asset.enabled=false - - tx.edc.postgresql.migration.agreementbpns.enabled=false - - tx.edc.postgresql.migration.bpn.enabled=false - - tx.edc.postgresql.migration.contractdefinition.enabled=false - - tx.edc.postgresql.migration.contractnegotiation.enabled=false - - tx.edc.postgresql.migration.dataplaneinstance.enabled=false - - tx.edc.postgresql.migration.edr.enabled=false - - tx.edc.postgresql.migration.federatedcatalog.enabled=false - - tx.edc.postgresql.migration.jti-validation.enabled=false - - tx.edc.postgresql.migration.policy-monitor.enabled=false - - tx.edc.postgresql.migration.policy.enabled=false - - tx.edc.postgresql.migration.transferprocess.enabled=false - edc.iam.trusted-issuer.example.id=did:web:local-issuer-wallet:con-x-issuer - edc.iam.did.web.use.https=false - edc.iam.sts.oauth.client.secret.alias=consumersecret @@ -248,9 +236,9 @@ services: - edc.vault.hashicorp.url=http://shared-vault:8200 - edc.vault.hashicorp.health.check.enabled=true - edc.vault.hashicorp.token=vaultsecret0123456789 - - tx.edc.iam.iatp.default-scopes.test.alias=org.eclipse.dspace.dcp.vc.type - - tx.edc.iam.iatp.default-scopes.test.type=MembershipCredential - - tx.edc.iam.iatp.default-scopes.test.operation=read + - tx.edc.iam.dcp.default-scopes.test.alias=org.eclipse.dspace.dcp.vc.type + - tx.edc.iam.dcp.default-scopes.test.type=MembershipCredential + - tx.edc.iam.dcp.default-scopes.test.operation=read healthcheck: test: ["CMD-SHELL", "wget --spider http://localhost:9000/api/check/readiness || exit 1"] start_period: 10s @@ -317,18 +305,6 @@ services: pull_policy: never environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 - - tx.edc.postgresql.migration.asset.enabled=false - - tx.edc.postgresql.migration.agreementbpns.enabled=false - - tx.edc.postgresql.migration.bpn.enabled=false - - tx.edc.postgresql.migration.contractdefinition.enabled=false - - tx.edc.postgresql.migration.contractnegotiation.enabled=false - - tx.edc.postgresql.migration.dataplaneinstance.enabled=false - - tx.edc.postgresql.migration.edr.enabled=false - - tx.edc.postgresql.migration.federatedcatalog.enabled=false - - tx.edc.postgresql.migration.jti-validation.enabled=false - - tx.edc.postgresql.migration.policy-monitor.enabled=false - - tx.edc.postgresql.migration.policy.enabled=false - - tx.edc.postgresql.migration.transferprocess.enabled=false - edc.iam.trusted-issuer.example.id=did:web:local-issuer-wallet:con-x-issuer - edc.iam.did.web.use.https=false - edc.iam.sts.oauth.client.secret.alias=providersecret @@ -358,9 +334,9 @@ services: - edc.vault.hashicorp.url=http://shared-vault:8200 - edc.vault.hashicorp.health.check.enabled=true - edc.vault.hashicorp.token=vaultsecret0123456789 - - tx.edc.iam.iatp.default-scopes.test.alias=org.eclipse.dspace.dcp.vc.type - - tx.edc.iam.iatp.default-scopes.test.type=MembershipCredential - - tx.edc.iam.iatp.default-scopes.test.operation=read + - tx.edc.iam.dcp.default-scopes.test.alias=org.eclipse.dspace.dcp.vc.type + - tx.edc.iam.dcp.default-scopes.test.type=MembershipCredential + - tx.edc.iam.dcp.default-scopes.test.operation=read healthcheck: test: [ "CMD-SHELL", "wget --spider http://localhost:9000/api/check/readiness || exit 1" ] start_period: 10s diff --git a/edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-hashicorp-vault/build.gradle.kts b/edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-hashicorp-vault/build.gradle.kts index 092766e100..e48f397ae0 100644 --- a/edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-hashicorp-vault/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-hashicorp-vault/build.gradle.kts @@ -29,9 +29,10 @@ configurations.all { exclude(group = "org.eclipse.edc", module = "data-plane-util") } +val edcVersion = project.property("con-x-edcVersion") as String +val txVersion = project.property("version") as String + dependencies { - val edcVersion = "0.15.1" - val txVersion = "0.12.0" implementation("org.eclipse.edc:dataplane-base-bom:$edcVersion") implementation("org.eclipse.edc:dataplane-feature-sql-bom:$edcVersion") implementation("org.eclipse.edc:vault-hashicorp:${edcVersion}") diff --git a/edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-vault/build.gradle.kts b/edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-vault/build.gradle.kts index 25d3b323eb..dd664ef633 100644 --- a/edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-vault/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-vault/build.gradle.kts @@ -29,9 +29,10 @@ configurations.all { exclude(group = "org.eclipse.edc", module = "data-plane-util") } +val edcVersion = project.property("con-x-edcVersion") as String +val txVersion = project.property("version") as String + dependencies { - val edcVersion = "0.15.1" - val txVersion = "0.12.0" implementation("org.eclipse.edc:dataplane-base-bom:$edcVersion") implementation("org.eclipse.edc:dataplane-feature-sql-bom:$edcVersion") implementation(project(":edc-extensions:sql-vault")) diff --git a/edc-extensions/agreements/retirement-evaluation-bootstrapping/README.md b/edc-extensions/agreements/retirement-evaluation-bootstrapping/README.md new file mode 100644 index 0000000000..1254bb6a56 --- /dev/null +++ b/edc-extensions/agreements/retirement-evaluation-bootstrapping/README.md @@ -0,0 +1,8 @@ +## RetirementEvaluationBootstrappingExtension + +This extension will utilize the SqlSchemaBootstrapper in order to make sure that the SQL table `edc_agreement_retirement` gets created. + +This is because the retirement-evaluation-store-sql extension does not take care of the creation of this table itself, but instead relies on the controlplane-migration extension. + +So this extension is useful as a lightweight-replacement, if you want to use the agreement-retirement extension with SQL persistence, but don't want to use the database migration extension. + diff --git a/edc-extensions/agreements/retirement-evaluation-bootstrapping/build.gradle.kts b/edc-extensions/agreements/retirement-evaluation-bootstrapping/build.gradle.kts new file mode 100644 index 0000000000..a95aacec4b --- /dev/null +++ b/edc-extensions/agreements/retirement-evaluation-bootstrapping/build.gradle.kts @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +plugins { + id("java") + id("application") +} + +repositories { mavenCentral() } + +val edcVersion = project.property("con-x-edcVersion") as String + +dependencies { + implementation("org.eclipse.edc:sql-lib:${edcVersion}") + implementation("org.eclipse.edc:sql-bootstrapper:${edcVersion}") + implementation("org.eclipse.edc:core-spi:${edcVersion}") + + testImplementation("org.eclipse.edc:junit:${edcVersion}") { + exclude(group = "org.junit.jupiter") + exclude(group = "org.junit.platform") + exclude(group = "org.junit") + } +} + diff --git a/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/java/de/fraunhofer/isst/edc/extension/retirement_bootstrapper/dev/AgreementRetirementBootstrappingExtension.java b/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/java/de/fraunhofer/isst/edc/extension/retirement_bootstrapper/dev/AgreementRetirementBootstrappingExtension.java new file mode 100644 index 0000000000..9128e0bc38 --- /dev/null +++ b/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/java/de/fraunhofer/isst/edc/extension/retirement_bootstrapper/dev/AgreementRetirementBootstrappingExtension.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package de.fraunhofer.isst.edc.extension.retirement_bootstrapper.dev; + +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.runtime.metamodel.annotation.Setting; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; + + +@Extension("Agreement Retirement Bootstrapping Extension") +public class AgreementRetirementBootstrappingExtension implements ServiceExtension { + + @Setting(description = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE, key = "tx.edc.sql.store.agreementretirement.datasource") + private String dataSourceName; + @Inject + private SqlSchemaBootstrapper sqlSchemaBootstrapper; + + @Override + public String name() { + return "Agreement Retirement Bootstrapping Extension"; + } + + @Override + public void initialize(ServiceExtensionContext context) { + sqlSchemaBootstrapper.addStatementFromResource(dataSourceName, "V0_0_1__Init_ContractAgreementRetirement.sql"); + } + +} diff --git a/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..ab5043307a --- /dev/null +++ b/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +################################################################################# +# Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################# + +de.fraunhofer.isst.edc.extension.retirement_bootstrapper.dev.AgreementRetirementBootstrappingExtension \ No newline at end of file diff --git a/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/resources/V0_0_1__Init_ContractAgreementRetirement.sql b/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/resources/V0_0_1__Init_ContractAgreementRetirement.sql new file mode 100644 index 0000000000..53c0724c7a --- /dev/null +++ b/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/main/resources/V0_0_1__Init_ContractAgreementRetirement.sql @@ -0,0 +1,22 @@ +-- +-- Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +-- +-- 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: +-- Mercedes-Benz Tech Innovation GmbH - Initial Database Schema +-- + +-- +-- table: edc_agreement_retirement +-- +CREATE TABLE IF NOT EXISTS edc_agreement_retirement +( + contract_agreement_id VARCHAR PRIMARY KEY, + reason TEXT NOT NULL, + agreement_retirement_date BIGINT NOT NULL +); \ No newline at end of file diff --git a/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/test/java/SqlVaultTest.java b/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/test/java/SqlVaultTest.java new file mode 100644 index 0000000000..e5e580deef --- /dev/null +++ b/edc-extensions/agreements/retirement-evaluation-bootstrapping/src/test/java/SqlVaultTest.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) + * + * 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. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import static org.mockito.Mockito.mock; + +public class SqlVaultTest { + + +} diff --git a/edc-extensions/sql-vault/build.gradle.kts b/edc-extensions/sql-vault/build.gradle.kts index ef2302cbe1..2791209076 100644 --- a/edc-extensions/sql-vault/build.gradle.kts +++ b/edc-extensions/sql-vault/build.gradle.kts @@ -21,7 +21,7 @@ plugins { repositories { mavenCentral() } -val edcVersion = "0.15.1" +val edcVersion = "0.17.0" dependencies { implementation("org.eclipse.edc:sql-lib:${edcVersion}") diff --git a/gradle.properties b/gradle.properties index b8d3c55b90..da9891bf80 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,3 +4,7 @@ version=0.13.0 txScmConnection=scm:git:git@github.com:eclipse-tractusx/tractusx-edc.git txWebsiteUrl=https://github.com/eclipse-tractusx/tractusx-edc.git txScmUrl=https://github.com/eclipse-tractusx/tractusx-edc.git + +# construction-x-properties +con-x-edcVersion=0.17.0 +org.gradle.jvmargs=-Xmx4096m \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 71783f0179..3cf4833936 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -109,6 +109,7 @@ include(":edc-extensions:agreements:retirement-evaluation-core") include(":edc-extensions:agreements:retirement-evaluation-api") include(":edc-extensions:agreements:retirement-evaluation-spi") include(":edc-extensions:agreements:retirement-evaluation-store-sql") +include(":edc-extensions:agreements:retirement-evaluation-bootstrapping") // extensions - data plane include(":edc-extensions:dataplane:dataplane-proxy:edc-dataplane-proxy-consumer-api") From 6df97172e7ff2499215cd9f7d724dd69a7f783e3 Mon Sep 17 00:00:00 2001 From: Ernst-Christoph Schrewe Date: Wed, 2 Sep 2026 08:55:49 +0200 Subject: [PATCH 259/259] fix: mem setting --- gradle.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index da9891bf80..e4215b2eb1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,4 +7,3 @@ txScmUrl=https://github.com/eclipse-tractusx/tractusx-edc.git # construction-x-properties con-x-edcVersion=0.17.0 -org.gradle.jvmargs=-Xmx4096m \ No newline at end of file