diff --git a/.github/actions/generate-and-check-dependencies/action.yml b/.github/actions/generate-and-check-dependencies/action.yml index 2a4e7eba08..1ed0ef1bb7 100644 --- a/.github/actions/generate-and-check-dependencies/action.yml +++ b/.github/actions/generate-and-check-dependencies/action.yml @@ -33,7 +33,9 @@ runs: - name: Generate dependency list shell: bash run: | - ./gradlew allDependencies | grep -Poh "(?<=\s)[\w.-]+:[\w.-]+:[^:\s\[\]]+" | sort | uniq > dependency-list + ./gradlew :edc-controlplane:allDependencies --configuration runtimeClasspath | grep -Poh "(?<=\s)[\w.-]+:[\w.-]+:[^:\s\[\]]+" > dependency-list-c + ./gradlew :edc-dataplane:allDependencies --configuration runtimeClasspath | grep -Poh "(?<=\s)[\w.-]+:[\w.-]+:[^:\s\[\]]+" > dependency-list-d + cat dependency-list-c dependency-list-d | sort | uniq > dependency-list cat dependency-list - name: Run dash diff --git a/.github/actions/generate-and-publish-allure-report/action.yml b/.github/actions/generate-and-publish-allure-report/action.yml index a7a3b0799c..78415514b6 100644 --- a/.github/actions/generate-and-publish-allure-report/action.yml +++ b/.github/actions/generate-and-publish-allure-report/action.yml @@ -35,7 +35,7 @@ runs: using: "composite" steps: - name: Download Allure results - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: ${{ inputs.allure_results }}-* merge-multiple: true diff --git a/.github/actions/publish-docker-image/action.yml b/.github/actions/publish-docker-image/action.yml index 6c549a730b..3875f423c5 100644 --- a/.github/actions/publish-docker-image/action.yml +++ b/.github/actions/publish-docker-image/action.yml @@ -52,19 +52,19 @@ runs: # Enable emulation for cross-arch builds ############################################### - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 ############################################### # Use Docker Buildx (required for multi-arch) ############################################### - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 ##################### # Login to DockerHub ##################### - name: DockerHub login - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ inputs.docker_user }} password: ${{ inputs.docker_token }} @@ -84,7 +84,7 @@ runs: # Create SemVer or ref tags dependent of trigger event - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: docker/metadata-action@v6 with: images: | ${{ inputs.namespace }}/${{ inputs.imagename }} @@ -101,7 +101,7 @@ runs: # Build and push the image ############################### - name: Build and push - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: ${{ inputs.rootDir }} file: ${{ inputs.rootDir }}/build/resources/docker/Dockerfile diff --git a/.github/actions/run-deployment-test/action.yml b/.github/actions/run-deployment-test/action.yml index 19b7e5a02f..264e9d3279 100644 --- a/.github/actions/run-deployment-test/action.yml +++ b/.github/actions/run-deployment-test/action.yml @@ -1,6 +1,7 @@ ################################################################################# # Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # Copyright (c) 2023 Contributors to the Eclipse Foundation +# Copyright (c) 2026 Cofinity-X GmbH # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -43,7 +44,7 @@ inputs: k8sversion: required: false description: "Version of Kubernetes to use" - default: "v1.30.0" + default: "v1.34.3" runs: using: "composite" @@ -55,10 +56,9 @@ runs: - uses: ./.github/actions/setup-kubectl - name: Create k8s Kind Cluster - uses: helm/kind-action@v1.13.0 + uses: helm/kind-action@v1.14.0 with: node_image: kindest/node:${{ inputs.k8sversion }} - version: v0.29.0 - name: Build docker images shell: bash diff --git a/.github/actions/update-version-and-charts/action.yml b/.github/actions/update-version-and-charts/action.yml index fecb4b1e17..2f9b0af1eb 100644 --- a/.github/actions/update-version-and-charts/action.yml +++ b/.github/actions/update-version-and-charts/action.yml @@ -42,18 +42,15 @@ runs: fi echo "version=$VERSION" >> "$GITHUB_OUTPUT" - name: Bump version in /charts - uses: mikefarah/yq@v4.52.2 + uses: mikefarah/yq@v4.52.4 with: cmd: | find charts -name Chart.yaml -maxdepth 3 | xargs -n1 yq -i '.appVersion = "${{ steps.resolver.outputs.version }}" | .version = "${{ steps.resolver.outputs.version }}"' - name: Update Chart READMEs - uses: addnab/docker-run-action@v3 - with: - image: jnorwood/helm-docs:v1.10.0 - options: -v ${{ github.workspace }}/charts:/helm-docs - run: | - helm-docs --log-level debug + shell: bash + run: | + docker run -v ${{ github.workspace }}/charts:/helm-docs jnorwood/helm-docs helm-docs - name: Update version in gradle.properties shell: bash run: |- diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f93f496e16..0979491a74 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -33,6 +33,7 @@ updates: - "dependencies" schedule: interval: "weekly" + open-pull-requests-limit: 50 ignore: - dependency-name: "org.eclipse.dataspacetck.dsp:*" - dependency-name: "org.eclipse.dataspacetck.dcp:*" @@ -49,6 +50,7 @@ updates: - "github-actions" schedule: interval: "weekly" + open-pull-requests-limit: 50 # Docker - package-ecosystem: "docker" @@ -62,3 +64,4 @@ updates: - "docker" schedule: interval: "weekly" + open-pull-requests-limit: 50 diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index a15c7b81ad..8e7aa6d0fa 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -76,8 +76,6 @@ jobs: - name: Build Production Code run: | ./gradlew compileJava --no-daemon --no-build-cache - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/deployment-test.yaml b/.github/workflows/deployment-test.yaml index 69be0e60ec..c737fc7a79 100644 --- a/.github/workflows/deployment-test.yaml +++ b/.github/workflows/deployment-test.yaml @@ -1,6 +1,7 @@ ################################################################################# # Copyright (c) 2023 Mercedes-Benz Tech Innovation GmbH # Copyright (c) 2021,2023 Contributors to the Eclipse Foundation +# Copyright (c) 2026 Cofinity-X GmbH # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -65,9 +66,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.33.1", - "v1.32.5", - "v1.31.9" ] + k8s-version: [ "v1.35.1", + "v1.34.3", + "v1.33.7" ] steps: - name: Checkout uses: actions/checkout@v6 diff --git a/.github/workflows/kics.yml b/.github/workflows/kics.yml index c79bc03f17..3a02b17da9 100644 --- a/.github/workflows/kics.yml +++ b/.github/workflows/kics.yml @@ -44,7 +44,7 @@ jobs: - uses: actions/checkout@v6 - name: KICS scan - uses: checkmarx/kics-github-action@v2.1.19 + uses: checkmarx/kics-github-action@v2.1.20 with: path: "." fail_on: high diff --git a/.github/workflows/publish-openapi-ui.yml b/.github/workflows/publish-openapi-ui.yml index 4129dac9e5..d3b6639499 100644 --- a/.github/workflows/publish-openapi-ui.yml +++ b/.github/workflows/publish-openapi-ui.yml @@ -55,9 +55,7 @@ jobs: - name: Generate openapi spec run: ./gradlew resolve - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: openapi-spec path: resources/openapi/yaml @@ -74,7 +72,7 @@ jobs: steps: - uses: actions/checkout@v6 - uses: eclipse-edc/.github/.github/actions/setup-build@main - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: name: openapi-spec path: resources/openapi/yaml @@ -93,14 +91,10 @@ jobs: run: | ./gradlew -p ${{ matrix.apiGroup.folder }} downloadOpenapi cp ${{ matrix.apiGroup.folder }}/build/docs/openapi/* resources/openapi/yaml/${{ matrix.apiGroup.name }} - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} - name: Merge API specs 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 }} - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} - name: Generate Swagger UI current version uses: Legion2/swagger-ui-action@v1 @@ -117,7 +111,7 @@ jobs: spec-file: ${{ matrix.apiGroup.name }}.yaml GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: ${{ matrix.apiGroup.name }}-api path: dist @@ -128,7 +122,7 @@ jobs: permissions: contents: write steps: - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: path: openapi pattern: "*-api" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c24033babe..c90f1341af 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,6 +32,11 @@ on: required: true type: boolean default: false + previous_tag: + description: "Generate release notes starting from tag" + type: string + required: true + default: "" jobs: @@ -48,6 +53,8 @@ jobs: update_main_branch_version: ${{ steps.update-main.outputs.update_main_branch_version }} steps: - uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Output release version id: release-version run: | @@ -79,6 +86,10 @@ jobs: echo "This workflow can not be executed for SNAPSHOT versions." exit 1 fi + - name: Validate previous_tag exists + run: | + git show-ref --tags --verify --quiet "refs/tags/${{ inputs.previous_tag }}" \ + || (echo "Tag '${{ inputs.previous_tag }}' not found." && exit 1) # Release: Maven Artifacts @@ -169,6 +180,7 @@ jobs: 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 }} diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml index 8a1e4b5983..a87e33be6b 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@7635b24fd512a2e817dd3e9dd661caaf035a079d + uses: trufflesecurity/trufflehog@6c05c4a00b91aa542267d8e32a8254774799d68d continue-on-error: true with: path: ./ # Scan the entire repository diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index a4650792a1..9a767e5080 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.33.1 + uses: aquasecurity/trivy-action@0.35.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.33.1 + uses: aquasecurity/trivy-action@0.35.0 with: image-ref: "tractusx/${{ matrix.image }}:sha-${{ needs.git-sha7.outputs.value }}" format: "sarif" diff --git a/.github/workflows/upgradeability-test.yaml b/.github/workflows/upgradeability-test.yaml index e353b0cb22..c5d79006a2 100644 --- a/.github/workflows/upgradeability-test.yaml +++ b/.github/workflows/upgradeability-test.yaml @@ -49,7 +49,7 @@ jobs: - uses: ./.github/actions/setup-kubectl - name: Create k8s Kind Cluster - uses: helm/kind-action@v1.13.0 + uses: helm/kind-action@v1.14.0 - name: "Update helm repo" run: | @@ -89,8 +89,6 @@ jobs: run: |- ./gradlew :edc-controlplane:edc-controlplane-postgresql-hashicorp-vault:dockerize ./gradlew :edc-dataplane:edc-dataplane-hashicorp-vault:dockerize - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} - name: "Load images into KinD" shell: bash @@ -114,7 +112,14 @@ jobs: - name: Print logs if: failure() shell: bash - run: kubectl get deployments | tail -n +2 | awk '{print $1}' | sed 's/^/deployment\//' | xargs -n1 kubectl logs + run: | + kubectl get pods -o wide + kubectl get pods --no-headers | awk '{print $1}' | while read pod; do + echo "=== logs: $pod ===" + kubectl logs "$pod" --all-containers=true || true + echo "=== previous logs: $pod ===" + kubectl logs "$pod" --previous --all-containers=true || true + done - name: Destroy the kind cluster if: always() diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 3008cd5fb8..e067eafc3d 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -53,8 +53,6 @@ jobs: - name: Run Checkstyle run: | ./gradlew checkstyleMain checkstyleTest - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} verify-javadoc: runs-on: ubuntu-latest @@ -64,8 +62,6 @@ jobs: - name: Run Javadoc run: ./gradlew javadoc - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} unit-tests: runs-on: ubuntu-latest @@ -76,12 +72,10 @@ jobs: - name: Run Unit tests run: ./gradlew test testCodeCoverage - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} # uploads the jacoco report as artifact - name: Upload JaCoCo Coverage Report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: JaCoCo coverage-report path: build/reports/jacoco/testCodeCoverageReport/testCodeCoverageReport.xml @@ -108,7 +102,7 @@ jobs: # uploads the coverage-report.md artifact - name: Upload Code Coverage Markdown Report - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: code-coverage-report-markdown path: "*/coverage-results.md" @@ -125,8 +119,6 @@ jobs: run: | ./gradlew :edc-tests:runtime:mock-connector:dockerize ./gradlew test -DincludeTags="ComponentTest" - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} api-tests: runs-on: ubuntu-latest @@ -137,8 +129,6 @@ jobs: - name: Run API tests run: ./gradlew test -DincludeTags="ApiTest" - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} prepare-end-to-end-tests: runs-on: ubuntu-latest @@ -166,8 +156,6 @@ jobs: run: | ./gradlew compileJava compileTestJava ./gradlew -p edc-tests/e2e/${{ matrix.dir }} test -DincludeTags="EndToEndTest" -PverboseTest=true --no-build-cache - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} - name: Set sanitized artifact name run: | @@ -175,7 +163,7 @@ jobs: echo "ARTIFACT_NAME=${SANITIZED_NAME}" >> $GITHUB_ENV - name: Upload test artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: allure-results-${{ env.ARTIFACT_NAME }} path: edc-tests/e2e/${{ matrix.dir }}/build/allure-results @@ -188,8 +176,6 @@ jobs: - name: Run Postgresql E2E tests run: ./gradlew test -DincludeTags="PostgresqlIntegrationTest" -PverboseTest=true - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} compatibility-tests: runs-on: ubuntu-latest @@ -202,8 +188,6 @@ jobs: - name: Run Compatibility tests run: ./gradlew test -DincludeTags="CompatibilityTest" -PverboseTest=true --no-build-cache - env: - DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_API_TOKEN }} generate-allure-report: runs-on: ubuntu-latest diff --git a/.tractusx b/.tractusx index c8b568d9ba..4897df1ed1 100644 --- a/.tractusx +++ b/.tractusx @@ -2,6 +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.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" diff --git a/README.md b/README.md index 502480069f..c0acbfb12c 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,10 @@ Build Tractus-X EDC together with its Container Images - [Internal Issue](https://github.com/eclipse-tractusx/tractusx-edc/issues/1772) - [Hashicorp Vault Issue](https://github.com/hashicorp/vault/issues/29357) + +## Contributing +See [CONTRIBUTING](https://github.com/eclipse-tractusx/tractusx-edc/blob/main/CONTRIBUTING.md). + ## License Distributed under the Apache 2.0 License. diff --git a/build.gradle.kts b/build.gradle.kts index f0152ef9a5..82be11fe4e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -68,13 +68,13 @@ allprojects { constraints { plugins.apply("org.gradle.java-test-fixtures") - implementation("org.yaml:snakeyaml:2.5") { + 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.2") { + 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") { diff --git a/charts/tractusx-connector-memory/Chart.yaml b/charts/tractusx-connector-memory/Chart.yaml index 4415e1dc42..5c2ee996f0 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.12.0-SNAPSHOT +version: 0.13.0-SNAPSHOT # 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.12.0-SNAPSHOT" +appVersion: "0.13.0-SNAPSHOT" 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 beb99d1858..22281ab276 100644 --- a/charts/tractusx-connector-memory/README.md +++ b/charts/tractusx-connector-memory/README.md @@ -1,6 +1,6 @@ # tractusx-connector-memory -![Version: 0.12.0-SNAPSHOT](https://img.shields.io/badge/Version-0.12.0--SNAPSHOT-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.12.0-SNAPSHOT](https://img.shields.io/badge/AppVersion-0.12.0--SNAPSHOT-informational?style=flat-square) +![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) 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! @@ -10,8 +10,8 @@ A Helm chart for Tractus-X Eclipse Data Space Connector based on memory. Please ### Preconditions -- You'll need an account with DIM, the wallet for VerifiableCredentials -- the necessary set of VerifiableCredentials for this participant must already be issued to your DIM tenant. This is typically done by the +- You'll need an account with DIV, the wallet for VerifiableCredentials +- the necessary set of VerifiableCredentials for this participant must already be issued to your DIV tenant. This is typically done by the Portal during participant onboarding - the client ID and client secret corresponding to that account must be known @@ -24,10 +24,10 @@ A Helm chart for Tractus-X Eclipse Data Space Connector based on memory. Please ### 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 DIM -- `iatp.sts.oauth.client.id`: the client ID of your tenant in DIM -- `iatp.sts.oauth.client.secret_alias`: alias under which you saved your DIM client secret in the vault -- `iatp.sts.dim.url`: the base URL for DIM +- `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 In addition, in order to map BPNs to DIDs, a new service is required, called the BPN-DID Resolution Service, which must be configured: @@ -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.12.0-SNAPSHOT \ +helm install my-release tractusx-edc/tractusx-connector-memory --version 0.13.0-SNAPSHOT \ -f /tractusx-connector-memory-test.yaml \ --set vault.secrets="client-secret:$YOUR_CLIENT_SECRET" ``` @@ -62,10 +62,10 @@ helm install my-release tractusx-edc/tractusx-connector-memory --version 0.12.0- | 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.dim.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 DIM 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 DIM access | -| iatp.sts.oauth.token_url | string | `nil` | URL where connectors can request OAuth2 access tokens for DIM access | +| 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. | @@ -81,19 +81,10 @@ helm install my-release tractusx-edc/tractusx-connector-memory --version 0.12.0- | runtime.autoscaling.targetMemoryUtilizationPercentage | int | `80` | targetAverageUtilization of memory provided to a pod | | runtime.bdrs.cache_validity_seconds | int | `600` | Time that a cached BPN/DID resolution map is valid in seconds, default is 600 seconds (10 min) | | runtime.bdrs.server.url | string | `nil` | URL of the BPN/DID Resolution Service | -| runtime.catalog | object | `{"crawler":{"initialDelay":null,"num":null,"period":null,"targetsFile":null},"enabled":false}` | configuration for the built-in federated catalog crawler | -| runtime.catalog.crawler.initialDelay | string | `nil` | Initial delay for the crawling to start. Leave blank for a random delay | -| runtime.catalog.crawler.num | string | `nil` | Number of desired crawlers. Final number might be different, based on number of crawl targets | -| runtime.catalog.crawler.period | string | `nil` | Period between two crawl runs in seconds. Default is 60 seconds. | -| runtime.catalog.crawler.targetsFile | string | `nil` | File path to a JSON file containing TargetNode entries | -| runtime.catalog.enabled | bool | `false` | Flag to globally enable/disable the FC feature | | runtime.debug.enabled | bool | `false` | Enables java debugging mode. | | runtime.debug.port | int | `1044` | Port where the debuggee can connect to. | | runtime.debug.suspendOnStart | bool | `false` | Defines if the JVM should wait with starting the application until someone connected to the debugging port. | -| runtime.endpoints | object | `{"catalog":{"authKey":"password","path":"/catalog","port":8085},"control":{"path":"/control","port":8083},"default":{"path":"/api","port":8080},"management":{"authKey":"password","jwksUrl":null,"path":"/management","port":8081},"protocol":{"path":"/api/v1/dsp","port":8084},"proxy":{"authKey":"password","path":"/proxy","port":8186},"public":{"path":"/api/public","port":8086}}` | endpoints of the controlplane | -| runtime.endpoints.catalog.authKey | string | `"password"` | authentication key, must be attached to each request as `X-Api-Key` header | -| runtime.endpoints.catalog.path | string | `"/catalog"` | path for incoming catalog cache query requests | -| runtime.endpoints.catalog.port | int | `8085` | port for incoming catalog cache query requests | +| runtime.endpoints | object | `{"control":{"path":"/control","port":8083},"default":{"path":"/api","port":8080},"management":{"authKey":"password","jwksUrl":null,"path":"/management","port":8081},"protocol":{"path":"/api/v1/dsp","port":8084},"proxy":{"authKey":"password","path":"/proxy","port":8186},"public":{"path":"/api/public","port":8086}}` | endpoints of the controlplane | | runtime.endpoints.control | object | `{"path":"/control","port":8083}` | control api, used for internal control calls. can be added to the internal ingress, but should probably not | | runtime.endpoints.control.path | string | `"/control"` | path for incoming api calls | | runtime.endpoints.control.port | int | `8083` | port for incoming api calls | diff --git a/charts/tractusx-connector-memory/README.md.gotmpl b/charts/tractusx-connector-memory/README.md.gotmpl index 3484c4f84a..fc0927964a 100644 --- a/charts/tractusx-connector-memory/README.md.gotmpl +++ b/charts/tractusx-connector-memory/README.md.gotmpl @@ -12,8 +12,8 @@ ### Preconditions -- You'll need an account with DIM, the wallet for VerifiableCredentials -- the necessary set of VerifiableCredentials for this participant must already be issued to your DIM tenant. This is typically done by the +- You'll need an account with DIV, the wallet for VerifiableCredentials +- the necessary set of VerifiableCredentials for this participant must already be issued to your DIV tenant. This is typically done by the Portal during participant onboarding - the client ID and client secret corresponding to that account must be known @@ -27,10 +27,10 @@ ### 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 DIM -- `iatp.sts.oauth.client.id`: the client ID of your tenant in DIM -- `iatp.sts.oauth.client.secret_alias`: alias under which you saved your DIM client secret in the vault -- `iatp.sts.dim.url`: the base URL for DIM +- `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 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 527df379f2..84de5ee953 100644 --- a/charts/tractusx-connector-memory/templates/deployment-runtime.yaml +++ b/charts/tractusx-connector-memory/templates/deployment-runtime.yaml @@ -210,14 +210,6 @@ spec: value: {{ .Values.runtime.endpoints.public.port | quote }} - name: "WEB_HTTP_PUBLIC_PATH" value: {{ .Values.runtime.endpoints.public.path | quote }} - - name: "WEB_HTTP_CATALOG_PORT" - value: {{ .Values.runtime.endpoints.catalog.port | quote }} - - name: "WEB_HTTP_CATALOG_PATH" - value: {{ .Values.runtime.endpoints.catalog.path | quote }} - - name: "WEB_HTTP_CATALOG_AUTH_TYPE" - value: "tokenbased" - - name: "WEB_HTTP_CATALOG_AUTH_KEY" - value: {{ .Values.runtime.endpoints.catalog.authKey | required ".Values.runtime.endpoints.catalog.authKey is required" | quote }} ######### ## DSP ## @@ -231,7 +223,7 @@ spec: value: {{ printf "%s%s" (include "txdc.runtime.url.protocol" . ) .Values.runtime.endpoints.protocol.path | quote }} ############################# - ## IATP / STS / DIM CONFIG ## + ## IATP / 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}} @@ -240,10 +232,10 @@ spec: - 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.dim.url }} - - name: "TX_EDC_IAM_STS_DIM_URL" - value: {{ .Values.iatp.sts.dim.url | quote}} - {{- end}} + {{- if .Values.iatp.sts.div.url }} + - name: "TX_EDC_IAM_STS_DIV_URL" + value: {{ .Values.iatp.sts.div.url | quote }} + {{- end }} {{- range $index, $issuer := .Values.iatp.trustedIssuers }} {{- if eq (kindOf $issuer) "string" }} @@ -323,31 +315,6 @@ spec: - name: "TX_EDC_VAULT_SECRETS" value: {{ .Values.vault.secrets | quote}} - - ############################### - ## FEDERATED CATALOG CRAWLER ## - ############################### - {{- if .Values.runtime.catalog.crawler.period }} - - name: "EDC_CATALOG_CACHE_EXECUTION_PERIOD_SECONDS" - value: {{ .Values.runtime.catalog.crawler.period | quote}} - {{- end }} - - {{- if .Values.runtime.catalog.crawler.initialDelay }} - - name: "EDC_CATALOG_CACHE_EXECUTION_DELAY_SECONDS" - value: {{ .Values.runtime.catalog.crawler.initialDelay | quote }} - {{- end }} - - {{- if .Values.runtime.catalog.crawler.num }} - - name: "EDC_CATALOG_CACHE_PARTITION_NUM_CRAWLERS" - value: {{ .Values.runtime.catalog.crawler.num }} - {{- end }} - - - name: "EDC_CATALOG_CACHE_EXECUTION_ENABLED" - value: {{ .Values.runtime.catalog.enabled | quote }} - - - name: "TX_EDC_CATALOG_NODE_LIST_FILE" - value: {{ .Values.runtime.catalog.crawler.targetsFile }} - ################### ## POLICY ENGINE ## ################### diff --git a/charts/tractusx-connector-memory/values.yaml b/charts/tractusx-connector-memory/values.yaml index 1d52cb346b..a0e1008643 100644 --- a/charts/tractusx-connector-memory/values.yaml +++ b/charts/tractusx-connector-memory/values.yaml @@ -48,16 +48,16 @@ iatp: # - "MembershipCredential" # - "did:web:example2.com" sts: - dim: + div: # -- URL where connectors can request SI tokens url: oauth: - # -- URL where connectors can request OAuth2 access tokens for DIM access + # -- URL where connectors can request OAuth2 access tokens for DIV access token_url: client: - # -- Client ID for requesting OAuth2 access token for DIM access + # -- Client ID for requesting OAuth2 access token for DIV access id: - # -- Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIM access + # -- Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access secret_alias: didService: selfRegistration: @@ -207,14 +207,6 @@ runtime: # -- authentication key, must be attached to each request as `X-Api-Key` header authKey: "password" - catalog: - # -- port for incoming catalog cache query requests - port: 8085 - # -- path for incoming catalog cache query requests - path: /catalog - # -- authentication key, must be attached to each request as `X-Api-Key` header - authKey: "password" - token: refresh: # -- TTL in seconds for access tokens (also known as EDR token) @@ -237,19 +229,6 @@ runtime: # -- URL of the BPN/DID Resolution Service url: - # -- configuration for the built-in federated catalog crawler - catalog: - # -- Flag to globally enable/disable the FC feature - enabled: false - crawler: - # -- Number of desired crawlers. Final number might be different, based on number of crawl targets - num: - # -- Period between two crawl runs in seconds. Default is 60 seconds. - period: - # -- Initial delay for the crawling to start. Leave blank for a random delay - initialDelay: - # -- File path to a JSON file containing TargetNode entries - targetsFile: # -- configuration for policy engine policy: validation: diff --git a/charts/tractusx-connector/Chart.yaml b/charts/tractusx-connector/Chart.yaml index 0a9efd8771..ff4e000e0e 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.12.0-SNAPSHOT +version: 0.13.0-SNAPSHOT # 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.12.0-SNAPSHOT" +appVersion: "0.13.0-SNAPSHOT" 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 c7b7b35068..8ee56f90a2 100644 --- a/charts/tractusx-connector/README.md +++ b/charts/tractusx-connector/README.md @@ -1,6 +1,6 @@ # tractusx-connector -![Version: 0.12.0-SNAPSHOT](https://img.shields.io/badge/Version-0.12.0--SNAPSHOT-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.12.0-SNAPSHOT](https://img.shields.io/badge/AppVersion-0.12.0--SNAPSHOT-informational?style=flat-square) +![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) 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. @@ -13,8 +13,8 @@ This chart is intended for use with an _existing_ PostgreSQL database and an _ex ### Preconditions -- You'll need an account with DIM, the wallet for VerifiableCredentials -- the necessary set of VerifiableCredentials for this participant must already be issued to your DIM tenant. This is typically done by the +- You'll need an account with DIV, the wallet for VerifiableCredentials +- the necessary set of VerifiableCredentials for this participant must already be issued to your DIV tenant. This is typically done by the Portal during participant onboarding - the client ID and client secret corresponding to that account must be known @@ -27,10 +27,10 @@ This chart is intended for use with an _existing_ PostgreSQL database and an _ex ### 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 DIM -- `iatp.sts.oauth.client.id`: the client ID of your tenant in DIM -- `iatp.sts.oauth.client.secret_alias`: alias under which you saved your DIM client secret in the vault -- `iatp.sts.dim.url`: the base URL for DIM +- `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 In addition, in order to map BPNs to DIDs, a new service is required, called the BPN-DID Resolution Service, which must be configured: @@ -44,7 +44,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.12.0-SNAPSHOT \ +helm install my-release tractusx-edc/tractusx-connector --version 0.13.0-SNAPSHOT \ -f /tractusx-connector-test.yaml ``` @@ -71,19 +71,10 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.12.0-SNAPSHO | 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.catalog | object | `{"crawler":{"initialDelay":null,"num":null,"period":null,"targetsFile":null},"enabled":false}` | configuration for the built-in federated catalog crawler | -| controlplane.catalog.crawler.initialDelay | string | `nil` | Initial delay for the crawling to start. Leave blank for a random delay | -| controlplane.catalog.crawler.num | string | `nil` | Number of desired crawlers. Final number might be different, based on number of crawl targets | -| controlplane.catalog.crawler.period | string | `nil` | Period between two crawl runs in seconds. Default is 60 seconds. | -| controlplane.catalog.crawler.targetsFile | string | `nil` | File path to a JSON file containing TargetNode entries | -| controlplane.catalog.enabled | bool | `false` | Flag to globally enable/disable the FC feature | | 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. | -| controlplane.endpoints | object | `{"catalog":{"authKey":"password","path":"/catalog","port":8085},"control":{"path":"/control","port":8083},"default":{"path":"/api","port":8080},"management":{"authKey":"password","jwksUrl":null,"path":"/management","port":8081},"metrics":{"path":"/metrics","port":9090},"protocol":{"path":"/api/v1/dsp","port":8084}}` | endpoints of the control plane | -| controlplane.endpoints.catalog.authKey | string | `"password"` | authentication key, must be attached to each request as `X-Api-Key` header | -| controlplane.endpoints.catalog.path | string | `"/catalog"` | path for incoming catalog cache query requests | -| controlplane.endpoints.catalog.port | int | `8085` | port for incoming catalog cache query requests | +| controlplane.endpoints | object | `{"control":{"path":"/control","port":8083},"default":{"path":"/api","port":8080},"management":{"authKey":"password","jwksUrl":null,"path":"/management","port":8081},"metrics":{"path":"/metrics","port":9090},"protocol":{"path":"/api/v1/dsp","port":8084}}` | endpoints of the control plane | | controlplane.endpoints.control | object | `{"path":"/control","port":8083}` | control api, used for internal control calls. can be added to the internal ingress, but should probably not | | controlplane.endpoints.control.path | string | `"/control"` | path for incoming api calls | | controlplane.endpoints.control.port | int | `8083` | port for incoming api calls | @@ -272,10 +263,10 @@ helm install my-release tractusx-edc/tractusx-connector --version 0.12.0-SNAPSHO | 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.dim.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 DIM 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 DIM access | -| iatp.sts.oauth.token_url | string | `nil` | URL where connectors can request OAuth2 access tokens for DIM access | +| 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 | diff --git a/charts/tractusx-connector/README.md.gotmpl b/charts/tractusx-connector/README.md.gotmpl index de3ef91496..9e9a12b487 100644 --- a/charts/tractusx-connector/README.md.gotmpl +++ b/charts/tractusx-connector/README.md.gotmpl @@ -12,8 +12,8 @@ ### Preconditions -- You'll need an account with DIM, the wallet for VerifiableCredentials -- the necessary set of VerifiableCredentials for this participant must already be issued to your DIM tenant. This is typically done by the +- You'll need an account with DIV, the wallet for VerifiableCredentials +- the necessary set of VerifiableCredentials for this participant must already be issued to your DIV tenant. This is typically done by the Portal during participant onboarding - the client ID and client secret corresponding to that account must be known @@ -27,10 +27,10 @@ ### 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 DIM -- `iatp.sts.oauth.client.id`: the client ID of your tenant in DIM -- `iatp.sts.oauth.client.secret_alias`: alias under which you saved your DIM client secret in the vault -- `iatp.sts.dim.url`: the base URL for DIM +- `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 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 e2fe4a3c85..9f7b748362 100644 --- a/charts/tractusx-connector/templates/deployment-controlplane.yaml +++ b/charts/tractusx-connector/templates/deployment-controlplane.yaml @@ -196,14 +196,6 @@ spec: value: {{ .Values.controlplane.endpoints.protocol.path | quote }} - name: "EDC_CONTROL_ENDPOINT" value: {{ include "txdc.controlplane.url.control" .}} - - name: "WEB_HTTP_CATALOG_PORT" - value: {{ .Values.controlplane.endpoints.catalog.port | quote }} - - name: "WEB_HTTP_CATALOG_PATH" - value: {{ .Values.controlplane.endpoints.catalog.path | quote }} - - name: "WEB_HTTP_CATALOG_AUTH_TYPE" - value: "tokenbased" - - name: "WEB_HTTP_CATALOG_AUTH_KEY" - value: {{ .Values.controlplane.endpoints.catalog.authKey | required ".Values.controlplane.endpoints.catalog.authKey is required" | quote }} ######### @@ -231,7 +223,7 @@ spec: ############################# - ## IATP / STS / DIM CONFIG ## + ## IATP / 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}} @@ -239,9 +231,9 @@ spec: value: {{ .Values.iatp.sts.oauth.client.id | required ".Values.iatp.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.dim.url }} - - name: "TX_EDC_IAM_STS_DIM_URL" - value: {{ .Values.iatp.sts.dim.url | quote }} + {{- if .Values.iatp.sts.div.url }} + - name: "TX_EDC_IAM_STS_DIV_URL" + value: {{ .Values.iatp.sts.div.url | quote }} {{- end }} {{- range $index, $issuer := .Values.iatp.trustedIssuers }} {{- if eq (kindOf $issuer) "string" }} @@ -302,32 +294,6 @@ spec: value: {{ .Values.vault.hashicorp.paths.folder | quote }} {{- end }} - - ############################### - ## FEDERATED CATALOG CRAWLER ## - ############################### - {{- if .Values.controlplane.catalog.crawler.period }} - - name: "EDC_CATALOG_CACHE_EXECUTION_PERIOD_SECONDS" - value: {{ .Values.controlplane.catalog.crawler.period | quote}} - {{- end }} - - {{- if .Values.controlplane.catalog.crawler.initialDelay }} - - name: "EDC_CATALOG_CACHE_EXECUTION_DELAY_SECONDS" - value: {{ .Values.controlplane.catalog.crawler.initialDelay | quote }} - {{- end }} - - {{- if .Values.controlplane.catalog.crawler.num }} - - name: "EDC_CATALOG_CACHE_PARTITION_NUM_CRAWLERS" - value: {{ .Values.controlplane.catalog.crawler.num }} - {{- end }} - - - name: "EDC_CATALOG_CACHE_EXECUTION_ENABLED" - value: {{ .Values.controlplane.catalog.enabled | quote }} - - - name: "TX_EDC_CATALOG_NODE_LIST_FILE" - value: {{ .Values.controlplane.catalog.crawler.targetsFile }} - - ################### ## POLICY ENGINE ## ################### diff --git a/charts/tractusx-connector/templates/deployment-dataplane.yaml b/charts/tractusx-connector/templates/deployment-dataplane.yaml index b784c17f51..40510d5627 100644 --- a/charts/tractusx-connector/templates/deployment-dataplane.yaml +++ b/charts/tractusx-connector/templates/deployment-dataplane.yaml @@ -222,7 +222,7 @@ spec: {{ end }} ############################# - ## IATP / STS / DIM CONFIG ## + ## IATP / 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}} @@ -230,9 +230,9 @@ spec: value: {{ .Values.iatp.sts.oauth.client.id | required ".Values.iatp.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.dim.url }} - - name: "TX_EDC_IAM_STS_DIM_URL" - value: {{ .Values.iatp.sts.dim.url | quote}} + {{- if .Values.iatp.sts.div.url }} + - name: "TX_EDC_IAM_STS_DIV_URL" + value: {{ .Values.iatp.sts.div.url | quote }} {{- end }} ################ diff --git a/charts/tractusx-connector/templates/service-controlplane.yaml b/charts/tractusx-connector/templates/service-controlplane.yaml index 851bf271a8..400a5d80c0 100644 --- a/charts/tractusx-connector/templates/service-controlplane.yaml +++ b/charts/tractusx-connector/templates/service-controlplane.yaml @@ -55,10 +55,6 @@ spec: targetPort: protocol protocol: TCP name: protocol - - port: {{ .Values.controlplane.endpoints.catalog.port }} - targetPort: catalog - protocol: TCP - name: catalog - port: {{ .Values.controlplane.endpoints.metrics.port }} targetPort: metrics protocol: TCP diff --git a/charts/tractusx-connector/values.yaml b/charts/tractusx-connector/values.yaml index 886bab0b00..1accc39341 100644 --- a/charts/tractusx-connector/values.yaml +++ b/charts/tractusx-connector/values.yaml @@ -55,16 +55,16 @@ iatp: # - "MembershipCredential" # - "did:web:example2.com" sts: - dim: + div: # -- URL where connectors can request SI tokens url: oauth: - # -- URL where connectors can request OAuth2 access tokens for DIM access + # -- URL where connectors can request OAuth2 access tokens for DIV access token_url: client: - # -- Client ID for requesting OAuth2 access token for DIM access + # -- Client ID for requesting OAuth2 access token for DIV access id: - # -- Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIM access + # -- Alias under which the client secret is stored in the vault for requesting OAuth2 access token for DIV access secret_alias: didService: selfRegistration: @@ -205,13 +205,6 @@ controlplane: port: 9090 # -- path for incoming api calls path: /metrics - catalog: - # -- port for incoming catalog cache query requests - port: 8085 - # -- path for incoming catalog cache query requests - path: /catalog - # -- authentication key, must be attached to each request as `X-Api-Key` header - authKey: "password" bdrs: # -- Time that a cached BPN/DID resolution map is valid in seconds, default is 600 seconds (10 min) @@ -220,19 +213,6 @@ controlplane: # -- URL of the BPN/DID Resolution Service url: - # -- configuration for the built-in federated catalog crawler - catalog: - # -- Flag to globally enable/disable the FC feature - enabled: false - crawler: - # -- Number of desired crawlers. Final number might be different, based on number of crawl targets - num: - # -- Period between two crawl runs in seconds. Default is 60 seconds. - period: - # -- Initial delay for the crawling to start. Leave blank for a random delay - initialDelay: - # -- File path to a JSON file containing TargetNode entries - targetsFile: # -- configuration for policy engine policy: validation: diff --git a/core/core-utils/src/main/java/org/eclipse/tractusx/edc/core/utils/FileUtils.java b/core/core-utils/src/main/java/org/eclipse/tractusx/edc/core/utils/FileUtils.java new file mode 100644 index 0000000000..16d9804530 --- /dev/null +++ b/core/core-utils/src/main/java/org/eclipse/tractusx/edc/core/utils/FileUtils.java @@ -0,0 +1,54 @@ +/******************************************************************************** + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE + * + * 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.core.utils; + +import org.eclipse.edc.spi.result.Result; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; + +import static java.lang.String.format; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; + +public class FileUtils { + + private FileUtils() { + } + + @NotNull + public static Result getResourceFile(String name) { + try (var stream = FileUtils.class.getClassLoader().getResourceAsStream(name)) { + if (stream == null) { + return Result.failure(format("Cannot find resource %s", name)); + } + + var filename = Path.of(name).getFileName().toString(); + var parts = filename.split("\\."); + var tempFile = Files.createTempFile(parts[0], "." + parts[1]); + Files.copy(stream, tempFile, REPLACE_EXISTING); + return Result.success(tempFile.toFile()); + } catch (Exception e) { + return Result.failure(format("Cannot read resource %s: ", name)); + } + } +} diff --git a/core/core-utils/src/test/java/org/eclipse/tractusx/edc/core/utils/FileUtilsTest.java b/core/core-utils/src/test/java/org/eclipse/tractusx/edc/core/utils/FileUtilsTest.java new file mode 100644 index 0000000000..eab2943dfd --- /dev/null +++ b/core/core-utils/src/test/java/org/eclipse/tractusx/edc/core/utils/FileUtilsTest.java @@ -0,0 +1,90 @@ +/******************************************************************************** + * Copyright (c) 2026 SAP SE + * + * 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.core.utils; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.lang.reflect.Modifier; + +import static org.assertj.core.api.Assertions.assertThat; + +class FileUtilsTest { + + @Test + @DisplayName("Should successfully load and copy a valid resource file") + void testGetResourceFile_SuccessfullyLoadsResource() { + var result = FileUtils.getResourceFile("test-resource.txt"); + + assertThat(result).isNotNull(); + assertThat(result.succeeded()).isTrue(); + assertThat(result.getContent()) + .isNotNull() + .isInstanceOf(File.class); + + File resultFile = result.getContent(); + assertThat(resultFile.exists()).isTrue(); + assertThat(resultFile.getName()) + .contains("test-resource") + .endsWith(".txt"); + + // Cleanup + resultFile.deleteOnExit(); + } + + @Test + @DisplayName("Should return failure when resource is not found") + void testGetResourceFile_ResourceNotFound() { + var result = FileUtils.getResourceFile("non-existent-resource.txt"); + + assertThat(result).isNotNull(); + assertThat(result.failed()).isTrue(); + assertThat(result.getFailure().getMessages()) + .isNotEmpty() + .contains("Cannot find resource non-existent-resource.txt"); + } + + @Test + @DisplayName("Should handle resource names with dots in filename") + void testGetResourceFile_WithDotsInFilename() { + var result = FileUtils.getResourceFile("test-resource.backup.txt"); + + assertThat(result).isNotNull(); + if (result.succeeded()) { + File resultFile = result.getContent(); + assertThat(resultFile).isNotNull(); + resultFile.deleteOnExit(); + } else { + assertThat(result.getFailure().getMessages()).isNotEmpty(); + } + } + + @Test + @DisplayName("Should not allow instantiation of FileUtils") + void testFileUtilsPrivateConstructor() { + // Verify that FileUtils has a private constructor by checking the class structure + assertThat(FileUtils.class.getDeclaredConstructors()).hasSize(1); + var constructor = FileUtils.class.getDeclaredConstructors()[0]; + assertThat(constructor.getModifiers()).matches(Modifier::isPrivate); + assertThat(constructor.getParameters()).isEmpty(); + } +} + diff --git a/core/core-utils/src/test/resources/test-resource.txt b/core/core-utils/src/test/resources/test-resource.txt new file mode 100644 index 0000000000..d7b42a0b5e --- /dev/null +++ b/core/core-utils/src/test/resources/test-resource.txt @@ -0,0 +1 @@ +This is a dummy test resource file. diff --git a/core/json-ld-core/build.gradle.kts b/core/json-ld-core/build.gradle.kts index 62071ad096..70123e50f9 100644 --- a/core/json-ld-core/build.gradle.kts +++ b/core/json-ld-core/build.gradle.kts @@ -23,9 +23,11 @@ plugins { dependencies { implementation(project(":spi:core-spi")) + implementation(project(":core:core-utils")) implementation(libs.edc.spi.core) implementation(libs.edc.spi.jsonld) implementation(libs.dsp.spi.v2025) implementation(libs.dsp.spi.v08) + implementation(libs.edc.lib.management.api) testImplementation(testFixtures(libs.edc.junit)) } 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 c396ae5dc0..0287e98845 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 @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -25,19 +26,14 @@ import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.jetbrains.annotations.NotNull; import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Map; -import static java.lang.String.format; -import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; +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.edr.spi.CoreConstants.CX_POLICY_NS; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_POLICY_PREFIX; +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; @@ -51,10 +47,6 @@ public class JsonLdExtension implements ServiceExtension { 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"; - @Deprecated(since = "0.11.0") - public static final String CX_POLICY_CONTEXT = "https://w3id.org/tractusx/policy/v1.0.0"; - 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"; public static final String TX_AUTH_CONTEXT = "https://w3id.org/tractusx/auth/v1.0.0"; private static final String PREFIX = "document" + File.separator; @@ -62,10 +54,8 @@ public class JsonLdExtension implements ServiceExtension { CREDENTIALS_V_1, PREFIX + "credential-v1.jsonld", SECURITY_JWS_V1, PREFIX + "security-jws-2020.jsonld", SECURITY_ED25519_V1, PREFIX + "security-ed25519-2020.jsonld", - CX_POLICY_2025_09_CONTEXT, PREFIX + "cx-policy-v1.jsonld", TX_AUTH_CONTEXT, PREFIX + "tx-auth-v1.jsonld", - EDC_CONTEXT, PREFIX + "edc-v1.jsonld", - CX_ODRL_CONTEXT, PREFIX + "cx-odrl.jsonld"); + EDC_CONTEXT, PREFIX + "edc-v1.jsonld"); @Inject private JsonLd jsonLdService; @@ -76,11 +66,10 @@ public class JsonLdExtension implements ServiceExtension { public void initialize(ServiceExtensionContext context) { jsonLdService.registerNamespace(TX_PREFIX, TX_NAMESPACE, DSP_SCOPE_V_08); jsonLdService.registerNamespace(TX_AUTH_PREFIX, TX_AUTH_NS, DSP_SCOPE_V_08); - jsonLdService.registerNamespace(CX_POLICY_PREFIX, CX_POLICY_NS, DSP_SCOPE_V_08); jsonLdService.registerContext(TX_AUTH_CONTEXT, DSP_SCOPE_V_2025_1); - jsonLdService.registerContext(CX_POLICY_2025_09_CONTEXT, DSP_SCOPE_V_2025_1); - jsonLdService.registerContext(CX_ODRL_CONTEXT, DSP_SCOPE_V_2025_1); + + 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())) @@ -91,21 +80,4 @@ private Result> mapToFile(Map.Entry file return getResourceFile(fileEntry.getValue()) .map(file1 -> Map.entry(fileEntry.getKey(), file1)); } - - @NotNull - private Result getResourceFile(String name) { - try (var stream = getClass().getClassLoader().getResourceAsStream(name)) { - if (stream == null) { - return Result.failure(format("Cannot find resource %s", name)); - } - - var filename = Path.of(name).getFileName().toString(); - var parts = filename.split("\\."); - var tempFile = Files.createTempFile(parts[0], "." + parts[1]); - Files.copy(stream, tempFile, REPLACE_EXISTING); - return Result.success(tempFile.toFile()); - } catch (Exception e) { - return Result.failure(format("Cannot read resource %s: ", name)); - } - } } diff --git a/core/json-ld-core/src/main/resources/document/edc-v1.jsonld b/core/json-ld-core/src/main/resources/document/edc-v1.jsonld index 070030be55..3b4fc7d254 100644 --- a/core/json-ld-core/src/main/resources/document/edc-v1.jsonld +++ b/core/json-ld-core/src/main/resources/document/edc-v1.jsonld @@ -13,7 +13,7 @@ "@id": "edc:policy", "@type": "@id", "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld" + "https://w3id.org/dspace/2025/1/odrl-profile.jsonld" ] }, "createdAt": "edc:createdAt", 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 743b05d4fa..0bb5d4115c 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 @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -29,7 +30,6 @@ import java.net.URI; import static org.eclipse.tractusx.edc.jsonld.JsonLdExtension.CREDENTIALS_V_1; -import static org.eclipse.tractusx.edc.jsonld.JsonLdExtension.CX_POLICY_2025_09_CONTEXT; 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.mockito.ArgumentMatchers.any; @@ -50,7 +50,6 @@ void setup(ServiceExtensionContext context) { void initialize(ServiceExtensionContext context, JsonLdExtension extension) { extension.initialize(context); jsonLdService.registerCachedDocument(eq(CREDENTIALS_V_1), any(URI.class)); - jsonLdService.registerCachedDocument(eq(CX_POLICY_2025_09_CONTEXT), any(URI.class)); jsonLdService.registerCachedDocument(eq(SECURITY_JWS_V1), any(URI.class)); jsonLdService.registerCachedDocument(eq(SECURITY_ED25519_V1), any(URI.class)); diff --git a/core/json-ld-cx/build.gradle.kts b/core/json-ld-cx/build.gradle.kts new file mode 100644 index 0000000000..12f9b9a4a6 --- /dev/null +++ b/core/json-ld-cx/build.gradle.kts @@ -0,0 +1,34 @@ +/******************************************************************************** + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE + * + * 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(project(":spi:core-spi")) + implementation(project(":core:core-utils")) + implementation(libs.edc.spi.core) + implementation(libs.edc.spi.jsonld) + implementation(libs.dsp.spi.v2025) + implementation(libs.dsp.spi.v08) + implementation(libs.edc.lib.management.api) + testImplementation(testFixtures(libs.edc.junit)) +} 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 new file mode 100644 index 0000000000..4515fb0cc4 --- /dev/null +++ b/core/json-ld-cx/src/main/java/org/eclipse/tractusx/edc/cx/CxJsonLdExtension.java @@ -0,0 +1,75 @@ +/******************************************************************************** + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE + * + * 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.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; + +public class CxJsonLdExtension implements ServiceExtension { + + @Deprecated(since = "0.11.0") + public static final String CX_POLICY_CONTEXT = "https://w3id.org/tractusx/policy/v1.0.0"; + @Deprecated(since = "0.12.0") + 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; + + @Inject + private Monitor monitor; + + @Override + public void initialize(ServiceExtensionContext context) { + jsonLdService.registerNamespace(CX_POLICY_PREFIX, CX_POLICY_NS, DSP_SCOPE_V_08); + + jsonLdService.registerContext(CX_POLICY_2025_09_CONTEXT, DSP_SCOPE_V_2025_1); + + 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()))); + } + + private Result> mapToFile(Map.Entry fileEntry) { + return getResourceFile(fileEntry.getValue()) + .map(file1 -> Map.entry(fileEntry.getKey(), file1)); + } +} diff --git a/edc-extensions/federated-catalog/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/core/json-ld-cx/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension similarity index 87% rename from edc-extensions/federated-catalog/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension rename to core/json-ld-cx/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index 72bc8734d2..169f8223e2 100644 --- a/edc-extensions/federated-catalog/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/core/json-ld-cx/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -1,6 +1,6 @@ ################################################################################# # Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# Copyright (c) 2021,2023 Contributors to the Eclipse Foundation +# Copyright (c) 2026 SAP SE # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -18,4 +18,4 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -org.eclipse.tractusx.edc.federatedcatalog.FederatedCatalogExtension +org.eclipse.tractusx.edc.cx.CxJsonLdExtension diff --git a/core/json-ld-core/src/main/resources/document/cx-odrl.jsonld b/core/json-ld-cx/src/main/resources/document/cx-odrl.jsonld similarity index 100% rename from core/json-ld-core/src/main/resources/document/cx-odrl.jsonld rename to core/json-ld-cx/src/main/resources/document/cx-odrl.jsonld diff --git a/core/json-ld-core/src/main/resources/document/cx-policy-v1.jsonld b/core/json-ld-cx/src/main/resources/document/cx-policy-v1.jsonld similarity index 100% rename from core/json-ld-core/src/main/resources/document/cx-policy-v1.jsonld rename to core/json-ld-cx/src/main/resources/document/cx-policy-v1.jsonld diff --git a/core/json-ld-cx/src/test/java/org/eclipse/tractusx/edc/jsonld/CxJsonLdExtensionTest.java b/core/json-ld-cx/src/test/java/org/eclipse/tractusx/edc/jsonld/CxJsonLdExtensionTest.java new file mode 100644 index 0000000000..277066ec90 --- /dev/null +++ b/core/json-ld-cx/src/test/java/org/eclipse/tractusx/edc/jsonld/CxJsonLdExtensionTest.java @@ -0,0 +1,55 @@ +/******************************************************************************** + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE + * + * 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.JsonLd; +import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.tractusx.edc.cx.CxJsonLdExtension; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.net.URI; + +import static org.eclipse.tractusx.edc.cx.CxJsonLdExtension.CX_ODRL_CONTEXT; +import static org.eclipse.tractusx.edc.cx.CxJsonLdExtension.CX_POLICY_2025_09_CONTEXT; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; + +@ExtendWith(DependencyInjectionExtension.class) +public class CxJsonLdExtensionTest { + + JsonLd jsonLdService = mock(JsonLd.class); + + @BeforeEach + void setup(ServiceExtensionContext context) { + context.registerService(JsonLd.class, jsonLdService); + } + + @Test + void initialize(ServiceExtensionContext context, CxJsonLdExtension extension) { + extension.initialize(context); + jsonLdService.registerCachedDocument(eq(CX_POLICY_2025_09_CONTEXT), any(URI.class)); + jsonLdService.registerCachedDocument(eq(CX_ODRL_CONTEXT), any(URI.class)); + } +} diff --git a/docs/development/management-domains/README.md b/docs/development/management-domains/README.md deleted file mode 100644 index e6741a7b48..0000000000 --- a/docs/development/management-domains/README.md +++ /dev/null @@ -1,199 +0,0 @@ -# Management Domains Primer - -> Disclaimer: this is an incubating feature that comes without any guarantees of any sort. Changes and even complete -> removal are possible without prior notice. Due to its experimental nature, this feature is disabled by default. - -Management Domains are a way to reflect a company's internal organizational structure in the deployment of several -connectors. For details please refer to -the [official documentation](https://github.com/eclipse-edc/Connector/blob/main/docs/developer/management-domains/management-domains.md). - -## Usage in Tractus-X - -There are several reasons why a company might consider the use of Management Domains: - -- independent management of connector instances: multiple departments within a (larger) company want to maintain - independence w.r.t. their data, so they operate individual EDCs -- independent version upgrade cycles of connector instances: multiple departments may choose to upgrade their EDCs at - different intervals or velocities. **Note that this only refers to minor changes of APIs, SPIs, configuration etc. All - instances must still maintain protocol (DSP, DCP,...) compatibility!** - -For the purposes of Tractus-X, the usage of -deployment [type 2b](https://github.com/eclipse-edc/Connector/blob/main/docs/developer/management-domains/management-domains.md#type-2b-edc-catalog-server-and-controldata-plane-runtimes) -or [type 2c](https://github.com/eclipse-edc/Connector/blob/main/docs/developer/management-domains/management-domains.md#type-2c-catalog-servercontrol-plane-with-data-plane-runtime) -is assumed: - -![type 2b](https://github.com/eclipse-edc/Connector/blob/main/docs/developer/management-domains/distributed.type2.b.svg) - -Note that is possible to use a conventional Tractus-X EDC runtime as catalog server. - -### Limitations and Caveats - -All runtimes within one company share the same `participantId`, thus they are one single logical entity. They must share -the same set of VerifiableCredentials. In practice, they could either share one credential wallet instance, or have -multiple identical instances. - -## The Federated Catalog crawler - -The Federated Catalog crawler subsystem periodically scrapes target nodes (i.e. catalog servers or EDC runtimes) by -executing a catalog request. If it encounters an `Asset`, that points to another `Asset`, it will automatically recurse -down by following the link, thus building a hierarchical catalog. In other words, there can "Catalogs of Catalogs". A -special [asset type](https://github.com/eclipse-edc/Connector/blob/main/docs/developer/management-domains/management-domains.md#31-asset-and-dataset-specialization) -was introduced for this purpose. - -Every target node produces one `Catalog`, so in the end there is a `List` which contains all the assets that -are available in a particular dataspace. - -## The Federated Catalog QueryApi - -After some time, when all crawlers have returned, this list of catalogs can be queried using a new REST endpoint: - -```shell -POST /v1alpha/catalog/query -{ - "@context": { - "edc": "https://w3id.org/edc/v0.0.1/ns/" - }, - "@type": "QuerySpec" -} -``` - -the response body contains a list of catalogs as JSON-LD array (`hasPolicy` omitted for legibility). Notice -the `@type: "dcat:Catalog` -of the first `dataset` entry. This indicates that the "outer" Catalog actually contains another Catalog: - -```json -[ - { - "@id": "a6574324-8dd2-4169-adf1-f94423c5d213", - "@type": "dcat:Catalog", - "dcat:dataset": [ - { - "@id": "1af92996-0bb7-4bdd-b04e-938fe54fb27f", - "@type": "dcat:Catalog", - "dcat:dataset": [ - { - "@id": "asset-2", - "@type": "dcat:Dataset", - "odrl:hasPolicy": { - }, - "dcat:distribution": [], - "id": "asset-2" - }, - { - "@id": "asset-1", - "@type": "dcat:Dataset", - "odrl:hasPolicy": { - }, - "dcat:distribution": [], - "id": "asset-1" - } - ], - "dcat:distribution": [], - "dcat:service": { - "@id": "684635d3-acc8-4ff5-ba71-d1e968be5e3b", - "@type": "dcat:DataService", - "dcat:endpointDescription": "dspace:connector", - "dcat:endpointUrl": "http://localhost:8192/api/dsp", - "dct:terms": "dspace:connector", - "dct:endpointUrl": "http://localhost:8192/api/dsp" - }, - "dspace:participantId": "did:web:localhost%3A7093", - "participantId": "did:web:localhost%3A7093" - } - ], - "dcat:distribution": [], - "dcat:service": { - "@id": "8c99b5d6-0c46-455e-97b1-7b31f32a714b", - "@type": "dcat:DataService", - "dcat:endpointDescription": "dspace:connector", - "dcat:endpointUrl": "http://localhost:8092/api/dsp", - "dct:terms": "dspace:connector", - "dct:endpointUrl": "http://localhost:8092/api/dsp" - }, - "dspace:participantId": "did:web:localhost%3A7093", - "originator": "http://localhost:8092/api/dsp", - "participantId": "did:web:localhost%3A7093" - } -] -``` - -There is an additional optional query param `?flatten=true` that puts all `dataset` objects in a flat list for -linear consumption. Note that the hierarchy and provenance of a single `dataset` can't be restored anymore. - -## Implementation guidance - -Under the hood, a Tractus-X EDC connector leverages -the [Federated Catalog](https://github.com/eclipse-edc/FederatedCatalog/) and its crawler mechanism to periodically -scrape the dataspace. Note that without additional and explicit configuration, this feature is **disabled** -out-of-the-box! - -There are several steps a consumer EDC needs to take before being able to use it: - -### Create `CatalogAssets` - -`CatalogAssets` are assets that point to another catalog using hyperlinks. They can be thought of as pointers to another -catalog. A catalog server (on the provider side) creates `CatalogAsset` via the Management API by using the following -request body: - -```json -{ - "@id": "linked-asset-1", - "@type": "CatalogAsset", - "properties": { - "description": "This is a linked asset that points to another EDC's catalog." - }, - "dataAddress": { - "@type": "DataAddress", - "type": "HttpData", - "baseUrl": "https://another-edc.com/api/dsp" - } -} -``` - -### Enable and configure the crawler subsystem - -The following config values are used to configure the crawlers: - -| Configuration property | Helm value | default value | description | -|----------------------------------------------|---------------------------------------------|---------------|--------------------------------------------------------------------| -| `edc.catalog.cache.execution.enabled` | `controlplane.catalog.enabled` | false | enables/disables periodic crawling | -| `edc.catalog.cache.execution.period.seconds` | `controlplane.catalog.crawler.period` | 60 | period between two crawl runs | -| `edc.catalog.cache.execution.delay.seconds` | `controlplane.catalog.crawler.initialDelay` | random | initial delay before the first crawl run | -| `edc.catalog.cache.partition.num.crawlers` | `controlplane.catalog.crawler.num` | 2 | desired number of crawlers | -| `web.http.catalog.port` | `controlplane.endpoints.catalog.port` | 8085 | port of the catalog QueryApi's web context | -| `web.http.catalog.path` | `controlplane.endpoints.catalog.path` | /catalog | URL path of the catalog QueryApi's web context | -| `tx.edc.catalog.node.list.file` | `controlplane.catalog.crawler.targetsFile ` | | path to a JSON file that contains an array of `TargetNode` objects | - -all of these config values are optional and come preconfigured with defaults. - -### Configure the target nodes - -The crawler subsystem needs a list of `TargetNode` objects, which it obtains from the `TargetNodeDirectory`. Currently, -for testing purposes, there is a file-based implementation. To use it, a JSON file is needed that contains an array -of `TargetNode` objects: - -```json -[ - { - "name": "test-1", - "url": "https://nodes.com/test-1/api/dsp", - "id": "1", - "supportedProtocols": "dataspace-protocol-http" - }, - { - "name": "test-2", - "url": "https://nodes.com/test-2/api/dsp", - "id": "2", - "supportedProtocols": "dataspace-protocol-http" - } -] -``` - -On Kubernetes, a common way to achieve this is using ConfigMaps. - -## References - -- [Management Domains - documentation](https://github.com/eclipse-edc/Connector/blob/main/docs/developer/management-domains/management-domains.md) -- [Federated Catalog - documentation](https://github.com/eclipse-edc/FederatedCatalog/tree/main/docs/developer/architecture) \ No newline at end of file diff --git a/docs/migration/2026_03-Version_0.11.x_0.12.x.md b/docs/migration/2026_03-Version_0.11.x_0.12.x.md index a6cdca712f..912305fe98 100644 --- a/docs/migration/2026_03-Version_0.11.x_0.12.x.md +++ b/docs/migration/2026_03-Version_0.11.x_0.12.x.md @@ -7,25 +7,215 @@ to another. This document is not a comprehensive feature list. -* [Migration Guide `0.11.x -> 0.12.x`](#migration-guide-010x---011x) - +* [Migration Guide `0.11.x -> 0.12.x`](#migration-guide-011x---012x) + * [1. Connector Discovery](#1-connector-discovery) + * [Self-Registration of Connectors in DID Document](#self-registration-of-connectors-in-did-document) + * [Discovery of Connectors](#discovery-of-connectors) + * [Changed Param Discovery Request Body](#changed-param-discovery-request-body) + * [2. Participant ID](#2-participant-id) + * [3. Changed behavior for old policies](#3-changed-behavior-for-old-policies) + * [4. Verifiable Presentation Caching](#4-verifiable-presentation-caching) + * [5. Catalog response changes](#5-catalog-response-changes) + * [6. Deprecation of `https://w3id.org/catenax/2025/9/policy/odrl.jsonld` context](#6-deprecation-of-httpsw3idorgcatenax20259policyodrljsonld-context) + * [7. Deprecated instances](#7-deprecated-instances) -# Connector Discovery +## 1. Connector Discovery + +### Self-Registration of Connectors in DID Document + +The connector provides a new feature that automatically registers a running connectors in the DID documents service +section, so that it is published to be discovered by potential consumers. The feature is can be enabled. The following +three parameters allow you to influence the execution of this feature. + +```properties +TX_EDC_DID_SERVICE_SELF_REGISTRATION_ENABLED=true +TX_EDC_DID_SERVICE_SELF_DEREGISTRATION_ENABLED=false +TX_EDC_DID_SERVICE_SELF_REGISTRATION_ID="did:web:connector_id" +``` + +The registration enabled parameter turns on self registration on startup. For a standard one instance connector +setup, it is recommended to also enable the deregistration enabled parameter, as this automatically deregisters the +connector during shutdown. This allows a full controlled life-cycle of the availability of the connector in the +decentral discovery. For setups with a scaling connector or other scenarios, where the availability of a connector is +not bound on it, currently executed, this auto deregistration leads to issues, that is, why it can the deregistration +can be disabled explicitly. + +The third parameter is a requirement from the format given for service entries in a DID document. Such a record requires +a unique id for the connector, which is typically in the did format. The content actually is only used as a string, so +the concrete content has no further constraints bound to it. + +Be aware, that in the standard helm charts, only the first and third parameter can be set in the values file: + +```yaml +iatp: + didService: + 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" +``` + +The value for the second parameter is determined from other parameters like the scaling setting for the deployment. If +an adopter wants to influence the deregistration procedure explicitly, he has to adapt the template setting for that +parameter. + +### Discovery of Connectors + +There is a new endpoint in the management api `/v4alpha/connectordiscovery/connectors` that supports the decentral +discovery of DSP endpoints. The api takes a did as parameter `edc:counterPartyId` and does the did based connector +endpoint retrieval according to the DSP spec. I.e., it downloads the DID document, searches for service entries of type +`DataService`. For each found endpoint, the version metadata endpoint is called to determine the dsp versions supported +by the connector and the appropriate one is selected. For each connector the right connection parameters are extracted +and returned as an array of connection parameters. + +For the time being the parameter given to the endpoint can also be a BPNL, but it is strictly recommended to start with +the DID. The BPNL mechanism is only provided as legacy mechanism as long as central Catena-X mechanisms do not properly +allow to search for the DID of the counterparty. + +For a proper discovery of connectors operated by a business partner, this method is strongly recommended to be used in +a proper discover, retrieve catalog, initiate data transfer cycle! + +### Changed Param Discovery Request Body + +The already existing management api endpoint `/v4alpha/connectordiscovery/dspversionparams`, introduced in version 0.11.0 +has been adapted to be more neutral. For that reason, the endpoints payload now requires the two parameters +`counterPartyAddress` and `counterPartyId`. The latter has been renamed from the parameter name `bpnl`. It is +recommended to switch the parameter name in addressing the endpoint, for backward compatibility reasons, the parameter +`bpnl` still works but is a candidate to be removed in a later version. + +## 2. Participant ID + +In preparation of the new multi-tenancy ability of the connector, a participant context id has been introduced, that +represents the future tenant id. The new identifier is mandatory and has been added to the helm charts: + +```yaml +participant: + # -- BPN Number + id: "BPNLCHANGEME" + # -- Participant Context Id - Newly introduced id for a connector instance (needed for multitenancy) + contextId: "UUID CHANGEME" +``` +The actual setting/environment variable for the connector is named `EDC_PARTICIPANT_CONTEXT_ID`. + +The participant context id is recommended to be a uuid. A minimum requirement is, that it can be used within a url path +as segment to make it usable for a tenant id later on. + +Note, that the connector contains a code segment that prevents starting a connector, if the identifier is not set. + +## 3. Changed behavior for old policies + +There is a change when old policies are compacted in a response from the management api. The behavior in 0.12.0 is +breaking in contrast to Jupiter versions 0.10.x and earlier. The issue is, that with the redefinition of the policies, +the prefix json-ld `cx-policy` has been redefined for the new policies. + +When creating an old policy at the management api, nothing changes, as you control the json-ld namespace, i.e., by using + +```json +{ + "@context": { + "cx-policy": "https://w3id.org/catenax/policy/" + } +} +``` + +You still can refer to old policy terms in this way `cx-policy:UsagePurpose`. The issue is, that in the other direction, +when requesting a policy via the management api, the connector cannot compact anymore to `cx-policy:Usage-Purpose` +because in that direction, due to a breaking change in the Catena-X standardization, the prefix `cx-policy` is bound +to `https://w3id.org/catenax/2025/9/policy/`. + +Due to a bug in 0.11.0 json-ld compacting is not done for Catena-X specifics in the management api, so 0.11.0 already has +breaking behavior in comparison with 0.10.x and earlier. In 0.12.0, we fix these deviations, but for old policies, +based on the `https://w3id.org/catenax/policy/` namespace, we cannot provide a solution, i.e., these terms in responses +from the management api will always be fully expanded. This is the only solution, that does not add a breaking change +on the level of json-ld, but a pure json based handling of responses will see unavoidable differences. + +## 4. Verifiable Presentation Caching + +A new feature in the connector allows to cache verifiable presentations requested from the wallet to reduce the amount +of requests to the consumer wallet and to improve processing time. The feature as such is switchable, using the +boolean configuration parameter `TX_EDC_DCP_CACHE_ENABLED`. By default, it is enabled. A second parameter +`TX_EDC_DCP_CACHE_VALIDITY_SECONDS` allows for an enabled cache to define the length of the validity of a cache entry +in seconds. This defaults to 24h, as the development group rated the delayed recognition of a revoked credential as +acceptable. The settings can be changed with the mentioned parameters/environment variables. For the helm charts there +is a new section in the values file that allows the setting of the parameters. + +```yaml +iatp: + cache: + # -- Whether the Verifiable Presentation cache is enabled + enabled: true + # -- Validity of the Verifiable Presentation cache in seconds + validity: 86400 +``` +## 5. Catalog response changes + +Starting with version 0.11.0, the catalog response returned by `/v3/catalog/request` was changed +(see [walkthrough](../../docs/usage/management-api-walkthrough/04_catalog.md)). Each `distribution` entry now exposes its `format` +as a simple string (for example `AzureStorage-PUSH`, `HttpData-PULL`, `AmazonS3-PUSH`), and the top-level service attribute +is an array of `DataService` objects instead of a single object. This representation is emitted for DSP2025-1 catalogs and +should be expected by clients. The legacy structure is still emitted only when interacting with DSP0.8 connectors for backward compatibility. + +## 6. Deprecation of `https://w3id.org/catenax/2025/9/policy/odrl.jsonld` context + +The Catena-X Data Sovereignty Expert Group has decommissioned the 'odrl' context named +`https://w3id.org/catenax/2025/9/policy/odrl.jsonld` as this was a redundant copy of the original dataspace +subset of ODRL as defined in the context `https://w3id.org/dspace/2025/1/odrl-profile.jsonld`. The current +version still handles the obsolete context properly, when seen as input, but JSON-LD compacting will not +consider the old context. + +Note: This does not affect the `https://w3id.org/catenax/2025/9/policy/context.jsonld` context which defines +the policy constraints of the Catena-X policy framework, it only affects the specification of the ODRL defined +elements usable for expressing policies. + +## 7. Deprecated instances + +The `Data Plane Selector Configuration Extension` has been removed, as it has been deprecated since version 0.7.2. +Additionally, several configuration parameters deprecated since version 0.7.x have also been removed. +Please use the updated configuration parameters instead. + +[VaultSeedExtension](../../edc-controlplane/edc-runtime-memory/src/main/java/org/eclipse/tractusx/edc/vault/memory/VaultSeedExtension.java): + +| Old value | New value | New environment variable | +|----------------------|------------------------|--------------------------| +| `edc.vault.secrets` | `tx.edc.vault.secrets` | `TX_EDC_VAULT_SECRETS` | + + +[BdrsClientExtension](../../edc-extensions/bdrs-client/src/main/java/org/eclipse/tractusx/edc/identity/mapper/BdrsClientExtension.java): + +| Old value | New value | New environment variable | +|--------------------------------------|-----------------------------------------|-----------------------------------------| +| `tx.iam.iatp.bdrs.server.url` | `tx.edc.iam.iatp.bdrs.server.url` | `TX_EDC_IAM_IATP_BDRS_SERVER_URL` | +| `tx.iam.iatp.credentialservice.url` | `tx.edc.iam.iatp.credentialservice.url` | `TX_EDC_IAM_IATP_CREDENTIALSERVICE_URL` | +| `tx.iam.iatp.bdrs.cache.validity` | `tx.edc.iam.iatp.bdrs.cache.validity` | `TX_EDC_IAM_IATP_BDRS_CACHE_VALIDITY` | -## Self-Registration of Connectors in DID Document +[DataPlaneProxyConsumerApiExtension](../../edc-extensions/dataplane/dataplane-proxy/edc-dataplane-proxy-consumer-api/src/main/java/org/eclipse/tractusx/edc/dataplane/proxy/consumer/api/DataPlaneProxyConsumerApiExtension.java): -Enable self registration and deregistration +| Old value | New value | New environment variable | +|---------------------------------------|-----------------------------------------------|-----------------------------------------------| +| `tx.dpf.consumer.proxy.port` | `tx.edc.dpf.consumer.proxy.port` | `TX_EDC_DPF_CONSUMER_PROXY_PORT` | +| `tx.dpf.consumer.proxy.thread.pool` | `tx.edc.dpf.consumer.proxy.thread.pool` | `TX_EDC_DPF_CONSUMER_PROXY_THREAD_POOL` | +| `edc.api.auth.key.alias` | `tx.edc.dpf.consumer.proxy.auth.apikey.alias` | `TX_EDC_DPF_CONSUMER_PROXY_AUTH_APIKEY_ALIAS` | +| `edc.api.auth.key` | `tx.edc.dpf.consumer.proxy.auth.apikey` | `TX_EDC_DPF_CONSUMER_PROXY_AUTH_APIKEY` | -## Discovery of Connectors +[DataPlaneTokenRefreshServiceExtension](../../edc-extensions/dataplane/dataplane-token-refresh/token-refresh-core/src/main/java/org/eclipse/tractusx/edc/dataplane/tokenrefresh/core/DataPlaneTokenRefreshServiceExtension.java): -DID document download +| Old value | New value | New environment variable | +|---------------------------------------|-------------------------------------------|-------------------------------------------| +| `edc.dataplane.token.expiry.tolerance`| `tx.edc.dataplane.token.expiry.tolerance` | `TX_EDC_DATAPLANE_TOKEN_EXPIRY_TOLERANCE` | +| `edc.dataplane.token.refresh.endpoint`| `tx.edc.dataplane.token.refresh.endpoint` | `TX_EDC_DATAPLANE_TOKEN_REFRESH_ENDPOINT` | +| `edc.dataplane.token.expiry` | `tx.edc.dataplane.token.expiry` | `TX_EDC_DATAPLANE_TOKEN_EXPIRY` | -## Changed Param Discovery Request Body +[RemoteTokenServiceClientExtension](../../edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java): -bpnl -> counterPartyId +| Old value | New value | New environment variable | +|------------------------|----------------------------|--------------------------| +| `edc.iam.sts.dim.url` | `tx.edc.iam.sts.dim.url` | `TX_EDC_IAM_STS_DIM_URL` | -# Participant ID +[AbstractPostgresqlMigrationExtension](../../edc-extensions/migrations/postgresql-migration-lib/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java): -Set new setting --> Implication on migration +| Old value | New value | New environment variable | +|---------------------------------------------------------------------|---------------------------------------------------|---------------------------------------------------| +| `org.eclipse.tractusx.edc.postgresql.migration..enabled` | `tx.edc.postgresql.migration..enabled` | `TX_EDC_POSTGRESQL_MIGRATION__ENABLED` | +| `org.eclipse.tractusx.edc.postgresql.migration.schema` | `tx.edc.postgresql.migration.schema` | `TX_EDC_POSTGRESQL_MIGRATION_SCHEMA` | 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 new file mode 100644 index 0000000000..fa465ce168 --- /dev/null +++ b/docs/migration/2026_06-Version_0.12.x_0.13.x.md @@ -0,0 +1,40 @@ +# Migration Guide `0.12.x -> 0.13.x` + +This document outlines the necessary changes for migrating your tractusx-edc installation from versions 0.12.x to 0.13.x. +It also outlines some points that adopters and operators should pay close attention to when migrating from one version +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](#2-federate-catalog-removal) + + +## 1. Federate Catalog removal + +The Federate Catalog feature has not been proven to be usable, that's why it will be removed. The deletion of the table +`edc_federated_catalog` will be done automatically by migration script. If you need to keep the data, please make sure +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. +Additionally, several configuration parameters deprecated since version 0.8.x have also been removed. +Please use the updated configuration parameters instead. + +[SqlBusinessPartnerGroupStoreExtension](../../edc-extensions/bpn-validation/business-partner-store-sql/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/store/SqlBusinessPartnerGroupStoreExtension.java): + +| Old value | New value | New environment variable | +|---------------------------|--------------------------------|--------------------------------| +| `edc.datasource.bpn.name` | `edc.sql.store.bpn.datasource` | `EDC_SQL_STORE_BPN_DATASOURCE` | + + +[SqlEdrLockExtension](../../edc-extensions/edr/edr-index-lock-sql/src/main/java/org/eclipse/tractusx/edc/edr/index/sql/lock/SqlEdrLockExtension.java): + +| Old value | New value | New environment variable | +|---------------------------|--------------------------------|--------------------------------| +| `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 diff --git a/docs/usage/management-api-walkthrough/02_policies.md b/docs/usage/management-api-walkthrough/02_policies.md index 38ba30e1c1..4e948f5be7 100644 --- a/docs/usage/management-api-walkthrough/02_policies.md +++ b/docs/usage/management-api-walkthrough/02_policies.md @@ -9,13 +9,13 @@ The `Policy` object is extensible. EDC generally follows the subset that the [Dataspace Protocol](https://eclipse-dataspace-protocol-base.github.io/DataspaceProtocol/2025-1/message/schema/contract-schema.json#/definitions/Policy) has selected from [ODRL](https://www.w3.org/TR/odrl-model/#policy). -| Variable | Content | -|----------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `@context` | In JSON-LD, `@context` is a fundamental concept used to define the mapping of terms used within the JSON-LD document to specific IRIs (Internationalized Resource Identifiers). It provides a way to establish a shared understanding of the vocabulary used in a JSON-LD document, making it possible to create structured and semantically rich data that can be easily integrated with other data sources on the web. You can choose to bind prefixes to namespaces manually via json properties. However, importing existing remote contexts like `"@context":[ "https://w3id.org/catenax/2025/9/policy/odrl.jsonld" ]` is usually less error-prone and strongly encouraged by the examples. | -| `policy`.`@type` | `@type` is a property in every json-ld object that describes which class it belongs to. In this context, the only accepted value is `Set`. `Set` is aimed at scenarios where there is an open criteria for the semantics of the policy expressions. | -| `policy`.`permission`
`policy`.`obligation`
`policy`.`prohibition` | These properties define the context of what may, may not under which condition be done with the Dataset in question. | -| `policy`.`permission/oblication/prohibition`.`action` | Currently only the actions "use" (reused from ODRL) and "access" (specific to Catena-X) are conventions in the Dataspace. In the context of tractusx-edc, `action` should only be used for access policies and `use` should only be used for usage policies in a [`ContractDefinition`](./03_contractdefinitions.md). | -| `policy`.`permission/oblication/prohibition`.`constraint` | A list of `Constraint` objects that each represent a boolean/logical expression. It binds an `action` to certain rules. The `leftOperand` instances must clearly be defined to indicate the semantics of the `Constraint`. In Catena-X, some `leftOperand`s of a `Constraint` are associated with a check on specific verifiable credentials (VC). As most are use-case-agreements, [this notation](https://github.com/eclipse-tractusx/tractusx-profiles/blob/main/cx/policy/specs/policy.mapping.md) is useful. **Right Operand:** The rightOperand is the value of the Constraint that is to be compared to the leftOperand. | +| Variable | Content | +|----------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `@context` | In JSON-LD, `@context` is a fundamental concept used to define the mapping of terms used within the JSON-LD document to specific IRIs (Internationalized Resource Identifiers). It provides a way to establish a shared understanding of the vocabulary used in a JSON-LD document, making it possible to create structured and semantically rich data that can be easily integrated with other data sources on the web. You can choose to bind prefixes to namespaces manually via json properties. However, importing existing remote contexts like `"@context":[ "https://w3id.org/dspace/2025/1/odrl-profile.jsonld" ]` is usually less error-prone and strongly encouraged by the examples. | +| `policy`.`@type` | `@type` is a property in every json-ld object that describes which class it belongs to. In this context, the only accepted value is `Set`. `Set` is aimed at scenarios where there is an open criteria for the semantics of the policy expressions. | +| `policy`.`permission`
`policy`.`obligation`
`policy`.`prohibition` | These properties define the context of what may, may not under which condition be done with the Dataset in question. | +| `policy`.`permission/oblication/prohibition`.`action` | Currently only the actions "use" (reused from ODRL) and "access" (specific to Catena-X) are conventions in the Dataspace. In the context of tractusx-edc, `action` should only be used for access policies and `use` should only be used for usage policies in a [`ContractDefinition`](./03_contractdefinitions.md). | +| `policy`.`permission/oblication/prohibition`.`constraint` | A list of `Constraint` objects that each represent a boolean/logical expression. It binds an `action` to certain rules. The `leftOperand` instances must clearly be defined to indicate the semantics of the `Constraint`. In Catena-X, some `leftOperand`s of a `Constraint` are associated with a check on specific verifiable credentials (VC). As most are use-case-agreements, [this notation](https://github.com/eclipse-tractusx/tractusx-profiles/blob/main/cx/policy/specs/policy.mapping.md) is useful. **Right Operand:** The rightOperand is the value of the Constraint that is to be compared to the leftOperand. | ## Policies in Catena-X @@ -107,7 +107,7 @@ Content-Type: application/json ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" @@ -203,7 +203,7 @@ Agreement. The signing of the Agreement should be checked at the time of contrac ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" @@ -232,7 +232,7 @@ Agreement. The signing of the Agreement should be checked at the time of contrac ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" @@ -272,7 +272,7 @@ DismantlerCredential"). ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" @@ -301,7 +301,7 @@ DismantlerCredential"). ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" @@ -344,7 +344,7 @@ that the Connector interprets policies it can't evaluate as true by default. A c ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" @@ -373,7 +373,7 @@ it. ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" @@ -404,7 +404,7 @@ Constraints can be chained together via logical constraints. This is currently p ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" diff --git a/docs/usage/management-api-walkthrough/04_catalog.md b/docs/usage/management-api-walkthrough/04_catalog.md index dabb1b9f86..69926339d5 100644 --- a/docs/usage/management-api-walkthrough/04_catalog.md +++ b/docs/usage/management-api-walkthrough/04_catalog.md @@ -169,12 +169,12 @@ The returned payload is a `dcat:Catalog` as specified by the DSP version used in "@type": "Dataset", "hasPolicy": { "@id": "MQ==:MQ==:M2ZmZDRhY2MtMzkyNy00NGI4LWJlZDItNDcwY2RiZGRjN2Ex", - "@type": "odrl:Offer", + "@type": "Offer", "permission": { "action": "use", "constraint": { "leftOperand": "FrameworkAgreement", - "operand": "eq", + "operator": "eq", "rightOperand": "DataExchangeGovernance:1.0" }, "prohibition": [], @@ -183,55 +183,50 @@ The returned payload is a `dcat:Catalog` as specified by the DSP version used in }, "distribution": [ { - "@type": "dcat:Distribution", - "format": { - "@id": "AzureStorage-PUSH" - }, + "@type": "Distribution", + "format": "AzureStorage-PUSH", "accessService": { "@id": "1338f9ac-1728-4a7e-b3dc-31fe5bc109f6", "@type": "DataService", - "terms": "connector", - "endpointUrl": "https://provider.domain.com/api/v1/dsp/2025-1" + "endpointDescription": "dspace:connector", + "endpointURL": "https://provider.domain.com/api/v1/dsp/2025-1" } }, { - "@type": "dcat:Distribution", - "format": { - "@id": "HttpData-PULL" - }, + "@type": "Distribution", + "format": "HttpData-PULL", "accessService": { "@id": "1338f9ac-1728-4a7e-b3dc-31fe5bc109f6", "@type": "DataService", - "terms": "connector", - "endpointUrl": "https://provider.domain.com/api/v1/dsp/2025-1" + "endpointDescription": "dspace:connector", + "endpointURL": "https://provider.domain.com/api/v1/dsp/2025-1" } }, { "@type": "Distribution", - "format": { - "@id": "AmazonS3-PUSH" - }, + "format":"AmazonS3-PUSH", "accessService": { "@id": "1338f9ac-1728-4a7e-b3dc-31fe5bc109f6", - "@type": "dcat:DataService", - "terms": "connector", - "endpointUrl": "https://provider.domain.com/api/v1/dsp/2025-1" + "@type": "DataService", + "endpointDescription": "dspace:connector", + "endpointURL": "https://provider.domain.com/api/v1/dsp/2025-1" } } ], "description": "Product Connector Demo Asset 1", "id": "1" }, - "service": { - "@id": "1338f9ac-1728-4a7e-b3dc-31fe5bc109f6", - "@type": "dcat:DataService", - "terms": "connector", - "endpointUrl": "https://provider.domain.com/api/v1/dsp/2025-1" - }, + "service": [ + { + "@id": "1338f9ac-1728-4a7e-b3dc-31fe5bc109f6", + "@type": "DataService", + "endpointDescription": "dspace:connector", + "endpointURL": "https://provider.domain.com/api/v1/dsp/2025-1" + } + ], "@context": [ "https://w3id.org/tractusx/auth/v1.0.0", "https://w3id.org/catenax/2025/9/policy/context.jsonld", - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", "https://w3id.org/dspace/2025/1/context.jsonld", "https://w3id.org/edc/dspace/v0.0.1" ] diff --git a/docs/usage/management-api-walkthrough/05_contractnegotiations.md b/docs/usage/management-api-walkthrough/05_contractnegotiations.md index 98cfbe5611..ccad402762 100644 --- a/docs/usage/management-api-walkthrough/05_contractnegotiations.md +++ b/docs/usage/management-api-walkthrough/05_contractnegotiations.md @@ -20,7 +20,7 @@ Content-Type: application/json ```json { "@context": [ - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "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/" @@ -34,9 +34,9 @@ Content-Type: application/json "@id": "{{OFFER_ID}}", "target": "{{ASSET_ID}}", "assigner": "{{PROVIDER_IDENTIFIER}}", - "permission": {{OFFER_ODRL_PERMISSION}}, - "prohibition": {{OFFER_ODRL_PROHIBITION}}, - "obligation": {{OFFER_ODRL_OBLIGATION}} + "permission": [], + "prohibition": [], + "obligation": [] }, "callbackAddresses": [ { @@ -61,7 +61,9 @@ section which refers to an existing published context definition. - `protocol` is the providers' supported protocol - In the `policy` section, the Data Consumer specifies the Data Offer for the negotiation. As there may be multiple Data Offers for the same DataSet, the Data Consumer must choose one. - It must hold an identical copy of the Data Offer's contract policy as provided via the catalog-API in the `odrl:hasPolicy` field plus: + It must hold an identical copy of the Data Offer's contract policy as provided via the catalog-API in the `odrl:hasPolicy` + field. Especially the `permission`, `prohibition` and `obligation` fields must contain the exact same `odrl` clauses as + found in the offer. In addition, two more properties are required: - `assigner` must hold the identifier of the Provider (BPN OR DID, as returned in the catalog response) - `target` must be the id of the EDC-Asset/dcat:DataSet that the offer was made for. - `callbackAddresses` is a list of Consumer-side endpoints that the Provider's Data Plane writes events to. @@ -88,7 +90,6 @@ the `@id` property. "@context": [ "https://w3id.org/tractusx/auth/v1.0.0", "https://w3id.org/catenax/2025/9/policy/context.jsonld", - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", "https://w3id.org/dspace/2025/1/context.jsonld", "https://w3id.org/edc/dspace/v0.0.1" ] @@ -133,7 +134,6 @@ that will look like this: "@context": [ "https://w3id.org/tractusx/auth/v1.0.0", "https://w3id.org/catenax/2025/9/policy/context.jsonld", - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", "https://w3id.org/dspace/2025/1/context.jsonld", "https://w3id.org/edc/dspace/v0.0.1" ] diff --git a/docs/usage/management-api-walkthrough/06_transferprocesses.md b/docs/usage/management-api-walkthrough/06_transferprocesses.md index 4d796741f6..69efad8e16 100644 --- a/docs/usage/management-api-walkthrough/06_transferprocesses.md +++ b/docs/usage/management-api-walkthrough/06_transferprocesses.md @@ -42,13 +42,11 @@ Content-Type: application/json "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, "@type": "TransferRequest", - "assetId": "{{ASSET_ID}}", "contractId": "{{CONTRACT_AGREEMENT_ID}}", "counterPartyAddress": "{{CONNECTOR_ADDRESS}}", "dataDestination": { "type": "" }, - "privateProperties": {}, "protocol": "dataspace-protocol-http:2025-1", "transferType": "HttpData-PULL", "callbackAddresses": [ @@ -68,7 +66,6 @@ Content-Type: application/json } ``` -- `assetId` is the id of the [asset](01_assets.md) that a transfer process should be triggered for. - `counterPartyAddress` is the DSP-endpoint of the Data Provider (usually ending on /api/v1/dsp). - `contractId` represents the Contract Agreement that the Provider and Consumer agreed on during the [Contract Negotiation](05_contractnegotiations.md) phase. diff --git a/docs/usage/management-api-walkthrough/07_edrs.md b/docs/usage/management-api-walkthrough/07_edrs.md index c926e765ea..75dbd0b89b 100644 --- a/docs/usage/management-api-walkthrough/07_edrs.md +++ b/docs/usage/management-api-walkthrough/07_edrs.md @@ -41,7 +41,7 @@ Content-Type: application/json { "@context": [ "https://w3id.org/catenax/2025/9/policy/context.jsonld", - "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "https://w3id.org/dspace/2025/1/odrl-profile.jsonld", { "@vocab": "https://w3id.org/edc/v0.0.1/ns/" } diff --git a/edc-controlplane/edc-controlplane-base/build.gradle.kts b/edc-controlplane/edc-controlplane-base/build.gradle.kts index 934e519773..660c369368 100644 --- a/edc-controlplane/edc-controlplane-base/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-base/build.gradle.kts @@ -27,21 +27,45 @@ configurations.all { // edr-cache-api excluded due to edr controller signature clash with tx-edr-api-v2 that provides same functionality with token auto_refresh capability exclude(group = "org.eclipse.edc", module = "edr-cache-api") - // decentralized-claims-sts-remote-client excluded because we have the tx-dcp-sts-dim that takes care to define the correct client in case of DIM + // 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") } 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") } runtimeOnly(libs.edc.bom.controlplane.dcp) - runtimeOnly(libs.edc.bom.federatedcatalog.base) - runtimeOnly(libs.edc.bom.federatedcatalog.dcp) - implementation(project(":core:edr-core")) implementation(project(":core:json-ld-core")) + implementation(project(":core:json-ld-cx")) implementation(project(":edc-extensions:log4j2-monitor")) implementation(project(":edc-extensions:agreements")) implementation(project(":edc-extensions:agreements-bpns")) @@ -50,12 +74,12 @@ dependencies { implementation(project(":edc-extensions:cx-policy")) implementation(project(":edc-extensions:cx-policy-legacy")) implementation(project(":edc-extensions:data-flow-properties-provider")) + implementation(project(":edc-extensions:dcp:cx-dcp")) implementation(project(":edc-extensions:dcp:tx-dcp")) - implementation(project(":edc-extensions:dcp:tx-dcp-sts-dim")) + implementation(project(":edc-extensions:dcp:tx-dcp-sts-div")) 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:federated-catalog")) implementation(project(":edc-extensions:provision-additional-headers")) implementation(project(":edc-extensions:tokenrefresh-handler")) implementation(project(":edc-extensions:validators:empty-asset-selector")) @@ -65,7 +89,7 @@ dependencies { implementation(project(":edc-extensions:token-interceptor")) implementation(project(":edc-extensions:event-subscriber")) implementation(project(":edc-extensions:did-document:did-document-service-self-registration")) - implementation(project(":edc-extensions:did-document:did-document-service-dim")) + implementation(project(":edc-extensions:did-document:did-document-service-div")) runtimeOnly(libs.bundles.edc.monitoring) runtimeOnly(libs.edc.aws.validator.data.address.s3) 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 073b26db84..8349f2fc7c 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 @@ -26,16 +26,17 @@ plugins { } dependencies { - val edcVersion = "0.14.1" - val txVersion = "0.11.2" + 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") implementation("org.eclipse.edc:vault-hashicorp:$edcVersion") + 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("org.eclipse.tractusx.edc:tx-dcp:${txVersion}") + implementation("org.eclipse.tractusx.edc:tx-dcp:$txVersion") } tasks.withType { diff --git a/edc-controlplane/edc-controlplane-construct-x/local/README.md b/edc-controlplane/edc-controlplane-construct-x/local/README.md index 72ccb8a0b7..dac9e8daca 100644 --- a/edc-controlplane/edc-controlplane-construct-x/local/README.md +++ b/edc-controlplane/edc-controlplane-construct-x/local/README.md @@ -17,7 +17,7 @@ It will start the following containers on your local machine: Before anything else, please make sure you have the docker images for con-x-controlplane-postgresql-hashicorp-vault in your local docker repository, see [here](../con-x-controlplane-postgresql-hashicorp-vault/README.md) and [here](../../../edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-hashicorp-vault/README.md). -Beyond that, you need to obtain the docker images needed to run the identity hub and the issuer services. In order to do so, please checckout this [repository](https://github.com/FraunhoferISST/dev-identity-services) and clone it onto your local machine. The upper section of this [README](https://github.com/FraunhoferISST/dev-identity-services/blob/main/runtimes/dev/README.md) informs +Beyond that, you need to obtain the docker images needed to run the identity hub and the issuer services. In order to do so, please check out this [repository](https://github.com/FraunhoferISST/dev-identity-services) and clone it onto your local machine. The upper section of this [README](https://github.com/FraunhoferISST/dev-identity-services/blob/main/runtimes/dev/README.md) informs you about the steps necessary to create the docker images. 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 5bd7a7f464..bf1c383ed2 100644 --- a/edc-controlplane/edc-controlplane-construct-x/local/docker-compose.yaml +++ b/edc-controlplane/edc-controlplane-construct-x/local/docker-compose.yaml @@ -65,7 +65,6 @@ services: shared-postgres: container_name: shared-postgres image: postgres:16.4-alpine - pull_policy: if_not_present environment: - POSTGRES_USER=admin - POSTGRES_PASSWORD=password @@ -82,7 +81,6 @@ services: shared-vault: container_name: shared-vault image: vault:1.13.3 - pull_policy: if_not_present command: server -dev -dev-root-token-id=vaultsecret0123456789 -dev-listen-address=0.0.0.0:8200 environment: VAULT_ADDR: http://0.0.0.0:8200 @@ -101,7 +99,6 @@ services: vault-init: container_name: vault-init image: alpine:3.19 - pull_policy: if_not_present depends_on: shared-vault: condition: service_healthy @@ -243,8 +240,8 @@ services: depends_on: shared-postgres: condition: service_healthy - shared-vault: - condition: service_healthy + vault-init: + condition: service_completed_successfully entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: - "5005:5005" # Debugger @@ -288,8 +285,8 @@ services: depends_on: shared-postgres: condition: service_healthy - shared-vault: - condition: service_healthy + vault-init: + condition: service_completed_successfully entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: - "5008:5005" # Debugger @@ -347,22 +344,21 @@ services: depends_on: shared-postgres: condition: service_healthy - shared-vault: - condition: service_healthy + vault-init: + condition: service_completed_successfully entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: - "5006:5005" # Debugger - "39000:9000" # Default port - "39010:9010" # Management API - "39020:9020" # DSP API - networks: - con-x-test-network provider-dataplane: container_name: provider-dataplane image: con-x-dataplane-postgresql-hashicorp-vault:latest - pull_policy: if_not_present + pull_policy: never environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 - web.http.public.port=9500 @@ -390,12 +386,11 @@ services: - edc.iam.sts.oauth.token.url=http://provider-idhub:9292/api/sts/token - edc.iam.sts.oauth.client.id=did:web:provider-idhub:user:provider - edc.iam.issuer.id=did:web:provider-idhub:user:provider - depends_on: shared-postgres: condition: service_healthy - shared-vault: - condition: service_healthy + vault-init: + condition: service_completed_successfully entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: - "5007:5005" # Debugger diff --git a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/build.gradle.kts b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/build.gradle.kts index 379efb01e7..a88a3d133a 100644 --- a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/build.gradle.kts +++ b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/build.gradle.kts @@ -17,9 +17,6 @@ * * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ - -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - plugins { `java-library` id("application") @@ -35,7 +32,6 @@ dependencies { implementation(project(":edc-controlplane:edc-controlplane-base")) runtimeOnly(libs.edc.bom.controlplane.feature.sql) - runtimeOnly(libs.edc.bom.federatedcatalog.feature.sql) implementation(project(":edc-extensions:agreements:retirement-evaluation-store-sql")) implementation(project(":edc-extensions:agreements-bpns:bpns-evaluation-store-sql")) diff --git a/edc-dataplane/edc-dataplane-base/build.gradle.kts b/edc-dataplane/edc-dataplane-base/build.gradle.kts index 8b91ace468..c31bc0f0fc 100644 --- a/edc-dataplane/edc-dataplane-base/build.gradle.kts +++ b/edc-dataplane/edc-dataplane-base/build.gradle.kts @@ -23,7 +23,34 @@ plugins { id(libs.plugins.swagger.get().pluginId) } +configurations.all { + exclude(group = "org.eclipse.edc", module = "data-plane-util") +} + 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")) @@ -33,7 +60,7 @@ dependencies { implementation(project(":edc-extensions:dataplane:dataplane-proxy:edc-dataplane-proxy-consumer-api")) implementation(project(":edc-extensions:dataplane:dataplane-token-refresh:token-refresh-api")) implementation(project(":edc-extensions:dataplane:dataplane-token-refresh:token-refresh-core")) - implementation(project(":edc-extensions:dcp:tx-dcp-sts-dim")) + implementation(project(":edc-extensions:dcp:tx-dcp-sts-div")) 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")) 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 d4248bb096..bbd4b63678 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 @@ -30,14 +30,16 @@ configurations.all { } dependencies { - val edcVersion = "0.14.1" - val txVersion = "0.11.2" + 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}") + implementation("org.eclipse.edc:dataplane-feature-sql-bom:$edcVersion") + implementation("org.eclipse.edc:vault-hashicorp:$edcVersion") + + implementation("org.eclipse.edc:participant-context-config-core:$edcVersion") implementation("org.eclipse.tractusx.edc:dataplane-public-api-v2:$txVersion") - implementation("org.eclipse.tractusx.edc:dataplane-util:${txVersion}") + implementation("org.eclipse.tractusx.edc:dataplane-util:$txVersion") } 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 fc29af9d04..8a9fb4c72f 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 @@ -29,6 +29,7 @@ import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; +import org.eclipse.tractusx.edc.agreements.bpns.spi.store.AgreementsBpnsStore; import org.eclipse.tractusx.edc.agreements.bpns.store.sql.PostgresAgreementsBpnsStatements; import org.eclipse.tractusx.edc.agreements.bpns.store.sql.SqlAgreementsBpnsStatements; import org.eclipse.tractusx.edc.agreements.bpns.store.sql.SqlAgreementsBpnsStore; @@ -57,7 +58,7 @@ public class SqlAgreementsBpnsStoreExtension implements ServiceExtension { private SqlAgreementsBpnsStatements statements; @Provider - public SqlAgreementsBpnsStore sqlStore(ServiceExtensionContext context) { + 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/bpn-validation/README.md b/edc-extensions/bpn-validation/README.md index 2e1e5550ca..53210af39b 100644 --- a/edc-extensions/bpn-validation/README.md +++ b/edc-extensions/bpn-validation/README.md @@ -46,7 +46,7 @@ The following example demonstrates a full JSON-LD structure in expanded form, co { "@type": "https://w3id.org/edc/v0.0.1/ns/PolicyDefinitionDto", "https://w3id.org/edc/v0.0.1/ns/policy": { - "@context": "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "@context": "https://w3id.org/dspace/2025/1/odrl-profile.jsonld", "permission": { "action": "USE", "constraint": { @@ -92,7 +92,7 @@ the policy. Here, only the ODRL `eq"` operator is supported, and the `rightOpera { "@type": "https://w3id.org/edc/v0.0.1/ns/PolicyDefinitionDto", "https://w3id.org/edc/v0.0.1/ns/policy": { - "@context": "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "@context": "https://w3id.org/dspace/2025/1/odrl-profile.jsonld", "permission": [ { "action": "USE", @@ -124,7 +124,7 @@ In case multiple BPNs are to be white-listed, the policy would contain multiple { "@type": "https://w3id.org/edc/v0.0.1/ns/PolicyDefinitionDto", "https://w3id.org/edc/v0.0.1/ns/policy": { - "@context": "https://w3id.org/catenax/2025/9/policy/odrl.jsonld", + "@context": "https://w3id.org/dspace/2025/1/odrl-profile.jsonld", "permission": [ { "action": "USE", diff --git a/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/BusinessPartnerGroupApiExtension.java b/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/BusinessPartnerGroupApiExtension.java index 8a5a34545e..ae33496d1e 100644 --- a/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/BusinessPartnerGroupApiExtension.java +++ b/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/BusinessPartnerGroupApiExtension.java @@ -29,7 +29,6 @@ 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.api.bpn.v1.BusinessPartnerGroupApiV1Controller; import org.eclipse.tractusx.edc.api.bpn.v3.BusinessPartnerGroupApiV3Controller; import org.eclipse.tractusx.edc.validation.businesspartner.spi.observe.BusinessPartnerObservableImpl; import org.eclipse.tractusx.edc.validation.businesspartner.spi.store.BusinessPartnerStore; @@ -59,13 +58,6 @@ public void initialize(ServiceExtensionContext context) { var businessPartnerObservable = new BusinessPartnerObservableImpl(); businessPartnerObservable.registerListener(new BusinessPartnerEventListener(clock, eventRouter)); - webService.registerResource(ApiContext.MANAGEMENT, new BusinessPartnerGroupApiV1Controller( - businessPartnerStore, businessPartnerObservable, context.getMonitor() - )); - webService.registerDynamicResource(ApiContext.MANAGEMENT, BusinessPartnerGroupApiV1Controller.class, - new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, "MANAGEMENT_API")); - - webService.registerResource(ApiContext.MANAGEMENT, new BusinessPartnerGroupApiV3Controller( businessPartnerStore, businessPartnerObservable )); diff --git a/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1.java b/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1.java deleted file mode 100644 index 2510020acc..0000000000 --- a/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1.java +++ /dev/null @@ -1,103 +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 - */ - -package org.eclipse.tractusx.edc.api.bpn.v1; - -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.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 org.eclipse.edc.web.spi.ApiErrorDetail; - -import java.util.Set; - -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; - -@OpenAPIDefinition(info = @Info(description = "With this API clients can create, read, update and delete BusinessPartnerNumber groups. It allows the assigning of BPNs to groups.", title = "Business Partner Group API")) -@Tag(name = "Business Partner Group") -@Deprecated(since = "0.8.0") -public interface BusinessPartnerGroupApiV1 { - - - @Operation(description = "Resolves all groups for a particular BPN", - deprecated = true, - responses = { - @ApiResponse(responseCode = "200", description = "An object containing an array with the assigned groups"), - @ApiResponse(responseCode = "404", description = "No entry for the given BPN was found"), - @ApiResponse(responseCode = "400", description = "Request body was malformed", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) - }) - JsonObject resolveV1(@Parameter(name = "bpn", description = "The business partner number") String bpn); - - @Operation(description = "Deletes the entry for a particular BPN", - deprecated = true, - responses = { - @ApiResponse(responseCode = "204", description = "The object was successfully deleted"), - @ApiResponse(responseCode = "404", description = "No entry for the given BPN was found"), - @ApiResponse(responseCode = "400", description = "Request body was malformed", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) - }) - void deleteEntryV1(@Parameter(name = "bpn", description = "The business partner number") String bpn); - - @Operation(description = "Updates the entry for a particular BPN", - requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ListSchema.class))), - deprecated = true, - responses = { - @ApiResponse(responseCode = "204", description = "The object was successfully updated"), - @ApiResponse(responseCode = "404", description = "No entry for the given BPN was found"), - @ApiResponse(responseCode = "400", description = "Request body was malformed", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) - }) - void updateEntryV1(JsonObject object); - - @Operation(description = "Creates an entry for a particular BPN", - requestBody = @RequestBody(content = @Content(schema = @Schema(implementation = ListSchema.class))), - deprecated = true, - responses = { - @ApiResponse(responseCode = "204", description = "The object was successfully created"), - @ApiResponse(responseCode = "409", description = "An entry already exists for that BPN"), - @ApiResponse(responseCode = "400", description = "Request body was malformed", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))) - }) - void createEntryV1(JsonObject entry); - - - @Schema(name = "List", example = ListSchema.EXAMPLE, deprecated = true) - record ListSchema( - @Schema(name = ID) String id, - Set groups - ) { - public static final String EXAMPLE = """ - { - "@context": { - "tx": "https://w3id.org/tractusx/v0.0.1/ns/" - }, - "@id": "tx:BPN000001234", - "tx:groups": ["group1", "group2", "group3"] - } - """; - } -} diff --git a/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1Controller.java b/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1Controller.java deleted file mode 100644 index 105aaf6247..0000000000 --- a/edc-extensions/bpn-validation/bpn-validation-api/src/main/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1Controller.java +++ /dev/null @@ -1,85 +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 - */ - -package org.eclipse.tractusx.edc.api.bpn.v1; - -import io.swagger.v3.oas.annotations.parameters.RequestBody; -import jakarta.json.JsonObject; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.tractusx.edc.api.bpn.BaseBusinessPartnerGroupApiController; -import org.eclipse.tractusx.edc.validation.businesspartner.spi.observe.BusinessPartnerObservable; -import org.eclipse.tractusx.edc.validation.businesspartner.spi.store.BusinessPartnerStore; - -import static org.eclipse.edc.api.ApiWarnings.deprecationWarning; - - -@Consumes({MediaType.APPLICATION_JSON}) -@Produces({MediaType.APPLICATION_JSON}) -@Path("/business-partner-groups") -@Deprecated(since = "0.8.0") -public class BusinessPartnerGroupApiV1Controller extends BaseBusinessPartnerGroupApiController implements BusinessPartnerGroupApiV1 { - - private final Monitor monitor; - - public BusinessPartnerGroupApiV1Controller(BusinessPartnerStore businessPartnerService, - BusinessPartnerObservable businessPartnerObservable, Monitor monitor) { - super(businessPartnerService, businessPartnerObservable); - this.monitor = monitor.withPrefix(getClass().getSimpleName()); - } - - @GET - @Path("/{bpn}") - @Override - public JsonObject resolveV1(@PathParam("bpn") String bpn) { - monitor.warning(deprecationWarning("/v1", "/v3")); - return super.resolve(bpn); - } - - @DELETE - @Path("/{bpn}") - @Override - public void deleteEntryV1(@PathParam("bpn") String bpn) { - monitor.warning(deprecationWarning("/v1", "/v3")); - super.deleteEntry(bpn); - } - - @PUT - @Override - public void updateEntryV1(@RequestBody JsonObject object) { - monitor.warning(deprecationWarning("/v1", "/v3")); - super.updateEntry(object); - } - - @POST - @Override - public void createEntryV1(@RequestBody JsonObject object) { - monitor.warning(deprecationWarning("/v1", "/v3")); - super.createEntry(object); - } - -} diff --git a/edc-extensions/bpn-validation/bpn-validation-api/src/test/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1ControllerTest.java b/edc-extensions/bpn-validation/bpn-validation-api/src/test/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1ControllerTest.java deleted file mode 100644 index 51500832d3..0000000000 --- a/edc-extensions/bpn-validation/bpn-validation-api/src/test/java/org/eclipse/tractusx/edc/api/bpn/v1/BusinessPartnerGroupApiV1ControllerTest.java +++ /dev/null @@ -1,50 +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 - */ - -package org.eclipse.tractusx.edc.api.bpn.v1; - -import io.restassured.specification.RequestSpecification; -import org.eclipse.edc.junit.annotations.ApiTest; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.tractusx.edc.api.bpn.BaseBusinessPartnerGroupApiControllerTest; - -import static io.restassured.RestAssured.given; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@ApiTest -class BusinessPartnerGroupApiV1ControllerTest extends BaseBusinessPartnerGroupApiControllerTest { - - @Override - protected Object controller() { - var monitor = mock(Monitor.class); - when(monitor.withPrefix(anyString())).thenReturn(monitor); - return new BusinessPartnerGroupApiV1Controller(businessPartnerStore, mock(), monitor); - } - - @Override - protected RequestSpecification baseRequest() { - return given() - .baseUri("http://localhost:" + port) - .basePath("/business-partner-groups") - .when(); - } - -} 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 c557e861c8..1cd5c389ac 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,10 +37,6 @@ @Extension("Registers an SQL implementation for the BusinessPartnerGroupStore") public class SqlBusinessPartnerGroupStoreExtension implements ServiceExtension { - private static final String DEFAULT_DATASOURCE_NAME = "bpn"; - @Deprecated(since = "0.8.0") - @Setting(value = "Datasource name for the SQL BusinessPartnerGroup store", defaultValue = DEFAULT_DATASOURCE_NAME) - private static final String DATASOURCE_SETTING_NAME = "edc.datasource.bpn.name"; @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) public static final String DATASOURCE_NAME = "edc.sql.store.bpn.datasource"; 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/v4alpha/api/ConnectorDiscoveryV4AlphaApi.java index 9766a5fb34..11483203c1 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/v4alpha/api/ConnectorDiscoveryV4AlphaApi.java @@ -153,11 +153,11 @@ record ConnectorDiscoveryRequestSchema( "edc": "https://w3id.org/edc/v0.0.1/ns/", "tx": "https://w3id.org/tractusx/v0.0.1/ns/" }, - "@type": "tx:ConnectorParamsDiscoveryRequest", + "@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", + "https://provider.domain.com/conn2/api/v1/dsp" ] } """; diff --git a/edc-extensions/cx-policy/build.gradle.kts b/edc-extensions/cx-policy/build.gradle.kts index 91cf71c45d..f33e2fd7a8 100644 --- a/edc-extensions/cx-policy/build.gradle.kts +++ b/edc-extensions/cx-policy/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { implementation(project(":spi:core-spi")) implementation(project(":core:core-utils")) implementation(project(":spi:bdrs-client-spi")) + implementation(libs.edc.core.policy.monitor) implementation(libs.edc.spi.catalog) implementation(libs.edc.spi.contract) implementation(libs.edc.spi.decentralized.claims) 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 52ec18c7fa..ffd9963b8e 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 @@ -23,6 +23,7 @@ import org.eclipse.edc.connector.controlplane.catalog.spi.policy.CatalogPolicyContext; import org.eclipse.edc.connector.controlplane.contract.spi.policy.ContractNegotiationPolicyContext; import org.eclipse.edc.connector.controlplane.contract.spi.policy.TransferProcessPolicyContext; +import org.eclipse.edc.connector.policy.monitor.spi.PolicyMonitorContext; import org.eclipse.edc.policy.engine.spi.PolicyEngine; import org.eclipse.edc.policy.engine.spi.RuleBindingRegistry; import org.eclipse.edc.policy.model.Duty; @@ -71,6 +72,7 @@ import java.util.stream.Stream; import static org.eclipse.edc.connector.controlplane.policy.spi.PolicyDefinition.EDC_POLICY_DEFINITION_TYPE; +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; import static org.eclipse.tractusx.edc.policy.cx.affiliates.AffiliatesBpnlProhibitionConstraintFunction.AFFILIATES_BPNL; @@ -154,11 +156,11 @@ public void registerFunctions(PolicyEngine engine) { withCxPolicyNsPrefix(USAGE_RESTRICTION), new UsageRestrictionConstraintFunction<>()); // Usage Duty Validators - engine.registerFunction(ContractNegotiationPolicyContext.class, Duty.class, + engine.registerFunction(PolicyMonitorContext.class, Duty.class, withCxPolicyNsPrefix(DATA_PROVISIONING_END_DURATION_DAYS), new DataProvisioningEndDurationDaysConstraintFunction<>()); engine.registerFunction(TransferProcessPolicyContext.class, Duty.class, withCxPolicyNsPrefix(DATA_PROVISIONING_END_DURATION_DAYS), new DataProvisioningEndDurationDaysConstraintFunction<>()); - engine.registerFunction(ContractNegotiationPolicyContext.class, Duty.class, + engine.registerFunction(PolicyMonitorContext.class, Duty.class, withCxPolicyNsPrefix(DATA_PROVISIONING_END_DATE), new DataProvisioningEndDateConstraintFunction<>()); engine.registerFunction(TransferProcessPolicyContext.class, Duty.class, withCxPolicyNsPrefix(DATA_PROVISIONING_END_DATE), new DataProvisioningEndDateConstraintFunction<>()); @@ -202,17 +204,17 @@ public void registerFunctions(PolicyEngine engine) { engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, withCxPolicyNsPrefix(USAGE_PURPOSE), new UsagePurposeConstraintFunction<>()); - engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, CX_POLICY_2025_09_NS + DATA_FREQUENCY, new DataFrequencyConstraintFunction<>()); - engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, CX_POLICY_2025_09_NS + DATA_FREQUENCY, new DataFrequencyConstraintFunction<>()); + engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, withCxPolicyNsPrefix(DATA_FREQUENCY), new DataFrequencyConstraintFunction<>()); + engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, withCxPolicyNsPrefix(DATA_FREQUENCY), new DataFrequencyConstraintFunction<>()); - engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, CX_POLICY_2025_09_NS + DATA_USAGE_END_DATE, new DataUsageEndDateConstraintFunction<>()); - engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, CX_POLICY_2025_09_NS + DATA_USAGE_END_DATE, new DataUsageEndDateConstraintFunction<>()); + engine.registerFunction(PolicyMonitorContext.class, Permission.class, withCxPolicyNsPrefix(DATA_USAGE_END_DATE), new DataUsageEndDateConstraintFunction<>()); + engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, withCxPolicyNsPrefix(DATA_USAGE_END_DATE), new DataUsageEndDateConstraintFunction<>()); - engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, CX_POLICY_2025_09_NS + DATA_USAGE_END_DEFINITION, new DataUsageEndDefinitionConstraintFunction<>()); - engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, CX_POLICY_2025_09_NS + DATA_USAGE_END_DEFINITION, new DataUsageEndDefinitionConstraintFunction<>()); + engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, withCxPolicyNsPrefix(DATA_USAGE_END_DEFINITION), new DataUsageEndDefinitionConstraintFunction<>()); + engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, withCxPolicyNsPrefix(DATA_USAGE_END_DEFINITION), new DataUsageEndDefinitionConstraintFunction<>()); - engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, CX_POLICY_2025_09_NS + DATA_USAGE_END_DURATION_DAYS, new DataUsageEndDurationDaysConstraintFunction<>()); - engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, CX_POLICY_2025_09_NS + DATA_USAGE_END_DURATION_DAYS, new DataUsageEndDurationDaysConstraintFunction<>()); + engine.registerFunction(PolicyMonitorContext.class, Permission.class, withCxPolicyNsPrefix(DATA_USAGE_END_DURATION_DAYS), new DataUsageEndDurationDaysConstraintFunction<>()); + engine.registerFunction(TransferProcessPolicyContext.class, Permission.class, withCxPolicyNsPrefix(DATA_USAGE_END_DURATION_DAYS), new DataUsageEndDurationDaysConstraintFunction<>()); engine.registerFunction(ContractNegotiationPolicyContext.class, Permission.class, withCxPolicyNsPrefix(JURISDICTION_LOCATION), new JurisdictionLocationConstraintFunction<>()); @@ -288,13 +290,13 @@ public static void registerBindings(RuleBindingRegistry registry) { registry.bind(ODRL_SCHEMA + "use", NEGOTIATION_SCOPE); registry.bind(ODRL_SCHEMA + "use", TRANSFER_PROCESS_SCOPE); - registry.bind(CX_POLICY_2025_09_NS + "access", CATALOG_SCOPE); - registry.bind(CX_POLICY_2025_09_NS + "access", NEGOTIATION_SCOPE); - registry.bind(CX_POLICY_2025_09_NS + "access", TRANSFER_PROCESS_SCOPE); + registry.bind(withCxPolicyNsPrefix("access"), CATALOG_SCOPE); + registry.bind(withCxPolicyNsPrefix("access"), NEGOTIATION_SCOPE); + registry.bind(withCxPolicyNsPrefix("access"), TRANSFER_PROCESS_SCOPE); - registry.bind(CX_POLICY_2025_09_NS + USAGE_PURPOSE, CATALOG_SCOPE); - registry.bind(CX_POLICY_2025_09_NS + USAGE_PURPOSE, NEGOTIATION_SCOPE); - registry.bind(CX_POLICY_2025_09_NS + USAGE_PURPOSE, TRANSFER_PROCESS_SCOPE); + registry.bind(withCxPolicyNsPrefix(USAGE_PURPOSE), CATALOG_SCOPE); + registry.bind(withCxPolicyNsPrefix(USAGE_PURPOSE), NEGOTIATION_SCOPE); + registry.bind(withCxPolicyNsPrefix(USAGE_PURPOSE), TRANSFER_PROCESS_SCOPE); var namesInCatalogScope = Set.of( withCxPolicyNsPrefix(USAGE_PURPOSE), @@ -310,11 +312,6 @@ public static void registerBindings(RuleBindingRegistry registry) { withCxPolicyNsPrefix(AFFILIATES_BPNL), withCxPolicyNsPrefix(AFFILIATES_REGION), withCxPolicyNsPrefix(DATA_FREQUENCY), - withCxPolicyNsPrefix(DATA_USAGE_END_DATE), - withCxPolicyNsPrefix(DATA_USAGE_END_DEFINITION), - withCxPolicyNsPrefix(DATA_USAGE_END_DURATION_DAYS), - withCxPolicyNsPrefix(DATA_PROVISIONING_END_DURATION_DAYS), - withCxPolicyNsPrefix(DATA_PROVISIONING_END_DATE), withCxPolicyNsPrefix(JURISDICTION_LOCATION), withCxPolicyNsPrefix(JURISDICTION_LOCATION_REFERENCE), withCxPolicyNsPrefix(LIABILITY), @@ -354,6 +351,15 @@ public static void registerBindings(RuleBindingRegistry registry) { withCxPolicyNsPrefix(USAGE_RESTRICTION) ); registerBindingSet(registry, namesInTransferProcessScope, TRANSFER_PROCESS_SCOPE); + + var namesInPolicyMonitorScope = Set.of( + withCxPolicyNsPrefix(DATA_USAGE_END_DATE), + withCxPolicyNsPrefix(DATA_USAGE_END_DEFINITION), + withCxPolicyNsPrefix(DATA_USAGE_END_DURATION_DAYS), + withCxPolicyNsPrefix(DATA_PROVISIONING_END_DURATION_DAYS), + withCxPolicyNsPrefix(DATA_PROVISIONING_END_DATE) + ); + registerBindingSet(registry, namesInPolicyMonitorScope, POLICY_MONITOR_SCOPE); } private static void registerBindingSet(RuleBindingRegistry registry, Set names, String scope) { diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDateConstraintFunction.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDateConstraintFunction.java new file mode 100644 index 0000000000..1d90958aeb --- /dev/null +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDateConstraintFunction.java @@ -0,0 +1,78 @@ +/* + * 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.policy.cx.common; + +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.policy.model.Rule; +import org.eclipse.edc.spi.result.Result; + +import java.time.Instant; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.util.Set; +import java.util.regex.Pattern; + + +/** + * This is an abstract constraint function for DataEndDate constraints. It evaluates to true if the current date is + * not after the specified expiry date. The expiry date is expected to be in ISO-8061 UTC date-time format, truncated + * to seconds (e.g. "2024-12-31T23:59:59Z"). + * + * @param the type of the rule (e.g. Permission, Duty, etc.) + * @param the type of the agreement policy context + */ +public abstract class AbstractDataEndDateConstraintFunction implements AtomicConstraintRuleFunction { + private static final Set ALLOWED_OPERATORS = Set.of( + Operator.EQ + ); + + private static final String DATE_PATTERN = "^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2}))$"; + + @Override + public boolean evaluate(Operator operator, Object rightOperand, R rule, C context) { + try { + var expiryDate = Instant.parse(rightOperand.toString()); + return !context.now().truncatedTo(ChronoUnit.SECONDS).isAfter(expiryDate); + } catch (DateTimeParseException e) { + context.reportProblem("Invalid right-operand: right operand must match pattern '%s'".formatted(DATE_PATTERN)); + return false; + } + } + + @Override + public Result validate(Operator operator, Object rightOperand, R rule) { + if (operator == null) { + return Result.failure("Invalid operator: this constraint only allows the following operators: %s, but received null.".formatted(ALLOWED_OPERATORS)); + } + + if (!ALLOWED_OPERATORS.contains(operator)) { + return Result.failure("Invalid operator: this constraint only allows the following operators: %s, but received '%s'.".formatted(ALLOWED_OPERATORS, operator)); + } + + var compiledPattern = Pattern.compile(DATE_PATTERN); + if (!(rightOperand instanceof String rightValue && compiledPattern.matcher(rightValue).matches())) { + return Result.failure("Invalid right-operand: right operand must match pattern '%s'".formatted(DATE_PATTERN)); + } + + return Result.success(); + } +} diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDurationDaysConstraintFunction.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDurationDaysConstraintFunction.java new file mode 100644 index 0000000000..cae0c02857 --- /dev/null +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDurationDaysConstraintFunction.java @@ -0,0 +1,85 @@ +/* + * 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.policy.cx.common; + +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.policy.model.Rule; +import org.eclipse.edc.spi.result.Result; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Set; + +/** + * This is an abstract constraint function for DataEndDurationDays constraints. It evaluates to true if the current + * date is before the expiry date, which is calculated by adding the specified number of days to the contract signing + * date. The contract signing date is retrieved from the agreement context. + * + * @param the type of the rule (e.g. Permission, Duty, etc.) + * @param the type of the agreement policy context + */ +public abstract class AbstractDataEndDurationDaysConstraintFunction implements AtomicConstraintRuleFunction { + private static final Set ALLOWED_OPERATORS = Set.of( + Operator.EQ + ); + + private Result extractRightValue(Object rightOperand) { + if (rightOperand instanceof Integer) { + return Result.success((Integer) rightOperand); + } else if (rightOperand instanceof String rightValue) { + try { + return Result.success(Integer.parseInt(rightValue)); + } catch (NumberFormatException e) { + return Result.failure("Invalid right-operand: value must be a valid integer, but got '%s'.".formatted(rightOperand)); + } + } + + return Result.failure("Invalid right-operand: this constraint only allows integer values or strings representing integers, but got '%s'." + .formatted(rightOperand != null ? rightOperand.getClass().getName() : "null")); + } + + @Override + public boolean evaluate(Operator operator, Object rightOperand, R rule, C context) { + return extractRightValue(rightOperand) + .map(rightValue -> Instant.ofEpochSecond(context.contractAgreement().getContractSigningDate()) + .truncatedTo(ChronoUnit.DAYS) + .plus(rightValue, ChronoUnit.DAYS)) + .map(expiryDate -> context.now().truncatedTo(ChronoUnit.DAYS).isBefore(expiryDate)) + .orElse(failure -> { + context.reportProblem("Failed to evaluate constraint due to invalid right operand: '%s'. Problems: %s".formatted(rightOperand, failure)); + return false; + }); + } + + @Override + public Result validate(Operator operator, Object rightValue, R rule) { + if (operator == null) { + return Result.failure("Invalid operator: this constraint only allows the following operators: %s, but received null.".formatted(ALLOWED_OPERATORS)); + } + + if (!ALLOWED_OPERATORS.contains(operator)) { + return Result.failure("Invalid operator: this constraint only allows the following operators: %s, but received '%s'.".formatted(ALLOWED_OPERATORS, operator)); + } + + return extractRightValue(rightValue).mapEmpty(); + } +} diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDateConstraintFunction.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDateConstraintFunction.java index c2bf428700..ef8dc579be 100644 --- a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDateConstraintFunction.java +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDateConstraintFunction.java @@ -19,24 +19,11 @@ package org.eclipse.tractusx.edc.policy.cx.dataprovisioning; -import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; import org.eclipse.edc.policy.model.Duty; -import org.eclipse.edc.policy.model.Operator; -import org.eclipse.tractusx.edc.policy.cx.common.ValueValidatingConstraintFunction; +import org.eclipse.tractusx.edc.policy.cx.common.AbstractDataEndDateConstraintFunction; -import java.util.Set; -/** - * This is a placeholder constraint function for DataProvisioningEndDate. It always returns true but allows - * the validation of policies to be strictly enforced. - */ -public class DataProvisioningEndDateConstraintFunction extends ValueValidatingConstraintFunction { +public class DataProvisioningEndDateConstraintFunction extends AbstractDataEndDateConstraintFunction { public static final String DATA_PROVISIONING_END_DATE = "DataProvisioningEndDate"; - - public DataProvisioningEndDateConstraintFunction() { - super( - Set.of(Operator.EQ), - "^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2}))$" - ); - } -} +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDurationDaysConstraintFunction.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDurationDaysConstraintFunction.java index 2d4251a919..bd597092f0 100644 --- a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDurationDaysConstraintFunction.java +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDurationDaysConstraintFunction.java @@ -19,48 +19,11 @@ package org.eclipse.tractusx.edc.policy.cx.dataprovisioning; -import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; -import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction; +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; import org.eclipse.edc.policy.model.Duty; -import org.eclipse.edc.policy.model.Operator; -import org.eclipse.edc.spi.result.Result; +import org.eclipse.tractusx.edc.policy.cx.common.AbstractDataEndDurationDaysConstraintFunction; -import java.util.Set; -/** - * This is a placeholder constraint function for DataProvisioningEndDurationDays. It always returns true but allows - * the validation of policies to be strictly enforced. - */ -public class DataProvisioningEndDurationDaysConstraintFunction implements AtomicConstraintRuleFunction { +public class DataProvisioningEndDurationDaysConstraintFunction extends AbstractDataEndDurationDaysConstraintFunction { public static final String DATA_PROVISIONING_END_DURATION_DAYS = "DataProvisioningEndDurationDays"; - private static final Set ALLOWED_OPERATORS = Set.of( - Operator.EQ - ); - - @Override - public boolean evaluate(Operator operator, Object rightOperand, Duty permission, C c) { - return true; - } - - @Override - public Result validate(Operator operator, Object rightValue, Duty rule) { - if (!ALLOWED_OPERATORS.contains(operator)) { - return Result.failure("Invalid operator: this constraint only allows the following operators: %s, but received '%s'.".formatted(ALLOWED_OPERATORS, operator)); - } - - if (rightValue instanceof Integer) { - return Result.success(); - } - - if (rightValue instanceof String stringValue) { - try { - Integer.parseInt(stringValue); - return Result.success(); - } catch (NumberFormatException e) { - return Result.failure("Invalid right-operand: String value must be a valid integer value, but got '%s'.".formatted(stringValue)); - } - } - - return Result.failure("Invalid right-operand: right operand must be an integer value"); - } } diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDateConstraintFunction.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDateConstraintFunction.java index d4f6259a03..04cd7760c1 100644 --- a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDateConstraintFunction.java +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDateConstraintFunction.java @@ -19,24 +19,11 @@ package org.eclipse.tractusx.edc.policy.cx.datausage; -import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; -import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; import org.eclipse.edc.policy.model.Permission; -import org.eclipse.tractusx.edc.policy.cx.common.ValueValidatingConstraintFunction; +import org.eclipse.tractusx.edc.policy.cx.common.AbstractDataEndDateConstraintFunction; -import java.util.Set; -/** - * This is a placeholder constraint function for DataUsageEndDate. It always returns true but allows - * the validation of policies to be strictly enforced. - */ -public class DataUsageEndDateConstraintFunction extends ValueValidatingConstraintFunction { +public class DataUsageEndDateConstraintFunction extends AbstractDataEndDateConstraintFunction { public static final String DATA_USAGE_END_DATE = "DataUsageEndDate"; - - public DataUsageEndDateConstraintFunction() { - super( - Set.of(Operator.EQ), - "^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|[+-]\\d{2}:\\d{2}))$" - ); - } } diff --git a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDurationDaysConstraintFunction.java b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDurationDaysConstraintFunction.java index 6412e68bd6..535ed089a4 100644 --- a/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDurationDaysConstraintFunction.java +++ b/edc-extensions/cx-policy/src/main/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDurationDaysConstraintFunction.java @@ -19,49 +19,11 @@ package org.eclipse.tractusx.edc.policy.cx.datausage; -import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; -import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction; -import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; import org.eclipse.edc.policy.model.Permission; -import org.eclipse.edc.spi.result.Result; +import org.eclipse.tractusx.edc.policy.cx.common.AbstractDataEndDurationDaysConstraintFunction; -import java.util.Set; -/** - * This is a placeholder constraint function for DataUsageEndDurationDays. It always returns true but allows - * the validation of policies to be strictly enforced. - */ -public class DataUsageEndDurationDaysConstraintFunction implements AtomicConstraintRuleFunction { +public class DataUsageEndDurationDaysConstraintFunction extends AbstractDataEndDurationDaysConstraintFunction { public static final String DATA_USAGE_END_DURATION_DAYS = "DataUsageEndDurationDays"; - private static final Set ALLOWED_OPERATORS = Set.of( - Operator.EQ - ); - - @Override - public boolean evaluate(Operator operator, Object rightOperand, Permission permission, C c) { - return true; - } - - @Override - public Result validate(Operator operator, Object rightValue, Permission rule) { - if (!ALLOWED_OPERATORS.contains(operator)) { - return Result.failure("Invalid operator: this constraint only allows the following operators: %s, but received '%s'.".formatted(ALLOWED_OPERATORS, operator)); - } - - if (rightValue instanceof Integer) { - return Result.success(); - } - - if (rightValue instanceof String operand) { - try { - Integer.parseInt(operand); - return Result.success(); - } catch (NumberFormatException e) { - return Result.failure("Invalid right-operand: value must be a valid integer, but got '%s'.".formatted(operand)); - } - } - - return Result.failure("Invalid right-operand: this constraint only allows integer values or strings representing integers, but got '%s'." - .formatted(rightValue != null ? rightValue.getClass().getName() : "null")); - } } diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/TestAgreementPolicyContext.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/TestAgreementPolicyContext.java new file mode 100644 index 0000000000..c59db55081 --- /dev/null +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/TestAgreementPolicyContext.java @@ -0,0 +1,73 @@ +/******************************************************************************** + * 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.policy.cx; + +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.connector.controlplane.contract.spi.types.agreement.ContractAgreement; +import org.eclipse.edc.policy.engine.spi.PolicyContextImpl; +import org.eclipse.edc.policy.model.Policy; + +import java.time.Instant; +import java.util.UUID; + +public class TestAgreementPolicyContext extends PolicyContextImpl implements AgreementPolicyContext { + + private final Instant now; + private final ContractAgreement contractAgreement; + + public TestAgreementPolicyContext() { + this(Instant.now()); + } + + public TestAgreementPolicyContext(Instant now) { + this(now, createAgreement(now)); + } + + public TestAgreementPolicyContext(Instant now, ContractAgreement contractAgreement) { + this.now = now; + this.contractAgreement = contractAgreement; + } + + public static ContractAgreement createAgreement(Instant signingTime) { + return ContractAgreement.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .providerId(UUID.randomUUID().toString()) + .consumerId(UUID.randomUUID().toString()) + .assetId(UUID.randomUUID().toString()) + .contractSigningDate(signingTime.getEpochSecond()) + .policy(Policy.Builder.newInstance().build()) + .build(); + } + + @Override + public ContractAgreement contractAgreement() { + return contractAgreement; + } + + @Override + public Instant now() { + return now; + } + + @Override + public String scope() { + return "any"; + } +} \ No newline at end of file diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDateConstraintFunctionTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDateConstraintFunctionTest.java new file mode 100644 index 0000000000..698d626086 --- /dev/null +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDateConstraintFunctionTest.java @@ -0,0 +1,102 @@ +/* + * 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.policy.cx.common; + +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.junit.assertions.AbstractResultAssert; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.policy.model.Permission; +import org.eclipse.tractusx.edc.policy.cx.TestAgreementPolicyContext; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; + +import static org.assertj.core.api.Assertions.assertThat; + +public class AbstractDataEndDateConstraintFunctionTest { + + private final AbstractDataEndDateConstraintFunction function = new AbstractDataEndDateConstraintFunction<>() {}; + private final AgreementPolicyContext context = new TestAgreementPolicyContext(); + + private Instant contextNowWithDelta(Integer delta, ChronoUnit unit) { + return context.now().plus(delta, unit).truncatedTo(ChronoUnit.SECONDS); + } + + @Test + void evaluate_whenPolicyIsValid_thenTrue() { + var result = function.evaluate( + Operator.EQ, + contextNowWithDelta(1, ChronoUnit.SECONDS).toString(), + null, context); + assertThat(result).isTrue(); + } + + @Test + void evaluate_whenPolicyIsSameTime_thenTrue() { + var fixedNow = context.now().truncatedTo(ChronoUnit.SECONDS); + // Ensure the Instant.now method called inside the evaluate function returns the fixedNow instant, to force equality comparison + try (var mockedInstant = Mockito.mockStatic(Instant.class, Mockito.CALLS_REAL_METHODS)) { + mockedInstant.when(Instant::now).thenReturn(fixedNow); + var result = function.evaluate( + Operator.EQ, + fixedNow.toString(), + null, context); + assertThat(result).isTrue(); + } + } + + @Test + void evaluate_whenPolicyIsExpired_thenFalse() { + var result = function.evaluate( + Operator.EQ, + contextNowWithDelta(-1, ChronoUnit.SECONDS).toString(), + null, context); + assertThat(result).isFalse(); + } + + @Test + void validate_whenOperatorAndRightOperandAreValid_thenSuccess() { + var result = function.validate(Operator.EQ, "2025-06-30T14:30:00Z", null); + AbstractResultAssert.assertThat(result).isSucceeded(); + } + + @Test + void validate_whenInvalidOperator_thenFailure() { + var result = function.validate(Operator.IS_ANY_OF, "2025-06-30T14:30:00+01:00", null); + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureDetail()).contains("Invalid operator"); + } + + @Test + void validate_whenInvalidInstant_thenFailure() { + var result = function.validate(Operator.EQ, "2025-06-30T14:30:00.456Z", null); + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureDetail()).contains("Invalid right-operand: "); + } + + @Test + void validate_whenInvalidValue_thenFailure() { + var result = function.validate(Operator.EQ, "invalid-test", null); + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureDetail()).contains("Invalid right-operand: "); + } +} diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDurationDaysConstraintFunctionTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDurationDaysConstraintFunctionTest.java new file mode 100644 index 0000000000..78ba3ea365 --- /dev/null +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/common/AbstractDataEndDurationDaysConstraintFunctionTest.java @@ -0,0 +1,83 @@ +/* + * 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.policy.cx.common; + +import org.eclipse.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.junit.assertions.AbstractResultAssert; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.policy.model.Permission; +import org.eclipse.tractusx.edc.policy.cx.TestAgreementPolicyContext; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; + +import static org.assertj.core.api.Assertions.assertThat; + +public class AbstractDataEndDurationDaysConstraintFunctionTest { + private final AbstractDataEndDurationDaysConstraintFunction function = new AbstractDataEndDurationDaysConstraintFunction<>() {}; + + @Test + void evaluate_whenPolicyIsValid_thenTrue() { + var validContext = new TestAgreementPolicyContext(); + var result = function.evaluate(Operator.EQ, 1, null, validContext); + assertThat(result).isTrue(); + } + + @Test + void evaluate_whenPolicyIsInSameDay_thenFalse() { + var expiredContext = new TestAgreementPolicyContext(); + var result = function.evaluate(Operator.EQ, 0, null, expiredContext); + assertThat(result).isFalse(); + } + + @Test + void evaluate_whenPolicyIsExpired_thenFalse() { + var expiredContext = new TestAgreementPolicyContext(Instant.now().minus(1, ChronoUnit.DAYS)); + var result = function.evaluate(Operator.EQ, -1, null, expiredContext); + assertThat(result).isFalse(); + } + + @Test + void validate_whenOperatorAndRightOperandAreValid_thenSuccess() { + var result = function.validate(Operator.EQ, 1, null); + AbstractResultAssert.assertThat(result).isSucceeded(); + } + + @Test + void validate_whenOperatorAndRightOperandAreValidString_thenSuccess() { + var result = function.validate(Operator.EQ, "1", null); + AbstractResultAssert.assertThat(result).isSucceeded(); + } + + @Test + void validate_whenInvalidOperator_thenFailure() { + var result = function.validate(Operator.IS_ANY_OF, 1, null); + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureDetail()).contains("Invalid operator"); + } + + @Test + void validate_whenInvalidValue_thenFailure() { + var result = function.validate(Operator.EQ, "invalid-test", null); + assertThat(result.failed()).isTrue(); + assertThat(result.getFailureDetail()).contains("Invalid right-operand: "); + } +} diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDateConstraintFunctionTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDateConstraintFunctionTest.java index 783b8ac1de..781498b764 100644 --- a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDateConstraintFunctionTest.java +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDateConstraintFunctionTest.java @@ -19,44 +19,23 @@ package org.eclipse.tractusx.edc.policy.cx.dataprovisioning; -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.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.policy.model.Duty; import org.junit.jupiter.api.Test; +import java.lang.reflect.ParameterizedType; + import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; -import static org.mockito.Mockito.mock; class DataProvisioningEndDateConstraintFunctionTest { - private final ParticipantAgent participantAgent = mock(); - private final DataProvisioningEndDateConstraintFunction function = new DataProvisioningEndDateConstraintFunction<>(); - private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent); - - @Test - void evaluate() { - assertThat(function.evaluate(Operator.EQ, "2025-06-30T14:30:00Z", null, context)).isTrue(); - } - - @Test - void validate_whenOperatorAndRightOperandAreValid_thenSuccess() { - var result = function.validate(Operator.EQ, "2025-06-30T14:30:00Z", null); - assertThat(result).isSucceeded(); - } - - @Test - void validate_whenInvalidOperator_thenFailure() { - var result = function.validate(Operator.IS_ANY_OF, "2025-06-30T14:30:00+01:00", null); - assertThat(result.failed()).isTrue(); - assertThat(result.getFailureDetail()).contains("Invalid operator"); - } + private final DataProvisioningEndDateConstraintFunction function = new DataProvisioningEndDateConstraintFunction<>(); @Test - void validate_whenInvalidValue_thenFailure() { - var result = function.validate(Operator.EQ, "invalid-test", null); - assertThat(result.failed()).isTrue(); - assertThat(result.getFailureDetail()).contains("Invalid right-operand: "); + void shouldOnlyApplyToDuty() { + // Ensure that the function is parameterized with the Duty class, which means it will only apply to Duty rules + var superclass = (ParameterizedType) function.getClass().getGenericSuperclass(); + var ruleType = superclass.getActualTypeArguments()[0]; + assertThat(ruleType).isEqualTo(Duty.class); } } diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDurationDaysConstraintFunctionTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDurationDaysConstraintFunctionTest.java index 09556bc14b..3442a78fe2 100644 --- a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDurationDaysConstraintFunctionTest.java +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/dataprovisioning/DataProvisioningEndDurationDaysConstraintFunctionTest.java @@ -19,48 +19,23 @@ package org.eclipse.tractusx.edc.policy.cx.dataprovisioning; -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.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.policy.model.Duty; import org.junit.jupiter.api.Test; +import java.lang.reflect.ParameterizedType; + import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; -import static org.mockito.Mockito.mock; class DataProvisioningEndDurationDaysConstraintFunctionTest { - private final ParticipantAgent participantAgent = mock(); - private final DataProvisioningEndDurationDaysConstraintFunction function = new DataProvisioningEndDurationDaysConstraintFunction<>(); - private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent); - - @Test - void evaluate() { - assertThat(function.evaluate(Operator.EQ, 1, null, context)).isTrue(); - } - - @Test - void validate_whenOperatorAndRightOperandAreValid_thenSuccess() { - var result = function.validate(Operator.EQ, 1, null); - assertThat(result).isSucceeded(); - } - - @Test - void validate_whenOperatorAndRightOperandAreValidString_thenSuccess() { - var result = function.validate(Operator.EQ, "1", null); - assertThat(result).isSucceeded(); - } - - @Test - void validate_whenInvalidOperator_thenFailure() { - var result = function.validate(Operator.IS_ANY_OF, 1, null); - assertThat(result).isFailed().detail().contains("Invalid operator"); - } + private final DataProvisioningEndDurationDaysConstraintFunction function = new DataProvisioningEndDurationDaysConstraintFunction<>(); @Test - void validate_whenInvalidValue_thenFailure() { - var result = function.validate(Operator.EQ, "invalid-test", null); - assertThat(result).isFailed().detail().contains("Invalid right-operand:"); + void shouldOnlyApplyToDuty() { + // Ensure that the function is parameterized with the Duty class, which means it will only apply to Duty rules + var superclass = (ParameterizedType) function.getClass().getGenericSuperclass(); + var ruleType = superclass.getActualTypeArguments()[0]; + assertThat(ruleType).isEqualTo(Duty.class); } } diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDateConstraintFunctionTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDateConstraintFunctionTest.java index 91d1d7a157..449e57a737 100644 --- a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDateConstraintFunctionTest.java +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDateConstraintFunctionTest.java @@ -19,44 +19,23 @@ package org.eclipse.tractusx.edc.policy.cx.datausage; -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.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.policy.model.Permission; import org.junit.jupiter.api.Test; +import java.lang.reflect.ParameterizedType; + import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; -import static org.mockito.Mockito.mock; class DataUsageEndDateConstraintFunctionTest { - private final ParticipantAgent participantAgent = mock(); - private final DataUsageEndDateConstraintFunction function = new DataUsageEndDateConstraintFunction<>(); - private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent); - - @Test - void evaluate() { - assertThat(function.evaluate(Operator.EQ, "2025-06-30T14:30:00Z", null, context)).isTrue(); - } - - @Test - void validate_whenOperatorAndRightOperandAreValid_thenSuccess() { - var result = function.validate(Operator.EQ, "2025-06-30T14:30:00Z", null); - assertThat(result).isSucceeded(); - } - - @Test - void validate_whenInvalidOperator_thenFailure() { - var result = function.validate(Operator.IS_ANY_OF, "2025-06-30T14:30:00+01:00", null); - assertThat(result.failed()).isTrue(); - assertThat(result.getFailureDetail()).contains("Invalid operator"); - } + private final DataUsageEndDateConstraintFunction function = new DataUsageEndDateConstraintFunction<>(); @Test - void validate_whenInvalidValue_thenFailure() { - var result = function.validate(Operator.EQ, "invalid-test", null); - assertThat(result.failed()).isTrue(); - assertThat(result.getFailureDetail()).contains("Invalid right-operand: "); + void shouldOnlyApplyToPermission() { + // Ensure that the function is parameterized with the Permission class, which means it will only apply to Permission rules + var superclass = (ParameterizedType) function.getClass().getGenericSuperclass(); + var ruleType = superclass.getActualTypeArguments()[0]; + assertThat(ruleType).isEqualTo(Permission.class); } } diff --git a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDurationDaysConstraintFunctionTest.java b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDurationDaysConstraintFunctionTest.java index 26298c66a8..03dc7acf9e 100644 --- a/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDurationDaysConstraintFunctionTest.java +++ b/edc-extensions/cx-policy/src/test/java/org/eclipse/tractusx/edc/policy/cx/datausage/DataUsageEndDurationDaysConstraintFunctionTest.java @@ -19,50 +19,23 @@ package org.eclipse.tractusx.edc.policy.cx.datausage; -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.edc.connector.controlplane.contract.spi.policy.AgreementPolicyContext; +import org.eclipse.edc.policy.model.Permission; import org.junit.jupiter.api.Test; +import java.lang.reflect.ParameterizedType; + import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; -import static org.mockito.Mockito.mock; class DataUsageEndDurationDaysConstraintFunctionTest { - private final ParticipantAgent participantAgent = mock(); - private final DataUsageEndDurationDaysConstraintFunction function = new DataUsageEndDurationDaysConstraintFunction<>(); - private final ParticipantAgentPolicyContext context = new TestParticipantAgentPolicyContext(participantAgent); - - @Test - void evaluate() { - assertThat(function.evaluate(Operator.EQ, 1, null, context)).isTrue(); - } - - @Test - void validate_whenOperatorAndRightOperandAreValid_thenSuccess() { - var result = function.validate(Operator.EQ, 1, null); - assertThat(result).isSucceeded(); - } - - @Test - void validate_whenOperatorAndRightOperandAreValidString_thenSuccess() { - var result = function.validate(Operator.EQ, "1", null); - assertThat(result).isSucceeded(); - } - - @Test - void validate_whenInvalidOperator_thenFailure() { - var result = function.validate(Operator.IS_ANY_OF, 1, null); - assertThat(result.failed()).isTrue(); - assertThat(result.getFailureDetail()).contains("Invalid operator"); - } + private final DataUsageEndDurationDaysConstraintFunction function = new DataUsageEndDurationDaysConstraintFunction<>(); @Test - void validate_whenInvalidValue_thenFailure() { - var result = function.validate(Operator.EQ, "invalid-test", null); - assertThat(result.failed()).isTrue(); - assertThat(result.getFailureDetail()).contains("Invalid right-operand: "); + void shouldOnlyApplyToPermission() { + // Ensure that the function is parameterized with the Permission class, which means it will only apply to Permission rules + var superclass = (ParameterizedType) function.getClass().getGenericSuperclass(); + var ruleType = superclass.getActualTypeArguments()[0]; + assertThat(ruleType).isEqualTo(Permission.class); } } diff --git a/edc-extensions/dataspace-protocol/cx-dataspace-protocol/src/main/java/org/eclipse/tractusx/edc/protocol/cx/identifier/BpnExtractionFunction.java b/edc-extensions/dataspace-protocol/cx-dataspace-protocol/src/main/java/org/eclipse/tractusx/edc/protocol/cx/identifier/BpnExtractionFunction.java index 3146bb4de6..fe12d96335 100644 --- a/edc-extensions/dataspace-protocol/cx-dataspace-protocol/src/main/java/org/eclipse/tractusx/edc/protocol/cx/identifier/BpnExtractionFunction.java +++ b/edc-extensions/dataspace-protocol/cx-dataspace-protocol/src/main/java/org/eclipse/tractusx/edc/protocol/cx/identifier/BpnExtractionFunction.java @@ -21,31 +21,76 @@ package org.eclipse.tractusx.edc.protocol.cx.identifier; import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential; +import org.eclipse.edc.protocol.spi.ParticipantIdExtractionFunction; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.iam.ClaimToken; import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.tractusx.edc.protocol.core.identifier.MembershipCredentialIdExtractionFunction; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.tractusx.edc.core.utils.credentials.CredentialTypePredicate; +import java.util.List; import java.util.Map; import java.util.Optional; +import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_CREDENTIAL_NS; + /** * Extracts the BPN (= holderIdentifier property) from the MembershipCredential as the participant id. * Used to handle id extraction for DSP 0.8. */ -public class BpnExtractionFunction extends MembershipCredentialIdExtractionFunction { - +public class BpnExtractionFunction implements ParticipantIdExtractionFunction { + + private static final String VC_CLAIM = "vc"; + private static final String IDENTITY_CREDENTIAL = "MembershipCredential"; private static final String IDENTITY_PROPERTY = "holderIdentifier"; + private final CredentialTypePredicate typePredicate = new CredentialTypePredicate(CX_CREDENTIAL_NS, IDENTITY_CREDENTIAL); + private final Monitor monitor; + public BpnExtractionFunction(Monitor monitor) { - super(monitor); + this.monitor = monitor.withPrefix(getClass().getSimpleName()); } @Override - public String identityProperty() { - return IDENTITY_PROPERTY; + public String apply(ClaimToken claimToken) { + var credentials = getCredentialList(claimToken) + .orElseThrow(failure -> new EdcException("Failed to fetch credentials from the claim token: %s".formatted(failure.getFailureDetail()))); + + return credentials.stream() + .filter(typePredicate) + .findFirst() + .flatMap(this::getIdentifier) + .orElseThrow(() -> { + var msg = "Required credential type '%s' not present in ClaimToken, cannot extract property '%s'".formatted(IDENTITY_CREDENTIAL, IDENTITY_PROPERTY); + monitor.warning(msg); + return new EdcException(msg); + }); } - - @Override - public Optional getIdentifier(VerifiableCredential vc) { + + @SuppressWarnings("unchecked") + private Result> getCredentialList(ClaimToken claimToken) { + var vcListClaim = claimToken.getClaims().get(VC_CLAIM); + + if (vcListClaim == null) { + var msg = "ClaimToken did not contain a '%s' claim.".formatted(VC_CLAIM); + monitor.warning(msg); + return Result.failure(msg); + } + if (!(vcListClaim instanceof List)) { + var msg = "ClaimToken contains a '%s' claim, but the type is incorrect. Expected %s, got %s.".formatted(VC_CLAIM, List.class.getName(), vcListClaim.getClass().getName()); + monitor.warning(msg); + return Result.failure(msg); + } + var vcList = (List) vcListClaim; + if (vcList.isEmpty()) { + var msg = "ClaimToken contains a '%s' claim but it did not contain any VerifiableCredentials.".formatted(VC_CLAIM); + monitor.warning(msg); + return Result.failure(msg); + } + return Result.success(vcList); + } + + private Optional getIdentifier(VerifiableCredential vc) { return vc.getCredentialSubject().stream() .flatMap(credentialSubject -> credentialSubject.getClaims().entrySet().stream()) .filter(entry -> entry.getKey().endsWith(IDENTITY_PROPERTY)) diff --git a/edc-extensions/dataspace-protocol/cx-dataspace-protocol/src/test/java/org/eclipse/tractusx/edc/protocol/cx/identifier/BpnExtractionFunctionTest.java b/edc-extensions/dataspace-protocol/cx-dataspace-protocol/src/test/java/org/eclipse/tractusx/edc/protocol/cx/identifier/BpnExtractionFunctionTest.java index a32b58b252..5315a15fd6 100644 --- a/edc-extensions/dataspace-protocol/cx-dataspace-protocol/src/test/java/org/eclipse/tractusx/edc/protocol/cx/identifier/BpnExtractionFunctionTest.java +++ b/edc-extensions/dataspace-protocol/cx-dataspace-protocol/src/test/java/org/eclipse/tractusx/edc/protocol/cx/identifier/BpnExtractionFunctionTest.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) * Copyright (c) 2025 Cofinity-X GmbH * Copyright (c) 2026 SAP SE * @@ -20,50 +21,95 @@ package org.eclipse.tractusx.edc.protocol.cx.identifier; +import org.eclipse.edc.iam.verifiablecredentials.spi.model.CredentialSubject; +import org.eclipse.edc.iam.verifiablecredentials.spi.model.Issuer; import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential; +import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.iam.ClaimToken; import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.tractusx.edc.protocol.core.identifier.MembershipCredentialIdExtractionFunction; -import org.eclipse.tractusx.edc.protocol.core.identifier.MembershipCredentialIdExtractionFunctionTest; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; +import java.time.Instant; import java.util.List; import java.util.Map; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_CREDENTIAL_NS; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class BpnExtractionFunctionTest extends MembershipCredentialIdExtractionFunctionTest { +public class BpnExtractionFunctionTest { + public static final String DID = "did:web:example"; public static final String BPN = "bpn"; public static final String ID_PROPERTY = "holderIdentifier"; private final Monitor monitor = mock(); - @Override - protected MembershipCredentialIdExtractionFunction extractionFunction() { + private BpnExtractionFunction extractionFunction() { when(monitor.withPrefix(anyString())).thenReturn(monitor); return new BpnExtractionFunction(monitor); } - - @Override - protected String expectedId() { - return BPN; - } @ParameterizedTest @ArgumentsSource(VerifiableCredentialArgumentProvider.class) void apply(VerifiableCredential credential) { var id = extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", List.of(credential)).build()); - assertThat(id).isEqualTo(expectedId()); + assertThat(id).isEqualTo(BPN); + } + + @Test + void apply_fails_WhenCredentialNotFound() { + assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", List.of(vc("FooCredential", Map.of("foo", "bar")))).build())) + .isInstanceOf(EdcException.class) + .hasMessage("Required credential type 'MembershipCredential' not present in ClaimToken, cannot extract property '%s'", ID_PROPERTY); + } + + @Test + void apply_fails_whenNoVcClaims() { + assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().build())) + .isInstanceOf(EdcException.class) + .hasMessageContaining("Failed to fetch credentials from the claim token: ClaimToken did not contain a 'vc' claim"); + } + + @Test + void apply_fails_whenNullVcClaims() { + assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", null).build())) + .isInstanceOf(EdcException.class) + .hasMessageContaining("Failed to fetch credentials from the claim token: ClaimToken did not contain a 'vc' claim"); + } + + @Test + void apply_fails_WhenVcClaimIsNotList() { + assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", "wrong").build())) + .isInstanceOf(EdcException.class) + .hasMessageContaining("Failed to fetch credentials from the claim token: ClaimToken contains a 'vc' claim, but the type is incorrect. Expected java.util.List, got java.lang.String."); + } + + @Test + void apply_fails_WhenVcClaimsIsEmptyList() { + assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", List.of()).build())) + .isInstanceOf(EdcException.class) + .hasMessageContaining("Failed to fetch credentials from the claim token: ClaimToken contains a 'vc' claim but it did not contain any VerifiableCredentials."); + } + + private static VerifiableCredential vc(String type, Map claims) { + return VerifiableCredential.Builder.newInstance().type(type) + .issuanceDate(Instant.now()) + .issuer(new Issuer("issuer", Map.of())) + .credentialSubject(CredentialSubject.Builder.newInstance() + .id(claims.containsKey("id") ? claims.get("id").toString() : null) + .claims(claims) + .build()) + .build(); } private static class VerifiableCredentialArgumentProvider implements ArgumentsProvider { diff --git a/edc-extensions/dataspace-protocol/dataspace-protocol-core/build.gradle.kts b/edc-extensions/dataspace-protocol/dataspace-protocol-core/build.gradle.kts index cf7583a642..6509a3243e 100644 --- a/edc-extensions/dataspace-protocol/dataspace-protocol-core/build.gradle.kts +++ b/edc-extensions/dataspace-protocol/dataspace-protocol-core/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { implementation(libs.edc.spi.participant) implementation(libs.edc.spi.protocol) + implementation(libs.edc.iam.decentralized.claims.core) implementation(project(":spi:core-spi")) implementation(project(":core:core-utils")) diff --git a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/CoreDataspaceProtocolExtension.java b/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/CoreDataspaceProtocolExtension.java index a980cd96de..c261f7a5bb 100644 --- a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/CoreDataspaceProtocolExtension.java +++ b/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/CoreDataspaceProtocolExtension.java @@ -20,6 +20,7 @@ package org.eclipse.tractusx.edc.protocol.core; +import org.eclipse.edc.iam.decentralizedclaims.core.defaults.DefaultDcpParticipantIdExtractionFunction; import org.eclipse.edc.participantcontext.single.spi.SingleParticipantContextSupplier; import org.eclipse.edc.protocol.dsp.http.spi.api.DspBaseWebhookAddress; import org.eclipse.edc.protocol.spi.DataspaceProfileContext; @@ -28,7 +29,6 @@ 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.protocol.core.identifier.DidExtractionFunction; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.DATASPACE_PROTOCOL_HTTP_V_2025_1; import static org.eclipse.edc.protocol.dsp.spi.type.Dsp2025Constants.V_2025_1; @@ -47,6 +47,6 @@ public class CoreDataspaceProtocolExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - contextRegistry.register(new DataspaceProfileContext(DATASPACE_PROTOCOL_HTTP_V_2025_1, V_2025_1, () -> dspWebhookAddress.get() + V_2025_1_PATH, new DidExtractionFunction(monitor))); + contextRegistry.register(new DataspaceProfileContext(DATASPACE_PROTOCOL_HTTP_V_2025_1, V_2025_1, () -> dspWebhookAddress.get() + V_2025_1_PATH, new DefaultDcpParticipantIdExtractionFunction())); } } diff --git a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/identifier/DidExtractionFunction.java b/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/identifier/DidExtractionFunction.java deleted file mode 100644 index 9ab86c5ce7..0000000000 --- a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/identifier/DidExtractionFunction.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2025 Cofinity-X GmbH - * Copyright (c) 2026 SAP SE - * - * 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.protocol.core.identifier; - -import org.eclipse.edc.iam.verifiablecredentials.spi.model.CredentialSubject; -import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential; -import org.eclipse.edc.spi.monitor.Monitor; - -import java.util.Optional; - -/** - * Extracts the DID (= credential subject id) from the MembershipCredential as the participant id. - * Used to handle id extraction for DSP 2025-1. - */ -public class DidExtractionFunction extends MembershipCredentialIdExtractionFunction { - - private static final String IDENTITY_PROPERTY = "id"; - - public DidExtractionFunction(Monitor monitor) { - super(monitor); - } - - @Override - public String identityProperty() { - return IDENTITY_PROPERTY; - } - - @Override - public Optional getIdentifier(VerifiableCredential vc) { - return vc.getCredentialSubject().stream() - .map(CredentialSubject::getId) - .findFirst(); - } -} diff --git a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/identifier/MembershipCredentialIdExtractionFunction.java b/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/identifier/MembershipCredentialIdExtractionFunction.java deleted file mode 100644 index 8321f1806b..0000000000 --- a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/main/java/org/eclipse/tractusx/edc/protocol/core/identifier/MembershipCredentialIdExtractionFunction.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2025 Cofinity-X GmbH - * Copyright (c) 2026 SAP SE - * - * 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.protocol.core.identifier; - -import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential; -import org.eclipse.edc.protocol.spi.ParticipantIdExtractionFunction; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.iam.ClaimToken; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.result.Result; -import org.eclipse.tractusx.edc.core.utils.credentials.CredentialTypePredicate; - -import java.util.List; -import java.util.Optional; - -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_CREDENTIAL_NS; - -/** - * Base class for participant id extraction from a {@link ClaimToken} based on the MembershipCredential. - */ -public abstract class MembershipCredentialIdExtractionFunction implements ParticipantIdExtractionFunction { - - private static final String VC_CLAIM = "vc"; - private static final String IDENTITY_CREDENTIAL = "MembershipCredential"; - - private final CredentialTypePredicate typePredicate = new CredentialTypePredicate(CX_CREDENTIAL_NS, IDENTITY_CREDENTIAL); - private final Monitor monitor; - - public MembershipCredentialIdExtractionFunction(Monitor monitor) { - this.monitor = monitor.withPrefix(getClass().getSimpleName()); - } - - @Override - public String apply(ClaimToken claimToken) { - var credentials = getCredentialList(claimToken) - .orElseThrow(failure -> new EdcException("Failed to fetch credentials from the claim token: %s".formatted(failure.getFailureDetail()))); - - return credentials.stream() - .filter(typePredicate) - .findFirst() - .flatMap(this::getIdentifier) - .orElseThrow(() -> { - var msg = "Required credential type '%s' not present in ClaimToken, cannot extract property '%s'".formatted(IDENTITY_CREDENTIAL, identityProperty()); - monitor.warning(msg); - return new EdcException(msg); - }); - } - - @SuppressWarnings("unchecked") - private Result> getCredentialList(ClaimToken claimToken) { - var vcListClaim = claimToken.getClaims().get(VC_CLAIM); - - if (vcListClaim == null) { - var msg = "ClaimToken did not contain a '%s' claim.".formatted(VC_CLAIM); - monitor.warning(msg); - return Result.failure(msg); - } - if (!(vcListClaim instanceof List)) { - var msg = "ClaimToken contains a '%s' claim, but the type is incorrect. Expected %s, got %s.".formatted(VC_CLAIM, List.class.getName(), vcListClaim.getClass().getName()); - monitor.warning(msg); - return Result.failure(msg); - } - var vcList = (List) vcListClaim; - if (vcList.isEmpty()) { - var msg = "ClaimToken contains a '%s' claim but it did not contain any VerifiableCredentials.".formatted(VC_CLAIM); - monitor.warning(msg); - return Result.failure(msg); - } - return Result.success(vcList); - } - - public abstract String identityProperty(); - - public abstract Optional getIdentifier(VerifiableCredential vc); - -} diff --git a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/test/java/org/eclipse/tractusx/edc/protocol/core/CoreDataspaceProtocolExtensionTest.java b/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/test/java/org/eclipse/tractusx/edc/protocol/core/CoreDataspaceProtocolExtensionTest.java index 2540882798..4c4c05d871 100644 --- a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/test/java/org/eclipse/tractusx/edc/protocol/core/CoreDataspaceProtocolExtensionTest.java +++ b/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/test/java/org/eclipse/tractusx/edc/protocol/core/CoreDataspaceProtocolExtensionTest.java @@ -21,11 +21,11 @@ package org.eclipse.tractusx.edc.protocol.core; import org.eclipse.edc.boot.system.injection.ObjectFactory; +import org.eclipse.edc.iam.decentralizedclaims.core.defaults.DefaultDcpParticipantIdExtractionFunction; 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.tractusx.edc.protocol.core.identifier.DidExtractionFunction; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -63,7 +63,7 @@ void initialize_shouldRegisterProfileContexts(ObjectFactory factory, ServiceExte dataspaceProfileContext -> dataspaceProfileContext.name().equals(DATASPACE_PROTOCOL_HTTP_V_2025_1) && dataspaceProfileContext.protocolVersion().equals(V_2025_1) && dataspaceProfileContext.webhook().url().equals(webhook + V_2025_1_PATH) && - dataspaceProfileContext.idExtractionFunction() instanceof DidExtractionFunction + dataspaceProfileContext.idExtractionFunction() instanceof DefaultDcpParticipantIdExtractionFunction )); } } diff --git a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/test/java/org/eclipse/tractusx/edc/protocol/core/identifier/DidExtractionFunctionTest.java b/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/test/java/org/eclipse/tractusx/edc/protocol/core/identifier/DidExtractionFunctionTest.java deleted file mode 100644 index c60e899c12..0000000000 --- a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/test/java/org/eclipse/tractusx/edc/protocol/core/identifier/DidExtractionFunctionTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2025 Cofinity-X GmbH - * Copyright (c) 2026 SAP SE - * - * 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.protocol.core.identifier; - -import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential; -import org.eclipse.edc.spi.iam.ClaimToken; -import org.eclipse.edc.spi.monitor.Monitor; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.ArgumentsProvider; -import org.junit.jupiter.params.provider.ArgumentsSource; - -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.tractusx.edc.edr.spi.CoreConstants.CX_CREDENTIAL_NS; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class DidExtractionFunctionTest extends MembershipCredentialIdExtractionFunctionTest { - - public static final String ID_PROPERTY = "id"; - private final Monitor monitor = mock(); - - @Override - protected MembershipCredentialIdExtractionFunction extractionFunction() { - when(monitor.withPrefix(anyString())).thenReturn(monitor); - return new DidExtractionFunction(monitor); - } - - @Override - protected String expectedId() { - return DID; - } - - @ParameterizedTest - @ArgumentsSource(VerifiableCredentialArgumentProvider.class) - void apply(VerifiableCredential credential) { - var id = extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", List.of(credential)).build()); - assertThat(id).isEqualTo(expectedId()); - } - - private static class VerifiableCredentialArgumentProvider implements ArgumentsProvider { - @Override - public Stream provideArguments(ExtensionContext context) { - return Stream.of( - Arguments.of(vc("MembershipCredential", Map.of(ID_PROPERTY, DID))), - Arguments.of(vc(CX_CREDENTIAL_NS + "MembershipCredential", Map.of(ID_PROPERTY, DID))), - Arguments.of(vc(CX_CREDENTIAL_NS + "MembershipCredential", Map.of(ID_PROPERTY, DID, CX_CREDENTIAL_NS + ID_PROPERTY, DID)))); - } - } -} diff --git a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/testFixtures/java/org/eclipse/tractusx/edc/protocol/core/identifier/MembershipCredentialIdExtractionFunctionTest.java b/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/testFixtures/java/org/eclipse/tractusx/edc/protocol/core/identifier/MembershipCredentialIdExtractionFunctionTest.java deleted file mode 100644 index 6433c0d3c2..0000000000 --- a/edc-extensions/dataspace-protocol/dataspace-protocol-core/src/testFixtures/java/org/eclipse/tractusx/edc/protocol/core/identifier/MembershipCredentialIdExtractionFunctionTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - * Copyright (c) 2025 Cofinity-X GmbH - * Copyright (c) 2026 SAP SE - * - * 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.protocol.core.identifier; - -import org.eclipse.edc.iam.verifiablecredentials.spi.model.CredentialSubject; -import org.eclipse.edc.iam.verifiablecredentials.spi.model.Issuer; -import org.eclipse.edc.iam.verifiablecredentials.spi.model.VerifiableCredential; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.iam.ClaimToken; -import org.junit.jupiter.api.Test; - -import java.time.Instant; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public abstract class MembershipCredentialIdExtractionFunctionTest { - - public static final String DID = "did:web:example"; - - @Test - void apply_fails_WhenCredentialNotFound() { - var function = extractionFunction(); - assertThatThrownBy(() -> function.apply(ClaimToken.Builder.newInstance().claim("vc", List.of(vc("FooCredential", Map.of("foo", "bar")))).build())) - .isInstanceOf(EdcException.class) - .hasMessage("Required credential type 'MembershipCredential' not present in ClaimToken, cannot extract property '%s'", function.identityProperty()); - } - - @Test - void apply_fails_whenNoVcClaims() { - assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().build())) - .isInstanceOf(EdcException.class) - .hasMessageContaining("Failed to fetch credentials from the claim token: ClaimToken did not contain a 'vc' claim"); - } - - @Test - void apply_fails_whenNullVcClaims() { - - assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", null).build())) - .isInstanceOf(EdcException.class) - .hasMessageContaining("Failed to fetch credentials from the claim token: ClaimToken did not contain a 'vc' claim"); - } - - @Test - void apply_fails_WhenVcClaimIsNotList() { - assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", "wrong").build())) - .isInstanceOf(EdcException.class) - .hasMessageContaining("Failed to fetch credentials from the claim token: ClaimToken contains a 'vc' claim, but the type is incorrect. Expected java.util.List, got java.lang.String."); - } - - @Test - void apply_fails_WhenVcClaimsIsEmptyList() { - assertThatThrownBy(() -> extractionFunction().apply(ClaimToken.Builder.newInstance().claim("vc", List.of()).build())) - .isInstanceOf(EdcException.class) - .hasMessageContaining("Failed to fetch credentials from the claim token: ClaimToken contains a 'vc' claim but it did not contain any VerifiableCredentials."); - } - - public static VerifiableCredential vc(String type, Map claims) { - return VerifiableCredential.Builder.newInstance().type(type) - .issuanceDate(Instant.now()) - .issuer(new Issuer("issuer", Map.of())) - .credentialSubject(CredentialSubject.Builder.newInstance() - .id(claims.containsKey("id") ? claims.get("id").toString() : null) - .claims(claims) - .build()) - .build(); - } - - protected abstract MembershipCredentialIdExtractionFunction extractionFunction(); - - protected abstract String expectedId(); -} diff --git a/edc-extensions/dcp/cx-dcp/build.gradle.kts b/edc-extensions/dcp/cx-dcp/build.gradle.kts new file mode 100644 index 0000000000..d97a7b5593 --- /dev/null +++ b/edc-extensions/dcp/cx-dcp/build.gradle.kts @@ -0,0 +1,40 @@ +/******************************************************************************** + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE + * + * 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` + `maven-publish` +} + +dependencies { + implementation(libs.edc.spi.core) + implementation(libs.edc.spi.policyengine) + implementation(libs.edc.spi.decentralized.claims) + implementation(libs.edc.spi.contract) + implementation(libs.edc.spi.transfer) + implementation(libs.edc.spi.catalog) + implementation(libs.dsp.spi.v2025) + implementation(libs.dsp.spi.v08) + implementation(project(":spi:core-spi")) + implementation(project(":edc-extensions:dcp:tx-dcp")) + + testImplementation(libs.edc.junit) + testImplementation(project(":edc-extensions:cx-policy-legacy")) +} 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 new file mode 100644 index 0000000000..b2b2bed45b --- /dev/null +++ b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtension.java @@ -0,0 +1,75 @@ +/******************************************************************************** + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE + * + * 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.iam.dcp.cx; + +import org.eclipse.edc.policy.context.request.spi.RequestCatalogPolicyContext; +import org.eclipse.edc.policy.context.request.spi.RequestContractNegotiationPolicyContext; +import org.eclipse.edc.policy.context.request.spi.RequestTransferProcessPolicyContext; +import org.eclipse.edc.policy.engine.spi.PolicyEngine; +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.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.tractusx.edc.iam.iatp.scope.DefaultScopeExtractor; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +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.iam.dcp.cx.CxDcpDefaultScopeExtension.NAME; + +@Extension(NAME) +public class CxDcpDefaultScopeExtension implements ServiceExtension { + + static final String NAME = "CX default scope extension"; + @Inject + private PolicyEngine policyEngine; + + @Inject + private Monitor monitor; + + @Override + public String name() { + return NAME; + } + + @Override + public void initialize(ServiceExtensionContext context) { + var defaultScopes = defaultScopes(context); + 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) { + var scopesByVersion = new HashMap>(); + scopesByVersion.put(DSP_SCOPE_V_08, V08_DEFAULT_SCOPES); + scopesByVersion.put(DSP_SCOPE_V_2025_1, DEFAULT_SCOPES); + monitor.info(format("Registering catena-x default scopes %s", scopesByVersion)); + return scopesByVersion; + } +} diff --git a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/IatpScopeExtractorExtension.java b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpScopeExtractorExtension.java similarity index 81% rename from edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/IatpScopeExtractorExtension.java rename to edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpScopeExtractorExtension.java index ce868198c6..77c2db55ca 100644 --- a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/IatpScopeExtractorExtension.java +++ b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpScopeExtractorExtension.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iam.iatp; +package org.eclipse.tractusx.edc.iam.dcp.cx; import org.eclipse.edc.iam.decentralizedclaims.spi.scope.ScopeExtractorRegistry; import org.eclipse.edc.runtime.metamodel.annotation.Extension; @@ -25,13 +25,12 @@ 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.CredentialScopeExtractor; - -import static org.eclipse.tractusx.edc.iam.iatp.IatpScopeExtractorExtension.NAME; +import org.eclipse.tractusx.edc.iam.dcp.cx.scope.CxCredentialScopeExtractor; +import static org.eclipse.tractusx.edc.iam.dcp.cx.CxDcpScopeExtractorExtension.NAME; @Extension(NAME) -public class IatpScopeExtractorExtension implements ServiceExtension { +public class CxDcpScopeExtractorExtension implements ServiceExtension { static final String NAME = "Tractusx scope extractor extension"; @Inject @@ -47,6 +46,6 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - scopeExtractorRegistry.registerScopeExtractor(new CredentialScopeExtractor(monitor)); + scopeExtractorRegistry.registerScopeExtractor(new CxCredentialScopeExtractor(monitor)); } } diff --git a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/scope/CredentialScopeExtractor.java b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractor.java similarity index 96% rename from edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/scope/CredentialScopeExtractor.java rename to edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractor.java index 881ab81eb6..b85d8cfda0 100644 --- a/edc-extensions/dcp/tx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/iatp/scope/CredentialScopeExtractor.java +++ b/edc-extensions/dcp/cx-dcp/src/main/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractor.java @@ -19,7 +19,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iam.iatp.scope; +package org.eclipse.tractusx.edc.iam.dcp.cx.scope; import org.eclipse.edc.connector.controlplane.catalog.spi.CatalogRequestMessage; import org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractRequestMessage; @@ -45,7 +45,7 @@ * Extract and map from the Credential DSL the required credential type * The left operand should be bound to the namespace {@link org.eclipse.tractusx.edc.edr.spi.CoreConstants#CX_CREDENTIAL_NS} */ -public class CredentialScopeExtractor implements ScopeExtractor { +public class CxCredentialScopeExtractor implements ScopeExtractor { public static final String FRAMEWORK_AGREEMENT_LEFT_OPERAND = "FrameworkAgreement"; public static final String DATA_EXCHANGE_GOVERNANCE = "DataExchangeGovernance"; public static final String SCOPE_FORMAT = "%s:%s:read"; @@ -61,7 +61,7 @@ public class CredentialScopeExtractor implements ScopeExtractor { private final Monitor monitor; - public CredentialScopeExtractor(Monitor monitor) { + public CxCredentialScopeExtractor(Monitor monitor) { this.monitor = monitor.withPrefix(getClass().getSimpleName()); } diff --git a/edc-extensions/dcp/cx-dcp/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dcp/cx-dcp/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 0000000000..e0f6c0473f --- /dev/null +++ b/edc-extensions/dcp/cx-dcp/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,22 @@ +################################################################################# +# Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (c) 2026 SAP SE +# +# 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.iam.dcp.cx.CxDcpDefaultScopeExtension +org.eclipse.tractusx.edc.iam.dcp.cx.CxDcpScopeExtractorExtension 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 new file mode 100644 index 0000000000..1f7afdf0c5 --- /dev/null +++ b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpDefaultScopeExtensionTest.java @@ -0,0 +1,107 @@ +/******************************************************************************** + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE + * + * 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.iam.dcp.cx; + +import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; +import org.eclipse.edc.policy.context.request.spi.RequestCatalogPolicyContext; +import org.eclipse.edc.policy.context.request.spi.RequestContractNegotiationPolicyContext; +import org.eclipse.edc.policy.context.request.spi.RequestTransferProcessPolicyContext; +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.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentMatcher; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +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.mockito.ArgumentMatchers.argThat; +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) +public class CxDcpDefaultScopeExtensionTest { + + private final PolicyEngine policyEngine = mock(); + + @BeforeEach + void setup(ServiceExtensionContext context) { + context.registerService(PolicyEngine.class, policyEngine); + } + + @Test + void initialize(ServiceExtensionContext context, CxDcpDefaultScopeExtension extension) { + extension.initialize(context); + var scopes = new HashMap>(); + scopes.put(DSP_SCOPE_V_08, V08_DEFAULT_SCOPES); + scopes.put(DSP_SCOPE_V_2025_1, DEFAULT_SCOPES); + + verify(policyEngine).registerPostValidator(eq(RequestCatalogPolicyContext.class), argThat(new ScopeMatcher(scopes))); + verify(policyEngine).registerPostValidator(eq(RequestContractNegotiationPolicyContext.class), argThat(new ScopeMatcher(scopes))); + verify(policyEngine).registerPostValidator(eq(RequestTransferProcessPolicyContext.class), argThat(new ScopeMatcher(scopes))); + } + + @Test + void initialize_withConfiguredScopes(ServiceExtensionContext context, CxDcpDefaultScopeExtension extension) { + var cfg = ConfigFactory.fromMap(Map.of( + "foo.alias", "org.test.alias.foo", + "foo.type", "FooCredential", + "foo.operation", "read", + "bar.alias", "org.test.alias.bar", + "bar.type", "BarCredential", + "bar.operation", "write" + )); + when(context.getConfig(TX_IATP_DEFAULT_SCOPE_PREFIX)).thenReturn(cfg); + extension.initialize(context); + + var scopes = new HashMap>(); + scopes.put(DSP_SCOPE_V_08, V08_DEFAULT_SCOPES); + scopes.put(DSP_SCOPE_V_2025_1, DEFAULT_SCOPES); + + verify(policyEngine).registerPostValidator(eq(RequestCatalogPolicyContext.class), argThat(new ScopeMatcher(scopes))); + verify(policyEngine).registerPostValidator(eq(RequestContractNegotiationPolicyContext.class), argThat(new ScopeMatcher(scopes))); + verify(policyEngine).registerPostValidator(eq(RequestTransferProcessPolicyContext.class), argThat(new ScopeMatcher(scopes))); + } + + private record ScopeMatcher(Map> expectedScopes) implements ArgumentMatcher { + + @Override + public boolean matches(DefaultScopeExtractor defaultScopeExtractor) { + Map> defaultScopes = defaultScopeExtractor.defaultScopes(); + return defaultScopes.entrySet().stream() + .allMatch((Map.Entry> entry) -> { + Set expectedSet = expectedScopes.get(entry.getKey()); + return expectedSet != null && entry.getValue().containsAll(expectedSet); + }); + } + } +} diff --git a/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/IatpScopeExtractorExtensionTest.java b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpScopeExtractorExtensionTest.java similarity index 82% rename from edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/IatpScopeExtractorExtensionTest.java rename to edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpScopeExtractorExtensionTest.java index 164178b436..329cbcbe95 100644 --- a/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/IatpScopeExtractorExtensionTest.java +++ b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/CxDcpScopeExtractorExtensionTest.java @@ -17,12 +17,12 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iam.iatp; +package org.eclipse.tractusx.edc.iam.dcp.cx; import org.eclipse.edc.iam.decentralizedclaims.spi.scope.ScopeExtractorRegistry; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.tractusx.edc.iam.iatp.scope.CredentialScopeExtractor; +import org.eclipse.tractusx.edc.iam.dcp.cx.scope.CxCredentialScopeExtractor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -32,7 +32,7 @@ import static org.mockito.Mockito.verify; @ExtendWith(DependencyInjectionExtension.class) -public class IatpScopeExtractorExtensionTest { +public class CxDcpScopeExtractorExtensionTest { private final ScopeExtractorRegistry extractorRegistry = mock(); @@ -42,9 +42,9 @@ void setup(ServiceExtensionContext context) { } @Test - void initialize(ServiceExtensionContext context, IatpScopeExtractorExtension extension) { + void initialize(ServiceExtensionContext context, CxDcpScopeExtractorExtension extension) { extension.initialize(context); - verify(extractorRegistry).registerScopeExtractor(isA(CredentialScopeExtractor.class)); + verify(extractorRegistry).registerScopeExtractor(isA(CxCredentialScopeExtractor.class)); } } diff --git a/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/scope/CredentialScopeExtractorTest.java b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractorTest.java similarity index 96% rename from edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/scope/CredentialScopeExtractorTest.java rename to edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractorTest.java index 5d51806b84..9d0be57f2e 100644 --- a/edc-extensions/dcp/tx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/iatp/scope/CredentialScopeExtractorTest.java +++ b/edc-extensions/dcp/cx-dcp/src/test/java/org/eclipse/tractusx/edc/iam/dcp/cx/scope/CxCredentialScopeExtractorTest.java @@ -19,7 +19,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ -package org.eclipse.tractusx.edc.iam.iatp.scope; +package org.eclipse.tractusx.edc.iam.dcp.cx.scope; import org.eclipse.edc.connector.controlplane.catalog.spi.CatalogRequestMessage; import org.eclipse.edc.connector.controlplane.contract.spi.types.agreement.ContractAgreementMessage; @@ -50,7 +50,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.iam.iatp.scope.CredentialScopeExtractor.FRAMEWORK_AGREEMENT_LEFT_OPERAND; +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; import static org.eclipse.tractusx.edc.policy.cx.legacy.membership.MembershipCredentialConstraintFunction.MEMBERSHIP_LITERAL; @@ -58,18 +58,18 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class CredentialScopeExtractorTest { +public class CxCredentialScopeExtractorTest { private static final String DATA_EXCHANGE_GOVERNANCE_RIGHT_VALUE = "DataExchangeGovernance:1.0"; private static final String DATA_EXCHANGE_GOVERNANCE_CREDENTIAL = "DataExchangeGovernanceCredential"; private final Monitor monitor = mock(); - private CredentialScopeExtractor extractor; + private CxCredentialScopeExtractor extractor; @BeforeEach void setup() { when(monitor.withPrefix(anyString())).thenReturn(monitor); - extractor = new CredentialScopeExtractor(monitor); + extractor = new CxCredentialScopeExtractor(monitor); } @DisplayName("Scope extractor with supported messages") diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/build.gradle.kts b/edc-extensions/dcp/tx-dcp-sts-div/build.gradle.kts similarity index 100% rename from edc-extensions/dcp/tx-dcp-sts-dim/build.gradle.kts rename to edc-extensions/dcp/tx-dcp-sts-div/build.gradle.kts diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/DimOauthClientExtension.java b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/DivOauthClientExtension.java similarity index 85% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/DimOauthClientExtension.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/DivOauthClientExtension.java index bd0f4e47d2..10035d714e 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/DimOauthClientExtension.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/DivOauthClientExtension.java @@ -28,12 +28,12 @@ import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.security.Vault; import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth.DimOauth2Client; -import org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth.DimOauthClientImpl; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauth2Client; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauthClientImpl; import java.time.Clock; -public class DimOauthClientExtension implements ServiceExtension { +public class DivOauthClientExtension implements ServiceExtension { @Inject private Monitor monitor; @@ -54,7 +54,7 @@ public class DimOauthClientExtension implements ServiceExtension { private SingleParticipantContextSupplier singleParticipantContextSupplier; @Provider - public DimOauth2Client dimOauth2Client() { - return new DimOauthClientImpl(oauth2Client, vault, clientConfiguration, clock, monitor, singleParticipantContextSupplier); + public DivOauth2Client divOauth2Client() { + return new DivOauthClientImpl(oauth2Client, vault, clientConfiguration, clock, monitor, singleParticipantContextSupplier); } } diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/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 similarity index 80% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtension.java index 63331fa85a..7ff3d5452f 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/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 @@ -35,16 +35,17 @@ 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.dim.DimSecureTokenService; -import org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth.DimOauth2Client; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.DivSecureTokenService; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauth2Client; import static java.util.Optional.ofNullable; @Extension(RemoteTokenServiceClientExtension.NAME) public class RemoteTokenServiceClientExtension implements ServiceExtension { - @Setting(value = "STS Dim endpoint") - public static final String DIM_URL = "tx.edc.iam.sts.dim.url"; + @Setting(value = "STS Div endpoint") + public static final String DIV_URL = "tx.edc.iam.sts.div.url"; + protected static final String NAME = "Secure Token Service (STS) client extension"; @Inject @@ -60,7 +61,7 @@ public class RemoteTokenServiceClientExtension implements ServiceExtension { @Inject private Vault vault; @Inject - private DimOauth2Client dimOauth2Client; + private DivOauth2Client divOauth2Client; @Override public String name() { @@ -69,15 +70,15 @@ public String name() { @Provider public SecureTokenService secureTokenService(ServiceExtensionContext context) { - var dimUrlConfig = context.getSetting(DIM_URL, null); - return ofNullable(dimUrlConfig) + var divUrlConfig = context.getSetting(DIV_URL, null); + return ofNullable(divUrlConfig) .map(PathUtils::removeTrailingSlash) - .map(dimUrl -> { - monitor.info("DIM URL configured, will use DIM STS client"); - return (SecureTokenService) new DimSecureTokenService(httpClient, dimUrl, dimOauth2Client, typeManager.getMapper(), monitor); + .map(divUrl -> { + monitor.info("DIV URL configured, will use DIV STS client"); + return (SecureTokenService) new DivSecureTokenService(httpClient, divUrl, divOauth2Client, typeManager.getMapper(), monitor); }) .orElseGet(() -> { - monitor.info("DIM URL not configured, will use the standard EDC Remote STS client"); + monitor.info("DIV URL not configured, will use the standard EDC Remote STS client"); return new RemoteSecureTokenService(oauth2Client, participantContextId -> clientConfiguration, vault); }); } diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/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 similarity index 99% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtension.java index f9c3075aed..4994e281a5 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/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 @@ -61,7 +61,7 @@ public StsRemoteClientConfiguration clientConfiguration(ServiceExtensionContext 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 DIM"); + var monitor = context.getMonitor().withPrefix("STS Client for DIV"); if (tokenUrl == null) { missingMandatoryProperty(monitor, TOKEN_URL); } diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/DimSecureTokenService.java b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenService.java similarity index 91% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/DimSecureTokenService.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenService.java index a1857b0603..ff44ceb050 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/DimSecureTokenService.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenService.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.iam.dcp.sts.dim; +package org.eclipse.tractusx.edc.iam.dcp.sts.div; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -31,7 +31,7 @@ import org.eclipse.edc.spi.iam.TokenRepresentation; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.Result; -import org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth.DimOauth2Client; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauth2Client; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,14 +54,14 @@ import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.SUBJECT; /** - * Implementation of {@link SecureTokenService} that talks with DIM wallet. It supports two APIs for fetching the + * Implementation of {@link SecureTokenService} that talks with DIV wallet. It supports two APIs for fetching the * SI Token: *
    - *
  • grantAccess: request the SI token to DIM by providing the credential types required
  • - *
  • signToken: request the SI token to DIM by providing the extracted `token` from the received SI token
  • + *
  • grantAccess: request the SI token to DIV by providing the credential types required
  • + *
  • signToken: request the SI token to DIV by providing the extracted `token` from the received SI token
  • *
*/ -public class DimSecureTokenService implements SecureTokenService { +public class DivSecureTokenService implements SecureTokenService { public static final MediaType TYPE_JSON = MediaType.parse("application/json"); public static final String READ_SCOPE = "read"; @@ -71,8 +71,8 @@ public class DimSecureTokenService implements SecureTokenService { public static final String SIGN_TOKEN = "signToken"; private final EdcHttpClient httpClient; - private final String dimUrl; - private final DimOauth2Client dimOauth2Client; + private final String divUrl; + private final DivOauth2Client divOauth2Client; private final ObjectMapper mapper; private final Monitor monitor; @@ -86,10 +86,10 @@ public class DimSecureTokenService implements SecureTokenService { SUBJECT, "subject", PRESENTATION_TOKEN_CLAIM, PRESENTATION_TOKEN_CLAIM); - public DimSecureTokenService(EdcHttpClient httpClient, String dimUrl, DimOauth2Client dimOauth2Client, ObjectMapper mapper, Monitor monitor) { + public DivSecureTokenService(EdcHttpClient httpClient, String divUrl, DivOauth2Client divOauth2Client, ObjectMapper mapper, Monitor monitor) { this.httpClient = httpClient; - this.dimUrl = dimUrl; - this.dimOauth2Client = dimOauth2Client; + this.divUrl = divUrl; + this.divOauth2Client = divOauth2Client; this.mapper = mapper; this.monitor = monitor.withPrefix(getClass().getSimpleName()); } @@ -104,14 +104,14 @@ public Result createToken(String participantContextId, Map< private Result grantAccessRequest(Map claims, @Nullable String bearerAccessScope) { return grantAccessPayload(claims, bearerAccessScope) .compose(this::postRequest) - .map(builder -> builder.url(dimUrl).build()) + .map(builder -> builder.url(divUrl).build()) .compose(request -> executeRequest(request, GRANT_ACCESS)); } private Result signTokenRequest(Map claims) { return signTokenPayload(claims) .compose(this::postRequest) - .map(builder -> builder.url(dimUrl).build()) + .map(builder -> builder.url(divUrl).build()) .compose(request -> executeRequest(request, SIGN_TOKEN)); } @@ -177,7 +177,7 @@ private Result handleResponse(Response response) { .map(Result::success) .orElseGet(() -> Result.failure("Failed to get jwt field")); } catch (IOException e) { - monitor.warning("Failed to parse response from DIM"); + monitor.warning("Failed to parse response from DIV"); return Result.failure(e.getMessage()); } } @@ -195,7 +195,7 @@ private Result postRequest(Map body) { } private Result baseRequestWithToken() { - return dimOauth2Client.obtainRequestToken() + return divOauth2Client.obtainRequestToken() .map(this::baseRequestWithToken); } diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauth2Client.java b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauth2Client.java similarity index 91% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauth2Client.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauth2Client.java index fe6dd24295..1c0252e87e 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauth2Client.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauth2Client.java @@ -17,17 +17,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth; +package org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth; import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; import org.eclipse.edc.spi.iam.TokenRepresentation; import org.eclipse.edc.spi.result.Result; /** - * OAuth2 client for fetching an access token to be added when using the DIM APIs + * OAuth2 client for fetching an access token to be added when using the DIV APIs */ @ExtensionPoint -public interface DimOauth2Client { +public interface DivOauth2Client { /** * Request a token from the Auth server diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauthClientImpl.java b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauthClientImpl.java similarity index 95% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauthClientImpl.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauthClientImpl.java index f3da8a3a2f..febc7c0032 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauthClientImpl.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauthClientImpl.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth; +package org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth; import org.eclipse.edc.iam.decentralizedclaims.sts.remote.StsRemoteClientConfiguration; import org.eclipse.edc.iam.oauth2.spi.client.Oauth2Client; @@ -35,7 +35,7 @@ import java.time.temporal.ChronoUnit; import java.util.Optional; -public class DimOauthClientImpl implements DimOauth2Client { +public class DivOauthClientImpl implements DivOauth2Client { private static final String GRANT_TYPE = "client_credentials"; private final StsRemoteClientConfiguration configuration; @@ -48,7 +48,7 @@ public class DimOauthClientImpl implements DimOauth2Client { private volatile TimestampedToken authToken; - public DimOauthClientImpl(Oauth2Client oauth2Client, Vault vault, StsRemoteClientConfiguration configuration, Clock clock, + public DivOauthClientImpl(Oauth2Client oauth2Client, Vault vault, StsRemoteClientConfiguration configuration, Clock clock, Monitor monitor, ParticipantContextSupplier participantContextSupplier) { this.configuration = configuration; this.oauth2Client = oauth2Client; @@ -63,7 +63,7 @@ public Result obtainRequestToken() { if (isExpired()) { synchronized (this) { if (isExpired()) { - monitor.debug("DIM Token expired, need to refresh."); + monitor.debug("DIV Token expired, need to refresh."); // expiresIn should always be present, but if not we don't cache it return requestToken().onSuccess(tokenRepresentation -> Optional.ofNullable(tokenRepresentation.getExpiresIn()) .ifPresent(expiresIn -> this.authToken = new TimestampedToken(tokenRepresentation, Instant.now(clock), expiresIn))); diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dcp/tx-dcp-sts-div/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension similarity index 94% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension rename to edc-extensions/dcp/tx-dcp-sts-div/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index e39ca1f331..6fecc55dd5 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -17,7 +17,7 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -org.eclipse.tractusx.edc.iam.dcp.sts.DimOauthClientExtension +org.eclipse.tractusx.edc.iam.dcp.sts.DivOauthClientExtension org.eclipse.tractusx.edc.iam.dcp.sts.RemoteTokenServiceClientExtension org.eclipse.tractusx.edc.iam.dcp.sts.StsClientConfigurationExtension diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/DimOauthClientExtensionTest.java b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/DivOauthClientExtensionTest.java similarity index 82% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/DimOauthClientExtensionTest.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/DivOauthClientExtensionTest.java index 40a552847d..74410092bc 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/DimOauthClientExtensionTest.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/DivOauthClientExtensionTest.java @@ -20,17 +20,17 @@ package org.eclipse.tractusx.edc.iam.dcp.sts; import org.eclipse.edc.junit.extensions.DependencyInjectionExtension; -import org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth.DimOauth2Client; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauth2Client; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.assertj.core.api.Assertions.assertThat; @ExtendWith(DependencyInjectionExtension.class) -public class DimOauthClientExtensionTest { +public class DivOauthClientExtensionTest { @Test - void initialize(DimOauthClientExtension extension) { - assertThat(extension.dimOauth2Client()).isInstanceOf(DimOauth2Client.class); + void initialize(DivOauthClientExtension extension) { + assertThat(extension.divOauth2Client()).isInstanceOf(DivOauth2Client.class); } } diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/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 similarity index 92% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/RemoteTokenServiceClientExtensionTest.java index 1e79ceba34..ae5ab124ef 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/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 @@ -24,12 +24,12 @@ 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.tractusx.edc.iam.dcp.sts.dim.DimSecureTokenService; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.DivSecureTokenService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.tractusx.edc.iam.dcp.sts.RemoteTokenServiceClientExtension.DIM_URL; +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; @@ -41,8 +41,8 @@ public class RemoteTokenServiceClientExtensionTest { void initialize(ServiceExtensionContext context, RemoteTokenServiceClientExtension extension) { var config = mock(Config.class); when(context.getConfig()).thenReturn(config); - when(config.getString(DIM_URL, null)).thenReturn("url"); - assertThat(extension.secureTokenService(context)).isInstanceOf(DimSecureTokenService.class); + when(config.getString(DIV_URL, null)).thenReturn("url"); + assertThat(extension.secureTokenService(context)).isInstanceOf(DivSecureTokenService.class); } @Test diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/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 similarity index 100% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/StsClientConfigurationExtensionTest.java diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/DimSecureTokenServiceTest.java b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenServiceTest.java similarity index 95% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/DimSecureTokenServiceTest.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenServiceTest.java index 4af86fac40..c3eb5e7685 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/DimSecureTokenServiceTest.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/DivSecureTokenServiceTest.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.iam.dcp.sts.dim; +package org.eclipse.tractusx.edc.iam.dcp.sts.div; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -32,7 +32,7 @@ import org.eclipse.edc.spi.iam.TokenRepresentation; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.Result; -import org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth.DimOauth2Client; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauth2Client; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.invocation.InvocationOnMock; @@ -56,19 +56,19 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class DimSecureTokenServiceTest { +public class DivSecureTokenServiceTest { - static final String DIM_URL = "http://localhost:8080/iatp"; + static final String DIV_URL = "http://localhost:8080/iatp"; private final Monitor monitor = mock(Monitor.class); - private final DimOauth2Client oauth2Client = mock(DimOauth2Client.class); + private final DivOauth2Client oauth2Client = mock(DivOauth2Client.class); private final ObjectMapper mapper = new ObjectMapper(); private final Interceptor interceptor = mock(Interceptor.class); - private DimSecureTokenService client; + private DivSecureTokenService client; @BeforeEach void setup() { when(monitor.withPrefix(anyString())).thenReturn(monitor); - client = new DimSecureTokenService(testHttpClient(interceptor), DIM_URL, oauth2Client, mapper, monitor); + client = new DivSecureTokenService(testHttpClient(interceptor), DIV_URL, oauth2Client, mapper, monitor); } @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -89,7 +89,7 @@ void createToken_grantAccess() throws IOException { assertThat(((Map) payload)).containsAllEntriesOf(expectedBody); }); - assertThat(request.url().url().toString()).isEqualTo(DIM_URL); + assertThat(request.url().url().toString()).isEqualTo(DIV_URL); }; @@ -123,7 +123,7 @@ void createToken_signToken() throws IOException { assertThat(((Map) payload)).containsAllEntriesOf(expectedBody); }); - assertThat(request.url().url().toString()).isEqualTo(DIM_URL); + assertThat(request.url().url().toString()).isEqualTo(DIV_URL); }; @@ -140,7 +140,7 @@ void createToken_signToken() throws IOException { } @Test - void createToken_grantFails_withDimFailure() throws IOException { + void createToken_grantFails_withDivFailure() throws IOException { when(oauth2Client.obtainRequestToken()).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("token").build())); when(interceptor.intercept(isA(Interceptor.Chain.class))) @@ -204,7 +204,7 @@ void createToken_grantFails_whenInvalidScope() throws IOException { } @Test - void createToken_signFails_withDimFailure() throws IOException { + void createToken_signFails_withDivFailure() throws IOException { when(oauth2Client.obtainRequestToken()).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("token").build())); when(interceptor.intercept(isA(Interceptor.Chain.class))) diff --git a/edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauthClientImplTest.java b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauthClientImplTest.java similarity index 95% rename from edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauthClientImplTest.java rename to edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauthClientImplTest.java index 7184ee0500..3b10d09c94 100644 --- a/edc-extensions/dcp/tx-dcp-sts-dim/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/dim/oauth/DimOauthClientImplTest.java +++ b/edc-extensions/dcp/tx-dcp-sts-div/src/test/java/org/eclipse/tractusx/edc/iam/dcp/sts/div/oauth/DivOauthClientImplTest.java @@ -17,7 +17,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth; +package org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth; import org.eclipse.edc.iam.decentralizedclaims.sts.remote.StsRemoteClientConfiguration; import org.eclipse.edc.iam.oauth2.spi.client.Oauth2Client; @@ -43,7 +43,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -public class DimOauthClientImplTest { +public class DivOauthClientImplTest { private final Oauth2Client oauth2Client = mock(); private final Vault vault = mock(); @@ -62,7 +62,7 @@ void obtainRequestToken_withNoExpiration() { var tokenRepresentation = TokenRepresentation.Builder.newInstance().token("token").build(); when(vault.resolveSecret("participantContextId", "client_secret_alias")).thenReturn("client_secret"); when(oauth2Client.requestToken(any())).thenReturn(Result.success(tokenRepresentation)); - var client = new DimOauthClientImpl(oauth2Client, vault, config, Clock.systemUTC(), monitor, participantContextSupplier); + var client = new DivOauthClientImpl(oauth2Client, vault, config, Clock.systemUTC(), monitor, participantContextSupplier); var response = client.obtainRequestToken(); assertThat(response).isNotNull().extracting(Result::getContent).isEqualTo(tokenRepresentation); @@ -88,7 +88,7 @@ void obtainRequestToken_withExpiration_whenNotExpired() { var tokenRepresentation = TokenRepresentation.Builder.newInstance().token("token").expiresIn(10L).build(); when(vault.resolveSecret("participantContextId", "client_secret_alias")).thenReturn("client_secret"); when(oauth2Client.requestToken(any())).thenReturn(Result.success(tokenRepresentation)); - var client = new DimOauthClientImpl(oauth2Client, vault, config, Clock.systemUTC(), monitor, participantContextSupplier); + var client = new DivOauthClientImpl(oauth2Client, vault, config, Clock.systemUTC(), monitor, participantContextSupplier); var response = client.obtainRequestToken(); assertThat(response).isNotNull().extracting(Result::getContent).isEqualTo(tokenRepresentation); @@ -114,7 +114,7 @@ void obtainRequestToken_withExpiration_whenExpired() throws InterruptedException var tokenRepresentation = TokenRepresentation.Builder.newInstance().token("token").expiresIn(2L).build(); when(vault.resolveSecret("participantContextId", "client_secret_alias")).thenReturn("client_secret"); when(oauth2Client.requestToken(any())).thenReturn(Result.success(tokenRepresentation)); - var client = new DimOauthClientImpl(oauth2Client, vault, config, Clock.systemUTC(), monitor, participantContextSupplier); + var client = new DivOauthClientImpl(oauth2Client, vault, config, Clock.systemUTC(), monitor, participantContextSupplier); var response = client.obtainRequestToken(); assertThat(response).isNotNull().extracting(Result::getContent).isEqualTo(tokenRepresentation); @@ -141,7 +141,7 @@ void obtainRequestToken_failed() { var config = new StsRemoteClientConfiguration("http://localhost:8081/token", "clientId", "client_secret"); when(oauth2Client.requestToken(any())).thenReturn(Result.failure("failure")); - var client = new DimOauthClientImpl(oauth2Client, vault, config, Clock.systemUTC(), monitor, participantContextSupplier); + var client = new DivOauthClientImpl(oauth2Client, vault, config, Clock.systemUTC(), monitor, participantContextSupplier); var response = client.obtainRequestToken(); assertThat(response).isNotNull().matches(Result::failed); diff --git a/edc-extensions/dcp/tx-dcp/build.gradle.kts b/edc-extensions/dcp/tx-dcp/build.gradle.kts index 3b8eb84641..3e92bdd65d 100644 --- a/edc-extensions/dcp/tx-dcp/build.gradle.kts +++ b/edc-extensions/dcp/tx-dcp/build.gradle.kts @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -25,16 +26,13 @@ plugins { dependencies { implementation(libs.edc.spi.core) implementation(libs.edc.spi.policyengine) - implementation(libs.edc.spi.decentralized.claims) implementation(libs.edc.spi.contract) implementation(libs.edc.spi.transfer) implementation(libs.edc.spi.catalog) - implementation(libs.edc.spi.request.policy.context) implementation(libs.dsp.spi.v2025) implementation(libs.dsp.spi.v08) implementation(project(":spi:core-spi")) implementation(project(":core:core-utils")) testImplementation(libs.edc.junit) - testImplementation(project(":edc-extensions:cx-policy-legacy")) } 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/iatp/IatpDefaultScopeExtension.java index 51f69bf8e0..d6bb6b8694 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/iatp/IatpDefaultScopeExtension.java @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2026 SAP SE * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -40,8 +41,6 @@ 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.iam.iatp.IatpDefaultScopeExtension.NAME; @Extension(NAME) @@ -73,26 +72,23 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - policyEngine.registerPostValidator(RequestCatalogPolicyContext.class, new DefaultScopeExtractor<>(defaultScopes(context))); - policyEngine.registerPostValidator(RequestContractNegotiationPolicyContext.class, new DefaultScopeExtractor<>(defaultScopes(context))); - policyEngine.registerPostValidator(RequestTransferProcessPolicyContext.class, new DefaultScopeExtractor<>(defaultScopes(context))); + var defaultScopes = defaultScopes(context); + if (!defaultScopes.isEmpty()) { + 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) { var config = context.getConfig(TX_IATP_DEFAULT_SCOPE_PREFIX); var scopes = config.partition().map(this::createScope).collect(Collectors.toSet()); var scopesByVersion = new HashMap>(); - if (scopes.isEmpty()) { - monitor.info(format("No default scope from configuration. Using the default ones %s for %s and %s for %s", - DSP_SCOPE_V_2025_1, DEFAULT_SCOPES, DSP_SCOPE_V_08, V08_DEFAULT_SCOPES)); - scopesByVersion.put(DSP_SCOPE_V_08, V08_DEFAULT_SCOPES); - scopesByVersion.put(DSP_SCOPE_V_2025_1, DEFAULT_SCOPES); - return scopesByVersion; - } else { + if (!scopes.isEmpty()) { scopesByVersion.put(DSP_SCOPE_V_08, scopes); scopesByVersion.put(DSP_SCOPE_V_2025_1, scopes); - return scopesByVersion; } + return scopesByVersion; } private String createScope(Config config) { @@ -100,5 +96,6 @@ private String createScope(Config config) { var type = config.getString(TYPE); var operation = config.getString(OPERATION); return format("%s:%s:%s", alias, type, operation); + } } 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 8441c54b3b..98a37b4e5a 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 @@ -18,5 +18,3 @@ ################################################################################# org.eclipse.tractusx.edc.iam.iatp.IatpDefaultScopeExtension -org.eclipse.tractusx.edc.iam.iatp.IatpScopeExtractorExtension - 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/iatp/IatpDefaultScopeExtensionTest.java index 41af7ce700..f84dd8ee6f 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/iatp/IatpDefaultScopeExtensionTest.java @@ -1,5 +1,6 @@ /******************************************************************************** * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2025 SAP SE * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -40,12 +41,12 @@ 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.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.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; 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; @@ -62,13 +63,10 @@ void setup(ServiceExtensionContext context) { @Test void initialize(ServiceExtensionContext context, IatpDefaultScopeExtension extension) { extension.initialize(context); - var scopes = new HashMap>(); - scopes.put(DSP_SCOPE_V_08, V08_DEFAULT_SCOPES); - scopes.put(DSP_SCOPE_V_2025_1, DEFAULT_SCOPES); - verify(policyEngine).registerPostValidator(eq(RequestCatalogPolicyContext.class), argThat(new ScopeMatcher(scopes))); - verify(policyEngine).registerPostValidator(eq(RequestContractNegotiationPolicyContext.class), argThat(new ScopeMatcher(scopes))); - verify(policyEngine).registerPostValidator(eq(RequestTransferProcessPolicyContext.class), argThat(new ScopeMatcher(scopes))); + verify(policyEngine, never()).registerPostValidator(eq(RequestCatalogPolicyContext.class), any()); + verify(policyEngine, never()).registerPostValidator(eq(RequestContractNegotiationPolicyContext.class), any()); + verify(policyEngine, never()).registerPostValidator(eq(RequestTransferProcessPolicyContext.class), any()); } @Test diff --git a/edc-extensions/did-document/did-document-service-dim/README.md b/edc-extensions/did-document/did-document-service-div/README.md similarity index 88% rename from edc-extensions/did-document/did-document-service-dim/README.md rename to edc-extensions/did-document/did-document-service-div/README.md index 1df0c80687..c48b624d68 100644 --- a/edc-extensions/did-document/did-document-service-dim/README.md +++ b/edc-extensions/did-document/did-document-service-div/README.md @@ -1,14 +1,14 @@ -# did-document-service-dim +# did-document-service-div ## Overview -This extension provides a client for managing DID Document Service entries using the DIM (Decentralized Identity Management) API. +This extension provides a client for managing DID Document Service entries using the DIV (Decentralized Identity Verification) API. It enables secure and programmatic updates to DID Documents for organizations using the TractusX ecosystem. The client's purpose is to be injected in the `did-document-service-self-registration` extension by implementing the `DidDocumentServiceClient` SPI. ## API Details ### 1. Add DID Document Service -- **Endpoint:** `PATCH {dimUrl}/api/v2.0.0/companyIdentities/{companyIdentityId}` +- **Endpoint:** `PATCH {divUrl}/api/v2.0.0/companyIdentities/{companyIdentityId}` - **Description:** Adds or replaces a service entry in the DID Document. - **Sample Request:** @@ -44,7 +44,7 @@ The client's purpose is to be injected in the `did-document-service-self-registr ``` ### 2. Delete DID Document Service -- **Endpoint:** `PATCH {dimUrl}/api/v2.0.0/companyIdentities/{companyIdentityId}` +- **Endpoint:** `PATCH {divUrl}/api/v2.0.0/companyIdentities/{companyIdentityId}` - **Description:** Removes a service entry from the DID Document. - **Sample Request:** ```json @@ -71,7 +71,7 @@ The client's purpose is to be injected in the `did-document-service-self-registr ``` ### 3. Update Patch Status -- **Endpoint:** `PATCH {dimUrl}/api/v2.0.0/companyIdentities/{companyIdentityId}/status` +- **Endpoint:** `PATCH {divUrl}/api/v2.0.0/companyIdentities/{companyIdentityId}/status` - **Description:** Finalizes the update operation for the DID Document. This API call must be made after adding or deleting services. - **Sample Response:** ```json @@ -82,7 +82,7 @@ The client's purpose is to be injected in the `did-document-service-self-registr ``` ### 4. Resolve Company Identity -- **Endpoint:** `GET {dimUrl}/api/v2.0.0/companyIdentities?$filter=issuerDID eq "{ownDid}"` +- **Endpoint:** `GET {divUrl}/api/v2.0.0/companyIdentities?$filter=issuerDID eq "{ownDid}"` - **Description:** Resolves the company identity ID for the given DID. All DID Document Service operations require the company identity ID. - **Sample Response:** ```json @@ -109,4 +109,4 @@ The client's purpose is to be injected in the `did-document-service-self-registr ] } ``` -> All APIs require authentication using an authentication token generated via DIM. +> All APIs require authentication using an authentication token generated via DIV. diff --git a/edc-extensions/did-document/did-document-service-dim/build.gradle.kts b/edc-extensions/did-document/did-document-service-div/build.gradle.kts similarity index 95% rename from edc-extensions/did-document/did-document-service-dim/build.gradle.kts rename to edc-extensions/did-document/did-document-service-div/build.gradle.kts index b40d6db2b3..72b1af86c4 100644 --- a/edc-extensions/did-document/did-document-service-dim/build.gradle.kts +++ b/edc-extensions/did-document/did-document-service-div/build.gradle.kts @@ -24,7 +24,7 @@ plugins { dependencies { implementation(project(":spi:did-document-service-spi")) - implementation(project(":edc-extensions:dcp:tx-dcp-sts-dim")) + implementation(project(":edc-extensions:dcp:tx-dcp-sts-div")) implementation(project(":core:core-utils")) implementation(libs.edc.runtime.metamodel) implementation(libs.edc.spi.identity.did) diff --git a/edc-extensions/did-document/did-document-service-dim/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClient.java b/edc-extensions/did-document/did-document-service-div/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClient.java similarity index 94% rename from edc-extensions/did-document/did-document-service-dim/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClient.java rename to edc-extensions/did-document/did-document-service-div/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClient.java index 984be6eec7..a46959cf55 100644 --- a/edc-extensions/did-document/did-document-service-dim/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClient.java +++ b/edc-extensions/did-document/did-document-service-div/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClient.java @@ -32,7 +32,7 @@ import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.spi.result.ServiceResult; -import org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth.DimOauth2Client; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauth2Client; import org.eclipse.tractusx.edc.spi.did.document.service.DidDocumentServiceClient; import java.io.IOException; @@ -49,14 +49,14 @@ import static org.eclipse.edc.http.spi.FallbackFactories.retryWhenStatusIsNotIn; /** - * Implementation of {@link DidDocumentServiceClient} that interacts with a DIM (Decentralized Identity + * Implementation of {@link DidDocumentServiceClient} that interacts with a DIV (Decentralized Identity * Verification) Service to manage services in a DID Document. * - * Did Document is tied to a company identity in DIM, which is resolved using the own DID. Company identity is needed + * Did Document is tied to a company identity in DIV, which is resolved using the own DID. Company identity is needed * to perform any updates to the DID Document. * *

- * Did document update is a two-step process in DIM: + * Did document update is a two-step process in DIV: * 1. A PATCH request is sent to add or remove services. * Sample payload to add a service: *

@@ -75,29 +75,29 @@
  * }
  * 
* 2. A subsequent PATCH request is sent to the /status endpoint to finalize the update. - * PATCH {dimUrl}/companyIdentities/{companyIdentityId}/status + * PATCH {divUrl}/companyIdentities/{companyIdentityId}/status */ -public class DidDocumentServiceDimClient implements DidDocumentServiceClient { +public class DidDocumentServiceDivClient implements DidDocumentServiceClient { public static final MediaType TYPE_JSON = MediaType.parse("application/json"); private static final String DID_DOC_API_PATH = "/api/v2.0.0/companyIdentities"; private final EdcHttpClient httpClient; - private final DimOauth2Client dimOauth2Client; + private final DivOauth2Client divOauth2Client; private final ObjectMapper mapper; private final String ownDid; private final Monitor monitor; private final String didDocApiUrl; private final AtomicReference companyIdentity = new AtomicReference<>(); - public DidDocumentServiceDimClient(EdcHttpClient httpClient, - DimOauth2Client dimOauth2Client, ObjectMapper mapper, String dimUrl, String ownDid, Monitor monitor) { + public DidDocumentServiceDivClient(EdcHttpClient httpClient, + DivOauth2Client divOauth2Client, ObjectMapper mapper, String divHost, String ownDid, Monitor monitor) { this.httpClient = httpClient; - this.dimOauth2Client = dimOauth2Client; + this.divOauth2Client = divOauth2Client; this.mapper = mapper; this.ownDid = ownDid; this.monitor = monitor.withPrefix(getClass().getSimpleName()); - this.didDocApiUrl = String.join("", dimUrl, DID_DOC_API_PATH); + this.didDocApiUrl = String.join("", divHost, DID_DOC_API_PATH); } @Override @@ -204,7 +204,7 @@ Result handleDidUpdateResponse(Response response) { .map(success -> Result.success(body)) .orElseGet(() -> Result.failure("Failed to Update Did Document, res: %s".formatted(body))); } catch (IOException e) { - monitor.severe("Failed to parse did update response from DIM", e); + monitor.severe("Failed to parse did update response from DIV", e); return Result.failure(e.getMessage()); } } @@ -294,7 +294,7 @@ Result handlePatchStatusResponse(Response response) { .map(success -> Result.success(body)) .orElseGet(() -> Result.failure("Failed to Update Patch Status, res: %s".formatted(body))); } catch (IOException e) { - monitor.severe("Failed to parse patch status response from DIM", e); + monitor.severe("Failed to parse patch status response from DIV", e); return Result.failure(e.getMessage()); } } @@ -316,7 +316,7 @@ private Result createTenantBaseUrl() { * Handles the response for a company identity resolution request. * Package Private visibility for testing. *

- * It is expected that DIM returns exactly one company identity for the given DID. + * It is expected that DIV returns exactly one company identity for the given DID. * If none or multiple are returned, it is considered a failure. *

* The expected successful response structure is: @@ -362,7 +362,7 @@ Result handleCompanyIdentityResponse(Response response) { .map(Result::success) .orElseGet(() -> Result.failure("Failed to Resolve Company Identity Response, res: %s".formatted(body))); } catch (IOException e) { - monitor.severe("Failed to parse company identity response from DIM", e); + monitor.severe("Failed to parse company identity response from DIV", e); return Result.failure(e.getMessage()); } } @@ -385,7 +385,7 @@ private Result executeRequest(Request request, Function baseRequestWithToken() { - return dimOauth2Client.obtainRequestToken().map(this::baseRequestWithToken); + return divOauth2Client.obtainRequestToken().map(this::baseRequestWithToken); } private Request.Builder baseRequestWithToken(TokenRepresentation tokenRepresentation) { diff --git a/edc-extensions/did-document/did-document-service-dim/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClientExtension.java b/edc-extensions/did-document/did-document-service-div/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClientExtension.java similarity index 71% rename from edc-extensions/did-document/did-document-service-dim/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClientExtension.java rename to edc-extensions/did-document/did-document-service-div/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClientExtension.java index 03ee87bd12..95417834d3 100644 --- a/edc-extensions/did-document/did-document-service-dim/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClientExtension.java +++ b/edc-extensions/did-document/did-document-service-div/src/main/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClientExtension.java @@ -27,18 +27,19 @@ 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.dim.oauth.DimOauth2Client; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauth2Client; import org.eclipse.tractusx.edc.spi.did.document.service.DidDocumentServiceClient; +import java.net.URI; + @Provides(DidDocumentServiceClient.class) -public class DidDocumentServiceDimClientExtension implements ServiceExtension { +public class DidDocumentServiceDivClientExtension implements ServiceExtension { @Inject private EdcHttpClient httpClient; @Inject(required = false) - private DimOauth2Client dimOauth2Client; + private DivOauth2Client divOauth2Client; @Inject private TypeManager typeManager; @@ -46,8 +47,8 @@ public class DidDocumentServiceDimClientExtension implements ServiceExtension { @Inject private Monitor monitor; - @Setting(key = "tx.edc.iam.sts.dim.url", description = "STS Dim endpoint", required = false) - private String dimUrl; + @Setting(key = "tx.edc.iam.sts.div.url", description = "STS Div endpoint", required = false) + private String divUrl; @Setting(key = "edc.participant.id", description = "EDC Participant Id") private String ownDid; @@ -55,17 +56,22 @@ public class DidDocumentServiceDimClientExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - if (dimUrl == null || dimUrl.isBlank() || dimOauth2Client == null) { - monitor.info("DidDocumentServiceDIMClient will not be registered because DIM URL not configured or an implementation of DimOauth2Client is missing"); + if (divUrl == null || divUrl.isBlank() || divOauth2Client == null) { + monitor.info("DidDocumentServiceDIVClient will not be registered because DIV URL not configured or an implementation of DivOauth2Client is missing"); } else { - var client = new DidDocumentServiceDimClient( + var client = new DidDocumentServiceDivClient( httpClient, - dimOauth2Client, + divOauth2Client, typeManager.getMapper(), - PathUtils.removeTrailingSlash(dimUrl), + getHostWithScheme(divUrl), ownDid, monitor); context.registerService(DidDocumentServiceClient.class, client); } } + + private String getHostWithScheme(String url) { + var uri = URI.create(url); + return "%s://%s".formatted(uri.getScheme(), uri.getAuthority()); + } } diff --git a/edc-extensions/did-document/did-document-service-dim/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/did-document/did-document-service-div/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension similarity index 97% rename from edc-extensions/did-document/did-document-service-dim/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension rename to edc-extensions/did-document/did-document-service-div/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index d79dc65c91..55350abf7c 100644 --- a/edc-extensions/did-document/did-document-service-dim/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/edc-extensions/did-document/did-document-service-div/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.did.document.service.DidDocumentServiceDimClientExtension +org.eclipse.tractusx.edc.did.document.service.DidDocumentServiceDivClientExtension diff --git a/edc-extensions/did-document/did-document-service-dim/src/test/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClientTest.java b/edc-extensions/did-document/did-document-service-div/src/test/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClientTest.java similarity index 97% rename from edc-extensions/did-document/did-document-service-dim/src/test/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClientTest.java rename to edc-extensions/did-document/did-document-service-div/src/test/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClientTest.java index 7651824cb9..403b544f6b 100644 --- a/edc-extensions/did-document/did-document-service-dim/src/test/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDimClientTest.java +++ b/edc-extensions/did-document/did-document-service-div/src/test/java/org/eclipse/tractusx/edc/did/document/service/DidDocumentServiceDivClientTest.java @@ -33,7 +33,7 @@ import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.result.Result; import org.eclipse.edc.spi.result.ServiceFailure; -import org.eclipse.tractusx.edc.iam.dcp.sts.dim.oauth.DimOauth2Client; +import org.eclipse.tractusx.edc.iam.dcp.sts.div.oauth.DivOauth2Client; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -61,7 +61,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -class DidDocumentServiceDimClientTest { +class DidDocumentServiceDivClientTest { private static final String COMPANY_ID = "ddfdcbad-44b2-43b5-b49f-6347ec2e586a"; @@ -70,27 +70,27 @@ class DidDocumentServiceDimClientTest { private static final String DATA_SERVICE_ENDPOINT = "https://edc.com/edc/.well-known/dspace-version"; private final EdcHttpClient httpClient = mock(EdcHttpClient.class); - private final DimOauth2Client dimOauth2Client = mock(DimOauth2Client.class); + private final DivOauth2Client divOauth2Client = mock(DivOauth2Client.class); private final ObjectMapper mapper = new ObjectMapper(); private final Monitor monitor = mock(Monitor.class); - private final String dimUrl = "https://div.example.com"; - private final String didDocApiUrl = String.join("", dimUrl, "/api/v2.0.0/companyIdentities"); + private final String divHost = "https://div.example.com"; + private final String didDocApiUrl = String.join("", divHost, "/api/v2.0.0/companyIdentities"); private final String tenantBaseUrl = String.join("/", didDocApiUrl, COMPANY_ID); private final String didUpdateStatusUrl = String.join("", tenantBaseUrl + "/status"); private final String ownDid = "did:web:example.com:123"; - private DidDocumentServiceDimClient client; + private DidDocumentServiceDivClient client; @BeforeEach void setUp() { when(monitor.withPrefix(anyString())).thenReturn(monitor); - client = new DidDocumentServiceDimClient(httpClient, dimOauth2Client, mapper, dimUrl, ownDid, monitor); + client = new DidDocumentServiceDivClient(httpClient, divOauth2Client, mapper, divHost, ownDid, monitor); } @Test void update_service_success() { - when(dimOauth2Client.obtainRequestToken()).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("token").build())); + when(divOauth2Client.obtainRequestToken()).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("token").build())); when(httpClient.execute(any(Request.class), anyList(), any())) .thenReturn(Result.success(COMPANY_ID)) // resolve company id .thenReturn(Result.success("")) // delete service @@ -175,7 +175,7 @@ private static class InvalidServiceProvider implements ArgumentsProvider { @Test void deleteById_success() { - when(dimOauth2Client.obtainRequestToken()).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("token").build())); + when(divOauth2Client.obtainRequestToken()).thenReturn(Result.success(TokenRepresentation.Builder.newInstance().token("token").build())); when(httpClient.execute(any(Request.class), anyList(), any())) .thenReturn(Result.success(COMPANY_ID)) // resolve company id .thenReturn(Result.success("")) // delete service 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 256a4a8264..a4c2e9e8ad 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 @@ -40,7 +40,6 @@ public class DidDocumentServiceSelfRegistrationExtension implements ServiceExten public static final String TX_EDC_DID_SERVICE_SELF_REGISTRATION_ID = "tx.edc.did.service.self.registration.id"; public static final String DATA_SERVICE_TYPE = "DataService"; - private static final String DATA_SERVICE_ID_WITH_TYPE_TEMPLATE = "%s#%s"; public static final String VERSION_METADATA_ENDPOINT_PATH = "/.well-known/dspace-version"; @Inject @@ -81,8 +80,7 @@ private void selfRegisterDidDocumentService(@NotNull DidDocumentServiceClient cl var wellKnownUrl = String.join("", dspBaseAddress.get(), VERSION_METADATA_ENDPOINT_PATH); validatedServiceId(serviceId) .onFailure(failure -> monitor.severe(failure.getFailureDetail())) - .map(id -> DATA_SERVICE_ID_WITH_TYPE_TEMPLATE.formatted(id, DATA_SERVICE_TYPE)) - .map(serviceIdWithType -> new Service(serviceIdWithType, DATA_SERVICE_TYPE, wellKnownUrl)) + .map(validatedServiceId -> new Service(validatedServiceId, DATA_SERVICE_TYPE, wellKnownUrl)) .onSuccess(service -> client.update(service) .onFailure(failure -> monitor.severe("Failed to self-register DID Document service: %s, reason: %s".formatted(failure.getFailureDetail(), failure.getReason()))) @@ -93,9 +91,8 @@ private void selfRegisterDidDocumentService(@NotNull DidDocumentServiceClient cl private void selfUnregisterDidDocumentService(@NotNull DidDocumentServiceClient client) { validatedServiceId(serviceId) - .map(id -> DATA_SERVICE_ID_WITH_TYPE_TEMPLATE.formatted(id, DATA_SERVICE_TYPE)) - .onSuccess(serviceIdWithType -> - client.deleteById(serviceIdWithType) + .onSuccess(validatedServiceId -> + client.deleteById(validatedServiceId) .onFailure(failure -> monitor.severe("Failed to unregister DID Document service: %s, reason: %s".formatted(failure.getFailureDetail(), failure.getReason()))) .onSuccess(result -> monitor.info("Successfully unregistered DID Document service")) ); 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 71da8f4031..939196717a 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 @@ -79,14 +79,14 @@ void start_shouldSelfRegister_whenEnabledAndClientPresent(ServiceExtensionContex extension.start(); verify(didDocumentServiceClient).update(argThat(service -> - service.getId().equals(SERVICE_ID + "#" + DATA_SERVICE_TYPE) && + service.getId().equals(SERVICE_ID) && service.getType().equals(DATA_SERVICE_TYPE) && service.getServiceEndpoint().equals(DSP_URL + "/.well-known/dspace-version"))); verify(monitor).info("Self Registration of DID Document service successful"); verify(monitor, never()).info("Did Document Service Client not available or not enabled, skipping self-registration"); extension.shutdown(); - verify(didDocumentServiceClient).deleteById(SERVICE_ID + "#" + DATA_SERVICE_TYPE); + verify(didDocumentServiceClient).deleteById(SERVICE_ID); verify(monitor).info("Successfully unregistered DID Document service"); } @@ -105,14 +105,14 @@ void start_selfRegister_whenEnabledAndClientReturnsFailure(ServiceExtensionConte extension.start(); verify(didDocumentServiceClient).update(argThat(service -> - service.getId().equals(SERVICE_ID + "#" + DATA_SERVICE_TYPE) && + service.getId().equals(SERVICE_ID) && service.getType().equals(DATA_SERVICE_TYPE) && service.getServiceEndpoint().equals(DSP_URL + "/.well-known/dspace-version"))); verify(monitor).severe(contains("Failed to self-register DID Document service")); verify(monitor, never()).info("Did Document Service Client not available or not enabled, skipping self-registration"); extension.shutdown(); - verify(didDocumentServiceClient).deleteById(SERVICE_ID + "#" + DATA_SERVICE_TYPE); + verify(didDocumentServiceClient).deleteById(SERVICE_ID); verify(monitor).severe(contains("Failed to unregister DID Document service")); } diff --git a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiExtension.java b/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiExtension.java index ee2aa6e917..d4871f37d9 100644 --- a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiExtension.java +++ b/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiExtension.java @@ -35,7 +35,6 @@ import org.eclipse.edc.web.spi.WebService; import org.eclipse.edc.web.spi.configuration.ApiContext; import org.eclipse.tractusx.edc.api.edr.transform.JsonObjectFromEndpointDataReferenceEntryTransformer; -import org.eclipse.tractusx.edc.api.edr.v2.EdrCacheApiV2Controller; import org.eclipse.tractusx.edc.api.edr.v3.EdrCacheApiV3Controller; import org.eclipse.tractusx.edc.edr.spi.service.EdrService; @@ -71,9 +70,6 @@ public class EdrCacheApiExtension implements ServiceExtension { public void initialize(ServiceExtensionContext context) { var mgmtApiTransformerRegistry = transformerRegistry.forContext("management-api"); mgmtApiTransformerRegistry.register(new JsonObjectFromEndpointDataReferenceEntryTransformer(Json.createBuilderFactory(Map.of()))); - webService.registerResource(MANAGEMENT, new EdrCacheApiV2Controller(edrStore, mgmtApiTransformerRegistry, validatorRegistry, monitor, edrService, contractNegotiationService, singleParticipantContextSupplier)); - webService.registerDynamicResource(ApiContext.MANAGEMENT, EdrCacheApiV2Controller.class, new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, "MANAGEMENT_API")); - webService.registerResource(MANAGEMENT, new EdrCacheApiV3Controller(edrStore, mgmtApiTransformerRegistry, validatorRegistry, monitor, edrService, contractNegotiationService, singleParticipantContextSupplier)); webService.registerDynamicResource(ApiContext.MANAGEMENT, EdrCacheApiV3Controller.class, new JerseyJsonLdInterceptor(jsonLd, typeManager, JSON_LD, "MANAGEMENT_API")); } diff --git a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2.java b/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2.java deleted file mode 100644 index 5a34601b1c..0000000000 --- a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2.java +++ /dev/null @@ -1,133 +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 - */ - -package org.eclipse.tractusx.edc.api.edr.v2; - -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.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.JsonArray; -import jakarta.json.JsonObject; -import org.eclipse.edc.api.model.ApiCoreSchema; -import org.eclipse.edc.connector.controlplane.api.management.contractnegotiation.v3.ContractNegotiationApiV3; -import org.eclipse.edc.edr.spi.types.EndpointDataReferenceEntry; -import org.eclipse.edc.web.spi.ApiErrorDetail; - -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; -import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.TYPE; - -@OpenAPIDefinition -@Tag(name = "Control Plane EDR Api") -@Deprecated(since = "0.8.0") -public interface EdrCacheApiV2 { - - @Operation(description = "Initiates an EDR negotiation by handling a contract negotiation first and then a transfer process for a given offer and with the given counter part. Please note that successfully invoking this endpoint " + - "only means that the negotiation was initiated.", - deprecated = true, - responses = { - @ApiResponse(responseCode = "200", description = "The negotiation was successfully initiated.", - content = @Content(schema = @Schema(implementation = ApiCoreSchema.IdResponseSchema.class))), - @ApiResponse(responseCode = "400", description = "Request body was malformed", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiErrorDetail.class)))), - }) - JsonObject initiateEdrNegotiationV2(@Schema(implementation = ContractNegotiationApiV3.ContractRequestSchema.class) JsonObject dto); - - @Operation(description = "Request all Edr entries according to a particular query", - deprecated = true, - requestBody = @RequestBody( - content = @Content(schema = @Schema(implementation = ApiCoreSchema.QuerySpecSchema.class)) - ), - responses = { - @ApiResponse(responseCode = "200", description = "The edr entries matching the query", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = EndpointDataReferenceEntrySchema.class)))), - @ApiResponse(responseCode = "400", description = "Request body was malformed", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) - }) - JsonArray requestEdrEntriesV2(JsonObject querySpecJson); - - @Operation(description = "Gets the EDR data address with the given transfer process ID", - deprecated = true, - parameters = { @Parameter(name = "transferProcessId", description = "The ID of the transferprocess for which the EDR should be fetched", required = true), - @Parameter(name = "auto_refresh", description = "Whether the access token that is stored on the EDR should be checked for expiry, and renewed if necessary. Default is true.") - }, - responses = { - @ApiResponse(responseCode = "200", description = "The data address", - content = @Content(schema = @Schema(implementation = ApiCoreSchema.DataAddressSchema.class))), - @ApiResponse(responseCode = "400", description = "Request was malformed, e.g. id was null", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), - @ApiResponse(responseCode = "404", description = "An EDR data address with the given transfer process ID does not exist", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) - } - ) - JsonObject getEdrEntryDataAddressV2(String transferProcessId, boolean autoRefresh); - - @Operation(description = "Removes an EDR entry given the transfer process ID", - deprecated = true, - responses = { - @ApiResponse(responseCode = "204", description = "EDR entry was deleted successfully"), - @ApiResponse(responseCode = "400", description = "Request was malformed, e.g. id was null", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), - @ApiResponse(responseCode = "404", description = "An EDR entry with the given ID does not exist", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) - }) - void removeEdrEntryV2(String transferProcessId); - - @Operation(description = "Refreshes and returns the EDR data address with the given transfer process ID", - deprecated = true, - parameters = { @Parameter(name = "transferProcessId", description = "The ID of the transferprocess for which the EDR should be fetched", required = true), - }, - responses = { - @ApiResponse(responseCode = "200", description = "The data address", - content = @Content(schema = @Schema(implementation = ApiCoreSchema.DataAddressSchema.class))), - @ApiResponse(responseCode = "400", description = "Request was malformed, e.g. id was null", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))), - @ApiResponse(responseCode = "404", description = "An EDR data address with the given transfer process ID does not exist", - content = @Content(array = @ArraySchema(schema = @Schema(implementation = ApiCoreSchema.ApiErrorDetailSchema.class)))) - } - ) - JsonObject refreshEdrV2(String transferProcessId); - - @ArraySchema() - @Schema(name = "EndpointDataReferenceEntry", example = EndpointDataReferenceEntrySchema.EDR_ENTRY_OUTPUT_EXAMPLE, deprecated = true) - record EndpointDataReferenceEntrySchema( - @Schema(name = ID) - String id, - @Schema(name = TYPE, example = EndpointDataReferenceEntry.EDR_ENTRY_TYPE) - String type - ) { - public static final String EDR_ENTRY_OUTPUT_EXAMPLE = """ - { - "@context": { "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, - "@id": "transfer-process-id", - "transferProcessId": "transfer-process-id", - "agreementId": "agreement-id", - "contractNegotiationId": "contract-negotiation-id", - "assetId": "asset-id", - "providerId": "provider-id", - "createdAt": 1688465655 - } - """; - } -} diff --git a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2Controller.java b/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2Controller.java deleted file mode 100644 index 75636876ae..0000000000 --- a/edc-extensions/edr/edr-api-v2/src/main/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2Controller.java +++ /dev/null @@ -1,99 +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 - */ - -package org.eclipse.tractusx.edc.api.edr.v2; - -import jakarta.json.JsonArray; -import jakarta.json.JsonObject; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.DefaultValue; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.QueryParam; -import jakarta.ws.rs.core.MediaType; -import org.eclipse.edc.connector.controlplane.services.spi.contractnegotiation.ContractNegotiationService; -import org.eclipse.edc.edr.spi.store.EndpointDataReferenceStore; -import org.eclipse.edc.participantcontext.spi.service.ParticipantContextSupplier; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.transform.spi.TypeTransformerRegistry; -import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; -import org.eclipse.tractusx.edc.api.edr.BaseEdrCacheApiController; -import org.eclipse.tractusx.edc.edr.spi.service.EdrService; - -import static org.eclipse.edc.api.ApiWarnings.deprecationWarning; - -@Consumes({ MediaType.APPLICATION_JSON }) -@Produces({ MediaType.APPLICATION_JSON }) -@Path("/v2/edrs") -@Deprecated(since = "0.8.0") -public class EdrCacheApiV2Controller extends BaseEdrCacheApiController implements EdrCacheApiV2 { - - public EdrCacheApiV2Controller(EndpointDataReferenceStore edrStore, - TypeTransformerRegistry transformerRegistry, - JsonObjectValidatorRegistry validator, - Monitor monitor, - EdrService edrService, ContractNegotiationService contractNegotiationService, - ParticipantContextSupplier participantContextSupplier) { - super(edrStore, transformerRegistry, validator, monitor, edrService, participantContextSupplier, contractNegotiationService); - } - - @POST - @Override - public JsonObject initiateEdrNegotiationV2(JsonObject requestObject) { - monitor.warning(deprecationWarning("/v2", "/v3")); - return super.initiateEdrNegotiation(requestObject); - } - - @POST - @Path("/request") - @Override - public JsonArray requestEdrEntriesV2(JsonObject querySpecJson) { - monitor.warning(deprecationWarning("/v2", "/v3")); - return requestEdrEntries(querySpecJson); - } - - @GET - @Path("{transferProcessId}/dataaddress") - @Override - public JsonObject getEdrEntryDataAddressV2(@PathParam("transferProcessId") String transferProcessId, @DefaultValue("true") @QueryParam("auto_refresh") boolean autoRefresh) { - monitor.warning(deprecationWarning("/v2", "/v3")); - return super.getEdrEntryDataAddress(transferProcessId, autoRefresh); - } - - @DELETE - @Path("{transferProcessId}") - @Override - public void removeEdrEntryV2(@PathParam("transferProcessId") String transferProcessId) { - monitor.warning(deprecationWarning("/v2", "/v3")); - super.removeEdrEntry(transferProcessId); - } - - @POST - @Path("{transferProcessId}/refresh") - @Override - public JsonObject refreshEdrV2(@PathParam("transferProcessId") String transferProcessId) { - monitor.warning(deprecationWarning("/v2", "/v3")); - return super.refreshEdr(transferProcessId); - } - -} diff --git a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiExtensionTest.java b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiExtensionTest.java index 6214ea21f8..cd787d5ef3 100644 --- a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiExtensionTest.java +++ b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiExtensionTest.java @@ -25,7 +25,6 @@ import org.eclipse.edc.validator.spi.JsonObjectValidatorRegistry; import org.eclipse.edc.web.spi.WebService; import org.eclipse.tractusx.edc.api.edr.transform.JsonObjectFromEndpointDataReferenceEntryTransformer; -import org.eclipse.tractusx.edc.api.edr.v2.EdrCacheApiV2Controller; import org.eclipse.tractusx.edc.api.edr.v3.EdrCacheApiV3Controller; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -58,7 +57,6 @@ void setUp(ServiceExtensionContext context) { void initialize_shouldRegisterControllers(EdrCacheApiExtension extension, ServiceExtensionContext context) { extension.initialize(context); - verify(webService).registerResource(any(), isA(EdrCacheApiV2Controller.class)); verify(webService).registerResource(any(), isA(EdrCacheApiV3Controller.class)); } diff --git a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiTest.java b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiTest.java index 2122044269..2b8bbe2fc6 100644 --- a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiTest.java +++ b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/EdrCacheApiTest.java @@ -36,7 +36,7 @@ import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.ID; import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.VALUE; import static org.eclipse.edc.junit.assertions.AbstractResultAssert.assertThat; -import static org.eclipse.tractusx.edc.api.edr.v2.EdrCacheApiV2.EndpointDataReferenceEntrySchema.EDR_ENTRY_OUTPUT_EXAMPLE; +import static org.eclipse.tractusx.edc.api.edr.v3.EdrCacheApiV3.EndpointDataReferenceEntrySchema.EDR_ENTRY_OUTPUT_EXAMPLE; import static org.mockito.Mockito.mock; public class EdrCacheApiTest { diff --git a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2ControllerTest.java b/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2ControllerTest.java deleted file mode 100644 index 9e220725cd..0000000000 --- a/edc-extensions/edr/edr-api-v2/src/test/java/org/eclipse/tractusx/edc/api/edr/v2/EdrCacheApiV2ControllerTest.java +++ /dev/null @@ -1,48 +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 - */ - -package org.eclipse.tractusx.edc.api.edr.v2; - -import io.restassured.specification.RequestSpecification; -import org.eclipse.edc.junit.annotations.ApiTest; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.tractusx.edc.api.edr.BaseEdrCacheApiControllerTest; - -import static io.restassured.RestAssured.given; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@ApiTest -public class EdrCacheApiV2ControllerTest extends BaseEdrCacheApiControllerTest { - - @Override - protected Object controller() { - var monitor = mock(Monitor.class); - when(monitor.withPrefix(anyString())).thenReturn(monitor); - return new EdrCacheApiV2Controller(edrStore, transformerRegistry, validator, monitor, edrService, contractNegotiationService, participantContextSupplier); - } - - protected RequestSpecification baseRequest() { - return given() - .baseUri("http://localhost:" + port + "/v2") - .when(); - } - -} 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 e2efb589cb..009a7d20d9 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,10 +37,6 @@ @Extension(value = "Database-level EDR Lock extension (PostgreSQL)") public class SqlEdrLockExtension implements ServiceExtension { - - @Deprecated(since = "0.8.1") - public static final String DATASOURCE_SETTING_NAME = "edc.datasource.edr.name"; - @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) public static final String DATASOURCE_NAME = "edc.sql.store.edr.datasource"; @@ -67,6 +63,4 @@ public void initialize(ServiceExtensionContext context) { context.registerService(EndpointDataReferenceLock.class, sqlStore); } - - } diff --git a/edc-extensions/federated-catalog/src/main/java/org/eclipse/tractusx/edc/federatedcatalog/FederatedCatalogExtension.java b/edc-extensions/federated-catalog/src/main/java/org/eclipse/tractusx/edc/federatedcatalog/FederatedCatalogExtension.java deleted file mode 100644 index d2c0958f7d..0000000000 --- a/edc-extensions/federated-catalog/src/main/java/org/eclipse/tractusx/edc/federatedcatalog/FederatedCatalogExtension.java +++ /dev/null @@ -1,85 +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.federatedcatalog; - -import org.eclipse.edc.crawler.spi.TargetNode; -import org.eclipse.edc.crawler.spi.TargetNodeDirectory; -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.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.types.TypeManager; - -import java.io.File; -import java.util.Collections; -import java.util.List; - -import static java.util.Optional.ofNullable; -import static org.eclipse.tractusx.edc.federatedcatalog.FederatedCatalogExtension.NAME; - - -@Extension(value = NAME) -public class FederatedCatalogExtension implements ServiceExtension { - - public static final String NAME = "Tractus-X Federated Catalog Extension"; - - @Setting(value = "File path to a JSON file containing TargetNode entries for the Federated Catalog Crawler") - public static final String NODE_LIST_FILE = "tx.edc.catalog.node.list.file"; - - @Inject - private TypeManager typeManager; - - - @Override - public String name() { - return NAME; - } - - @Provider - public TargetNodeDirectory createFileBasedNodeDirectory(ServiceExtensionContext context) { - return ofNullable(context.getConfig().getString(NODE_LIST_FILE, null)) - .map(File::new) - .map(f -> (TargetNodeDirectory) new FileBasedTargetNodeDirectory(f, context.getMonitor(), typeManager.getMapper())) - .orElseGet(() -> { - context.getMonitor().warning("TargetNode file is not configured ('%s'). Federated Catalog Crawler will be inactive.".formatted(NODE_LIST_FILE)); - return new NoopNodeDirectory(); - }); - - } - - private static class NoopNodeDirectory implements TargetNodeDirectory { - @Override - public List getAll() { - return Collections.emptyList(); - } - - @Override - public void insert(TargetNode targetNode) { - - } - - @Override - public TargetNode remove(String s) { - return null; - } - } -} diff --git a/edc-extensions/federated-catalog/src/main/java/org/eclipse/tractusx/edc/federatedcatalog/FileBasedTargetNodeDirectory.java b/edc-extensions/federated-catalog/src/main/java/org/eclipse/tractusx/edc/federatedcatalog/FileBasedTargetNodeDirectory.java deleted file mode 100644 index adc6bfbd46..0000000000 --- a/edc-extensions/federated-catalog/src/main/java/org/eclipse/tractusx/edc/federatedcatalog/FileBasedTargetNodeDirectory.java +++ /dev/null @@ -1,78 +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.federatedcatalog; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.eclipse.edc.crawler.spi.TargetNode; -import org.eclipse.edc.crawler.spi.TargetNodeDirectory; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.monitor.Monitor; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -/** - * File-based implementation of the {@link TargetNodeDirectory} that returns a static {@code List} that are - * serialized as JSON and stored in a file. - */ -class FileBasedTargetNodeDirectory implements TargetNodeDirectory { - - private static final TypeReference> LIST_TYPE = new TypeReference<>() { - }; - private final File nodeFile; - private final Monitor monitor; - private final ObjectMapper objectMapper; - private List nodes; - - FileBasedTargetNodeDirectory(File nodeFile, Monitor monitor, ObjectMapper objectMapper) { - - this.nodeFile = nodeFile; - this.monitor = monitor.withPrefix(getClass().getSimpleName()); - this.objectMapper = objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); - } - - @Override - public List getAll() { - - if (nodes == null) { - try { - nodes = objectMapper.readValue(nodeFile, LIST_TYPE); - } catch (IOException e) { - throw new EdcException(e); - } - } - return nodes; - - } - - @Override - public void insert(TargetNode targetNode) { - monitor.warning("Inserting nodes into the file-based TargetNodeDirectory is not supported."); - } - - @Override - public TargetNode remove(String s) { - monitor.warning("Deleting nodes into the file-based TargetNodeDirectory is not supported."); - return null; - } -} diff --git a/edc-extensions/federated-catalog/src/test/java/org/eclipse/tractusx/edc/federatedcatalog/FileBasedTargetNodeDirectoryTest.java b/edc-extensions/federated-catalog/src/test/java/org/eclipse/tractusx/edc/federatedcatalog/FileBasedTargetNodeDirectoryTest.java deleted file mode 100644 index ec8492f9e7..0000000000 --- a/edc-extensions/federated-catalog/src/test/java/org/eclipse/tractusx/edc/federatedcatalog/FileBasedTargetNodeDirectoryTest.java +++ /dev/null @@ -1,66 +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.federatedcatalog; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.eclipse.edc.crawler.spi.TargetNode; -import org.eclipse.edc.junit.testfixtures.TestUtils; -import org.eclipse.edc.spi.EdcException; -import org.eclipse.edc.spi.monitor.Monitor; -import org.junit.jupiter.api.Test; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -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 FileBasedTargetNodeDirectoryTest { - - @Test - void getAll_hasEntries() { - var nodeDir = new FileBasedTargetNodeDirectory(TestUtils.getFileFromResourceName("nodes.json"), mock(), new ObjectMapper()); - assertThat(nodeDir.getAll()).hasSize(2); - } - - @Test - void getAll_fileNotExist() { - var nodeDir = new FileBasedTargetNodeDirectory(new File("not-exist.json"), mock(), new ObjectMapper()); - assertThatThrownBy(nodeDir::getAll) - .isInstanceOf(EdcException.class) - .hasRootCauseInstanceOf(FileNotFoundException.class); - } - - @Test - void insert() { - var monitor = mock(Monitor.class); - when(monitor.withPrefix(anyString())).thenReturn(monitor); - var nodeDir = new FileBasedTargetNodeDirectory(new File("not-exist.json"), monitor, new ObjectMapper()); - - assertThatNoException().isThrownBy(() -> nodeDir.insert(new TargetNode("foo", "bar", "https://foobar.com", List.of()))); - verify(monitor).warning("Inserting nodes into the file-based TargetNodeDirectory is not supported."); - } -} \ No newline at end of file diff --git a/edc-extensions/federated-catalog/src/test/resources/nodes.json b/edc-extensions/federated-catalog/src/test/resources/nodes.json deleted file mode 100644 index 895b6d59aa..0000000000 --- a/edc-extensions/federated-catalog/src/test/resources/nodes.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "test-1", - "url": "http://nodes.com/test-1", - "id": "1", - "supportedProtocols": "test-protocol" - }, - { - "name": "test-2", - "url": "http://nodes.com/test-2", - "id": "2", - "supportedProtocols": "another-test-protocol" - } -] \ No newline at end of file diff --git a/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_5_0_SetParticipantContextId.sql b/edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_5_0__SetParticipantContextId.sql similarity index 100% rename from edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_5_0_SetParticipantContextId.sql rename to edc-extensions/migrations/connector-migration/src/main/resources/migrations/connector/V1_5_0__SetParticipantContextId.sql diff --git a/edc-extensions/migrations/connector-migration/src/test/java/org/eclipse/tractusx/edc/postgresql/migration/connector/ConnectorPostgresqlMigrationTest.java b/edc-extensions/migrations/connector-migration/src/test/java/org/eclipse/tractusx/edc/postgresql/migration/connector/ConnectorPostgresqlMigrationTest.java index 0f42c25ff7..6c2285ff46 100644 --- a/edc-extensions/migrations/connector-migration/src/test/java/org/eclipse/tractusx/edc/postgresql/migration/connector/ConnectorPostgresqlMigrationTest.java +++ b/edc-extensions/migrations/connector-migration/src/test/java/org/eclipse/tractusx/edc/postgresql/migration/connector/ConnectorPostgresqlMigrationTest.java @@ -107,7 +107,6 @@ void shouldUseMergedMigrationAsBaseline_whenSchemaAlreadyBuilt(ObjectFactory obj objectFactory.constructInstance(DataPlaneInstancePostgresqlMigrationExtension.class), objectFactory.constructInstance(EdrIndexPostgresqlMigrationExtension.class), objectFactory.constructInstance(FederatedCatalogCacheMigrationExtension.class), - objectFactory.constructInstance(FederatedCatalogCacheMigrationExtension.class), objectFactory.constructInstance(JtiValidationPostgresqlMigrationExtension.class), objectFactory.constructInstance(PolicyMonitorPostgresqlMigrationExtension.class), objectFactory.constructInstance(PolicyPostgresqlMigrationExtension.class), 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/control-plane-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/federatedcatalog/V0_0_2__Remove_FederatedCatalogCache_Database_Schema.sql new file mode 100644 index 0000000000..d84633b9f4 --- /dev/null +++ b/edc-extensions/migrations/control-plane-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/federatedcatalog/V0_0_2__Remove_FederatedCatalogCache_Database_Schema.sql @@ -0,0 +1,18 @@ +-- +-- 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_federated_catalog +-- + +DROP TABLE IF EXISTS edc_federated_catalog; \ No newline at end of file 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 8976f8a7b2..6eeb40d840 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 @@ -52,10 +52,6 @@ public Config getConfig(IatpParticipant participant, PostgresExtension postgresq put("web.http.management.path", controlPlaneManagement.get().getPath()); put("web.http.control.port", String.valueOf(getFreePort())); put("web.http.control.path", "/control"); - put("web.http.catalog.port", String.valueOf(federatedCatalog.get().getPort())); - put("web.http.catalog.path", federatedCatalog.get().getPath()); - put("web.http.catalog.auth.type", "tokenbased"); - put("web.http.catalog.auth.key", MANAGEMENT_API_KEY); put("edc.transfer.send.retry.limit", "1"); put("edc.transfer.send.retry.base-delay.ms", "100"); put("edc.dsp.callback.address", controlPlaneProtocol.get().toString()); 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 fc9689a263..8d5ca26dde 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 @@ -28,8 +28,8 @@ iatp: # Decentralized IDentifier id: "did:web:changeme" sts: - dim: - url: "https://somewhere.dim.org" + div: + url: "https://somewhere.div.org" oauth: token_url: "https://changeme.org" client: 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 582c801099..9f3a8acaf5 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 @@ -29,8 +29,8 @@ iatp: # Decentralized IDentifier id: "did:web:changeme" sts: - dim: - url: "https://somewhere.dim.org" + div: + url: "https://somewhere.div.org" oauth: token_url: "https://changeme.org" client: diff --git a/edc-tests/e2e-fixtures/build.gradle.kts b/edc-tests/e2e-fixtures/build.gradle.kts index 17b19327ce..7ba38a3c0c 100644 --- a/edc-tests/e2e-fixtures/build.gradle.kts +++ b/edc-tests/e2e-fixtures/build.gradle.kts @@ -31,6 +31,7 @@ dependencies { testFixturesApi(project(":edc-extensions:agreements-bpns:bpns-evaluation-spi")) testFixturesApi(project(":edc-extensions:bpn-validation:bpn-validation-spi")) testFixturesApi(project(":core:json-ld-core")) + testFixturesApi(project(":core:json-ld-cx")) testFixturesApi(libs.edc.ext.jsonld) testFixturesApi(libs.edc.core.token) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/azure/AzuriteExtension.java b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/azure/AzuriteExtension.java index b9440c29b6..0d08d689a6 100644 --- a/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/azure/AzuriteExtension.java +++ b/edc-tests/e2e-fixtures/src/testFixtures/java/org/eclipse/tractusx/edc/tests/azure/AzuriteExtension.java @@ -62,6 +62,11 @@ private static class AzuriteContainer extends GenericContainer super(IMAGE_NAME); addEnv("AZURITE_ACCOUNTS", stream(accounts).map(it -> "%s:%s".formatted(it.name(), it.key())).collect(joining(";"))); setPortBindings(List.of("%d:%d".formatted(azuriteHostPort, containerPort))); + // TODO remove when issue https://github.com/Azure/Azurite/issues/2623 is resolved + setCommand("azurite", + "--blobHost", "0.0.0.0", + "--blobPort", Integer.toString(containerPort), + "--skipApiVersionCheck"); } public AzureBlobClient getHelper(Account account) { 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 83deec135b..3cb224da49 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 @@ -22,13 +22,11 @@ package org.eclipse.tractusx.edc.tests.helpers; -import com.fasterxml.jackson.databind.ObjectMapper; 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.jsonld.util.JacksonJsonLd; import org.eclipse.edc.policy.model.AtomicConstraint; import org.eclipse.edc.policy.model.Operator; @@ -49,10 +47,11 @@ 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.jsonld.JsonLdExtension.CX_ODRL_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"; @@ -60,7 +59,10 @@ public class PolicyHelperFunctions { 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 ObjectMapper MAPPER = JacksonJsonLd.createObjectMapper(); + 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 JsonObject bpnGroupPolicy(Operator operator, String... allowedGroups) { return bpnGroupPolicy(operator.getOdrlRepresentation(), false, allowedGroups); @@ -83,7 +85,7 @@ public static JsonObject frameworkPolicy(String id, Map permissi public static JsonObject frameworkPolicy(Map permissions, String action) { return Json.createObjectBuilder() - .add(CONTEXT, CX_ODRL_CONTEXT) + .add(CONTEXT, ODRL_CONTEXT) .add(TYPE, "Set") .add("permission", Json.createArrayBuilder() .add(frameworkConstraint(new HashMap<>(permissions), action, Operator.EQ, false))) @@ -96,7 +98,7 @@ public static JsonObject frameworkPolicy(Map permissions, String public static JsonObject frameworkPolicy(Map permissions, String action, Operator operator) { return Json.createObjectBuilder() - .add(CONTEXT, CX_ODRL_CONTEXT) + .add(CONTEXT, ODRL_CONTEXT) .add(TYPE, "Set") .add("permission", Json.createArrayBuilder() .add(frameworkConstraint(new HashMap<>(permissions), action, operator, false))) @@ -106,7 +108,7 @@ public static JsonObject frameworkPolicy(Map permissions, String public static JsonObject emptyPolicy() { return Json.createObjectBuilder() - .add(CONTEXT, CX_ODRL_CONTEXT) + .add(CONTEXT, ODRL_CONTEXT) .add(TYPE, "Set") .build(); } @@ -138,7 +140,7 @@ public static JsonObject frameworkPolicy(String leftOperand, Operator operator, .build(); return Json.createObjectBuilder() - .add(CONTEXT, CX_ODRL_CONTEXT) + .add(CONTEXT, ODRL_CONTEXT) .add(TYPE, "Set") .add("permission", Json.createArrayBuilder().add(permission)) .build(); @@ -161,15 +163,15 @@ private static JsonObject usagePurposeConstraint() { .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() @@ -177,31 +179,14 @@ public static JsonObject legacyFrameworkPolicy() { .add("and", constraintsBuilder.build()) .build()) .build(); - + return Json.createObjectBuilder() - .add(CONTEXT, CX_ODRL_CONTEXT) + .add(CONTEXT, ODRL_CONTEXT) .add(TYPE, "Set") .add("permission", Json.createArrayBuilder().add(permission)) .build(); } - public static JsonObject inForceDateUsagePolicy(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(frameworkAgreementConstraint()) - .add(usagePurposeConstraint()) - .build()) - .build(); - - return policy(List.of(Json.createObjectBuilder() - .add("action", "use") - .add("constraint", constraint) - .build())); - } - public static JsonObject inForceDatePolicyLegacy(String operatorStart, Object startDate, String operatorEnd, Object endDate) { var constraint = Json.createObjectBuilder() .add("@type", "LogicalConstraint") @@ -230,7 +215,7 @@ public static JsonObjectBuilder policyDefinitionBuilder(JsonObject policy) { public static JsonObject bpnPolicy(String... bpns) { return Json.createObjectBuilder() - .add(CONTEXT, CX_ODRL_CONTEXT) + .add(CONTEXT, ODRL_CONTEXT) .add(TYPE, "Set") .add("permission", Json.createArrayBuilder() .add(permission(bpns))) @@ -256,7 +241,7 @@ public static JsonObject bpnPolicy(Operator operator, String... bpns) { .build()) .build(); return Json.createObjectBuilder() - .add(CONTEXT, CX_ODRL_CONTEXT) + .add(CONTEXT, ODRL_CONTEXT) .add(TYPE, "Set") .add("permission", Json.createArrayBuilder() .add(permission)) @@ -276,7 +261,7 @@ private static JsonObject bpnGroupPolicy(String operator, boolean rightOperandAs .build(); return Json.createObjectBuilder() - .add(CONTEXT, CX_ODRL_CONTEXT) + .add(CONTEXT, ODRL_CONTEXT) .add(TYPE, "Set") .add("permission", permission) .build(); @@ -338,4 +323,102 @@ private static JsonObject atomicConstraint(String leftOperand, String operator, } return builder.build(); } + + 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(frameworkAgreementConstraint()) + .add(usagePurposeConstraint()) + .build()) + .build(); + + return policy(List.of(Json.createObjectBuilder() + .add("action", "use") + .add("constraint", constraint) + .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(frameworkAgreementConstraint()) + .add(usagePurposeConstraint()) + .build()) + .build(); + + return policy(List.of(Json.createObjectBuilder() + .add("action", "use") + .add("constraint", constraint) + .build())); + } + + public static JsonObject dataProvisioningEndDurationDays(Integer duration) { + 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(); + + 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(); + } + + 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_DATE_LITERAL, "eq", endDate, false)) + .build()) + .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(); + } } 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/IatpParticipant.java index c8c235ce49..a9ce4ec56e 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/IatpParticipant.java @@ -59,8 +59,8 @@ public Config getConfig() { var settings = new HashMap(); settings.put("web.http.credentials.port", String.valueOf(csService.get().getPort())); settings.put("web.http.credentials.path", csService.get().getPath()); - if (dimUri != null) { - settings.put("tx.edc.iam.sts.dim.url", dimUri.get().toString()); + if (divUri != null) { + settings.put("tx.edc.iam.sts.div.url", divUri.get().toString()); } return super.getConfig().merge(ConfigFactory.fromMap(settings)); } @@ -69,7 +69,7 @@ public void configureParticipant(DataspaceIssuer issuer, RuntimeExtension runtim runtimeExtension.getService(Vault.class).storeSecret(getDid(), getPrivateKeyAlias(), getPrivateKeyAsString()); try { - // runtime has CredentialStore, DIM tests cases + // runtime has CredentialStore, DIV tests cases var credentialStore = runtimeExtension.getService(CredentialStore.class); issueCredentials(issuer).forEach(credentialStore::create); } catch (EdcException e) { 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/TractusxIatpParticipantBase.java index 9140b93aef..6d3a336c02 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/TractusxIatpParticipantBase.java @@ -35,7 +35,7 @@ public abstract class TractusxIatpParticipantBase extends TractusxParticipantBase { protected final LazySupplier csService = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/api/resolution")); - protected LazySupplier dimUri; + protected LazySupplier divUri; protected LazySupplier credentialServiceUri; protected LazySupplier stsUri; protected String stsClientId; @@ -79,8 +79,8 @@ public B trustedIssuer(String trustedIssuer) { return self(); } - public B dimUri(LazySupplier dimUri) { - participant.dimUri = dimUri; + public B divUri(LazySupplier divUri) { + participant.divUri = divUri; return self(); } 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 bbc065a02b..7067006b2c 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 @@ -39,7 +39,6 @@ import java.util.HashMap; import java.util.Map; -import static io.restassured.RestAssured.given; import static io.restassured.http.ContentType.JSON; import static jakarta.json.Json.createObjectBuilder; import static java.time.Duration.ofSeconds; @@ -71,7 +70,6 @@ public abstract class TractusxParticipantBase extends IdentityParticipant { private static final String API_KEY_HEADER_NAME = "x-api-key"; protected final LazySupplier dataPlaneProxy = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort())); protected final LazySupplier dataPlanePublic = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/public")); - protected final LazySupplier federatedCatalog = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort() + "/api/catalog")); protected ParticipantEdrApi edrs; protected ParticipantDataApi data; protected ParticipantConsumerDataPlaneApi dataPlane; @@ -115,10 +113,6 @@ public Config getConfig() { put("web.http.management.auth.key", MANAGEMENT_API_KEY); put("web.http.control.port", String.valueOf(getFreePort())); put("web.http.control.path", "/control"); - put("web.http.catalog.port", String.valueOf(federatedCatalog.get().getPort())); - put("web.http.catalog.path", federatedCatalog.get().getPath()); - put("web.http.catalog.auth.type", "tokenbased"); - put("web.http.catalog.auth.key", MANAGEMENT_API_KEY); put("edc.dsp.callback.address", controlPlaneProtocol.get().toString()); put("web.http.public.path", dataPlanePublic.get().getPath()); put("web.http.public.port", String.valueOf(dataPlanePublic.get().getPort())); @@ -136,8 +130,6 @@ public Config getConfig() { put("edc.iam.sts.oauth.client.secret.alias", "test-clientid-alias"); put("tx.edc.iam.iatp.bdrs.server.url", "http://sts.example.com"); put("edc.dataplane.api.public.baseurl", "%s/v2/data".formatted(dataPlanePublic.get())); - put("edc.catalog.cache.execution.delay.seconds", "2"); - put("edc.catalog.cache.execution.period.seconds", "2"); put("edc.policy.validation.enabled", "true"); put("edc.iam.did.web.use.https", "false"); put("edc.participant.context.id", "general-test-id"); @@ -268,24 +260,7 @@ public ValidatableResponse getCatalog(TractusxParticipantBase provider) { .then(); } - - public ValidatableResponse getFederatedCatalog() { - var requestBodyBuilder = createObjectBuilder() - .add(CONTEXT, createObjectBuilder().add(VOCAB, EDC_NAMESPACE)) - .add(TYPE, "QuerySpec"); - - - return given() - .baseUri(federatedCatalog.get().toString()) - .header("x-api-key", MANAGEMENT_API_KEY) - .contentType(JSON) - .when() - .body(requestBodyBuilder.build()) - .post("/v1alpha/catalog/query") - .then(); - - } - + public String getTransferProcessField(String transferProcessId, String fieldName) { return baseManagementRequest() .contentType(JSON) diff --git a/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile b/edc-tests/e2e-fixtures/src/testFixtures/resources/Dockerfile index ccba093825..17b167998b 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:17.4 +FROM postgres:18.3 USER "Dummy" diff --git a/edc-tests/e2e/catalog-tests/build.gradle.kts b/edc-tests/e2e/catalog-tests/build.gradle.kts index f52e7ab054..9414cc8a94 100644 --- a/edc-tests/e2e/catalog-tests/build.gradle.kts +++ b/edc-tests/e2e/catalog-tests/build.gradle.kts @@ -29,7 +29,6 @@ dependencies { testImplementation(libs.edc.junit) testImplementation(libs.restAssured) testImplementation(libs.awaitility) - testImplementation(libs.edc.fc.spi.crawler) testRuntimeOnly(libs.edc.transaction.local) testCompileOnly(project(":edc-tests:runtime:runtime-postgresql")) diff --git a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/FederatedCatalogTest.java b/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/FederatedCatalogTest.java deleted file mode 100644 index 10ba1282f9..0000000000 --- a/edc-tests/e2e/catalog-tests/src/test/java/org/eclipse/tractusx/edc/tests/catalog/FederatedCatalogTest.java +++ /dev/null @@ -1,122 +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 - ********************************************************************************/ - -package org.eclipse.tractusx.edc.tests.catalog; - -import org.eclipse.edc.crawler.spi.TargetNode; -import org.eclipse.edc.crawler.spi.TargetNodeDirectory; -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.DisplayName; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; - -import java.util.List; - -import static io.restassured.http.ContentType.JSON; -import static org.awaitility.Awaitility.await; -import static org.eclipse.edc.connector.controlplane.test.system.utils.PolicyFixtures.noConstraintPolicy; -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.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.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; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; - -@EndToEndTest -public class FederatedCatalogTest { - - private static final TransferParticipant CONSUMER = TransferParticipant.Builder.newInstance() - .name(CONSUMER_NAME) - .id(CONSUMER_DID) - .bpn(CONSUMER_BPN) - .build(); - - 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(CONSUMER.getName(), PROVIDER.getName()); - - @RegisterExtension - private static final RuntimeExtension CONSUMER_RUNTIME = pgRuntime(CONSUMER, POSTGRES) - .registerServiceMock(TargetNodeDirectory.class, new TestTargetNodeDirectory(List.of(PROVIDER))); - - @RegisterExtension - private static final RuntimeExtension PROVIDER_RUNTIME = pgRuntime(PROVIDER, POSTGRES); - - @Test - @DisplayName("Consumer gets cached catalog with provider entry") - void requestCatalog_fulfillsPolicy_shouldReturnOffer() { - PROVIDER.createAsset("test-asset"); - var ap = PROVIDER.createPolicyDefinition(noConstraintPolicy()); - var cp = PROVIDER.createPolicyDefinition(noConstraintPolicy()); - PROVIDER.createContractDefinition("test-asset", "test-def", ap, cp); - - await().pollInterval(ASYNC_POLL_INTERVAL) - .atMost(ASYNC_TIMEOUT) - .untilAsserted(() -> { - CONSUMER.getFederatedCatalog() - .statusCode(200) - .contentType(JSON) - .log().ifValidationFails() - .body("size()", is(1)) - .body("[0].'dataset'[0].'@id'", equalTo("test-asset")); - }); - } - - static class TestTargetNodeDirectory implements TargetNodeDirectory { - - private final List participants; - - TestTargetNodeDirectory(List participants) { - this.participants = participants; - } - - @Override - public List getAll() { - return participants.stream() - .map(p -> new TargetNode(p.getDid(), p.getBpn(), p.getProtocolUrl() + "/2025-1", List.of("dataspace-protocol-http:2025-1"))) - .toList(); - } - - @Override - public void insert(TargetNode node) { - - } - - @Override - public TargetNode remove(String s) { - return null; - } - } - -} 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 744afcc3fc..9129f36c8d 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 @@ -53,7 +53,7 @@ private static Config baseConfig(LazySupplier controlApi) { 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.sts.dim.url", "http://sts.example.com"); + put("tx.edc.iam.sts.div.url", "http://sts.example.com"); put("tx.edc.iam.iatp.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 a89073a745..42cb7b7e4c 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,7 @@ public class DcpPresentationFlowTest { @RegisterExtension static final RuntimePerClassExtension RUNTIME = new RuntimePerClassExtension( - new EmbeddedRuntime("Connector-under-test", ":edc-controlplane:edc-controlplane-base", ":edc-extensions:single-participant-vault") + new EmbeddedRuntime("Connector-under-test", ":edc-tests:runtime:runtime-dcp-tck") .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/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 78db7c6c5d..58eb8db163 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 @@ -65,7 +65,6 @@ public class EdcCompatibilityPostgresTest { private static final String API_KEY = "password"; 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 URI FEDERATED_CATALOG = URI.create("http://localhost:" + getFreePort() + "/api/catalog"); private static final String CONNECTOR_UNDER_TEST = "participantContextId"; private static final DataspaceProfileContextRegistry DATASPACE_PROFILE_CONTEXT_REGISTRY_SPY = spy(DataspaceProfileContextRegistryImpl.class); @@ -124,15 +123,9 @@ private static Config runtimeConfiguration() { put("edc.transfer.send.retry.base-delay.ms", "100"); put("tx.edc.dataplane.token.expiry", "3"); put("tx.edc.dataplane.token.expiry.tolerance", "0"); - put("web.http.catalog.port", String.valueOf(FEDERATED_CATALOG.getPort())); - put("web.http.catalog.path", FEDERATED_CATALOG.getPath()); - put("web.http.catalog.auth.type", "tokenbased"); - put("web.http.catalog.auth.key", API_KEY); 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("edc.catalog.cache.execution.delay.seconds", "2"); - put("edc.catalog.cache.execution.period.seconds", "2"); put("tractusx.edc.participant.bpn", CONNECTOR_UNDER_TEST); } }); @@ -152,8 +145,6 @@ void assertDspCompatibility() { "/etc/tck/tx-auth-v1.jsonld"); TCK_CONTAINER.withCopyFileToContainer(MountableFile.forClasspathResource("document/cx-policy-v1.jsonld"), "/etc/tck/cx-policy-v1.jsonld"); - TCK_CONTAINER.withCopyFileToContainer(MountableFile.forClasspathResource("document/cx-odrl.jsonld"), - "/etc/tck/cx-odrl.jsonld"); TCK_CONTAINER.withExtraHost("host.docker.internal", "host-gateway"); TCK_CONTAINER.withLogConsumer(outputFrame -> monitor.info(outputFrame.getUtf8String())); diff --git a/edc-tests/e2e/dsp-compatibility-tests/src/test/resources/docker.tck.properties b/edc-tests/e2e/dsp-compatibility-tests/src/test/resources/docker.tck.properties index e78d7a25e5..801d461a2a 100644 --- a/edc-tests/e2e/dsp-compatibility-tests/src/test/resources/docker.tck.properties +++ b/edc-tests/e2e/dsp-compatibility-tests/src/test/resources/docker.tck.properties @@ -31,8 +31,6 @@ dataspacetck.dsp.jsonld.context.tractusx_auth.path=/etc/tck/tx-auth-v1.jsonld dataspacetck.dsp.jsonld.context.tractusx_auth.uri=https://w3id.org/tractusx/auth/v1.0.0 dataspacetck.dsp.jsonld.context.tractusx_policy.path=/etc/tck/cx-policy-v1.jsonld dataspacetck.dsp.jsonld.context.tractusx_policy.uri=https://w3id.org/catenax/2025/9/policy/context.jsonld -dataspacetck.dsp.jsonld.context.tractusx_policy_odrl.path=/etc/tck/cx-odrl.jsonld -dataspacetck.dsp.jsonld.context.tractusx_policy_odrl.uri=https://w3id.org/catenax/2025/9/policy/odrl.jsonld dataspacetck.dsp.default.wait=7 # must be 0.0.0.0 for docker inet binding to work dataspacetck.callback.address=http://0.0.0.0:8083 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 901288138e..479ba2bd46 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 @@ -52,7 +52,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.sts.dim.url", "http://sts.example.com"); + put("tx.edc.iam.sts.div.url", "http://sts.example.com"); put("tx.edc.iam.iatp.bdrs.server.url", "http://sts.example.com"); } }; diff --git a/edc-tests/e2e/iatp-tests/build.gradle.kts b/edc-tests/e2e/iatp-tests/build.gradle.kts index 7c10216b12..50be7e9a7e 100644 --- a/edc-tests/e2e/iatp-tests/build.gradle.kts +++ b/edc-tests/e2e/iatp-tests/build.gradle.kts @@ -53,7 +53,7 @@ dependencies { testImplementation(libs.awaitility) testImplementation(libs.bouncyCastle.bcpkixJdk18on) - testCompileOnly(project(":edc-tests:runtime:iatp:runtime-memory-iatp-dim-ih")) + 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")) } diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java b/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java index 113212b3a4..0ee6a1e4cf 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java +++ b/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/CredentialSpoofTest.java @@ -74,7 +74,7 @@ public class CredentialSpoofTest { .name("STS") .build(); - private static final LazySupplier DIM_URI = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort())); + private static final LazySupplier DIV_URI = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort())); private static final DataspaceIssuer DATASPACE_ISSUER_PARTICIPANT = new DataspaceIssuer(DID_SERVER.didFor("issuer")); @RegisterExtension @@ -109,7 +109,7 @@ private static IatpParticipant participant(String name, String bpn) { .bpn(bpn) .stsClientId(bpn) .trustedIssuer(DATASPACE_ISSUER_PARTICIPANT.didUrl()) - .dimUri(DIM_URI) + .divUri(DIV_URI) .id(DID_SERVER.didFor(name)) .build(); } diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DimConsumerPullTest.java b/edc-tests/e2e/iatp-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/DimConsumerPullTest.java rename to edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java index e8772b8365..353060df2b 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DimConsumerPullTest.java +++ b/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/DivConsumerPullTest.java @@ -44,7 +44,7 @@ import org.eclipse.tractusx.edc.tests.runtimes.KeyPool; 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.DimDispatcher; +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,19 +68,19 @@ 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.dimRuntime; +import static org.eclipse.tractusx.edc.tests.transfer.iatp.runtime.Runtimes.divRuntime; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @EndToEndTest -public class DimConsumerPullTest extends AbstractIatpConsumerPullTest { +public class DivConsumerPullTest extends AbstractIatpConsumerPullTest { @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 LazySupplier DIM_URI = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort())); + private static final LazySupplier DIV_URI = new LazySupplier<>(() -> URI.create("http://localhost:" + getFreePort())); private static final IatpParticipant CONSUMER = IatpParticipant.Builder.newInstance() .name(CONSUMER_NAME) @@ -88,7 +88,7 @@ public class DimConsumerPullTest extends AbstractIatpConsumerPullTest { .stsUri(STS.stsUri()) .stsClientId(CONSUMER_BPN) .trustedIssuer(DATASPACE_ISSUER_PARTICIPANT.didUrl()) - .dimUri(DIM_URI) + .divUri(DIV_URI) .bpn(CONSUMER_BPN) .protocol(DSP_2025) .protocolVersionPath(DSP_2025_PATH) @@ -99,7 +99,7 @@ public class DimConsumerPullTest extends AbstractIatpConsumerPullTest { .stsUri(STS.stsUri()) .stsClientId(PROVIDER_BPN) .trustedIssuer(DATASPACE_ISSUER_PARTICIPANT.didUrl()) - .dimUri(DIM_URI) + .divUri(DIV_URI) .bpn(PROVIDER_BPN) .protocol(DSP_2025) .protocolVersionPath(DSP_2025_PATH) @@ -109,15 +109,15 @@ public class DimConsumerPullTest extends AbstractIatpConsumerPullTest { private static final BdrsServerExtension BDRS_SERVER_EXTENSION = new BdrsServerExtension(DATASPACE_ISSUER_PARTICIPANT.didUrl()); @RegisterExtension - private static final RuntimeExtension CONSUMER_RUNTIME = dimRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), + private static final RuntimeExtension CONSUMER_RUNTIME = divRuntime(CONSUMER.getName(), CONSUMER.getKeyPair(), () -> CONSUMER.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); @RegisterExtension - private static final RuntimeExtension PROVIDER_RUNTIME = dimRuntime(PROVIDER.getName(), PROVIDER.getKeyPair(), + private static final RuntimeExtension PROVIDER_RUNTIME = divRuntime(PROVIDER.getName(), PROVIDER.getKeyPair(), () -> PROVIDER.iatpConfig().merge(BDRS_SERVER_EXTENSION.getConfig())); private static final TypeManager MAPPER = new JacksonTypeManager(); private static WireMockServer oauthServer; - private static WireMockServer dimServer; + private static WireMockServer divServer; @BeforeAll static void prepare() { @@ -143,17 +143,17 @@ static void prepare() { oauthServer.stubFor(post(urlPathEqualTo(stsUri.getPath() + "/token")).willReturn(aResponse().withStatus(200) .withBody(MAPPER.writeValueAsString(Map.of("access_token", "token"))))); - dimServer = new WireMockServer(options().port(DIM_URI.get().getPort()).extensions(new DimDispatcher(generatorServices))); - dimServer.start(); - dimServer.stubFor(post(anyUrl()).willReturn(aResponse().withTransformers("dim-dispatcher"))); - + divServer = new WireMockServer(options().port(DIV_URI.get().getPort()).extensions(new DivDispatcher(generatorServices))); + divServer.start(); + divServer.stubFor(post(anyUrl()).willReturn(aResponse().withTransformers("div-dispatcher"))); + CONSUMER.setJsonLd(CONSUMER_RUNTIME.getService(JsonLd.class)); } @AfterAll static void unwind() { oauthServer.stop(); - dimServer.stop(); + divServer.stop(); } private static EmbeddedSecureTokenService tokenServiceFor(TokenGenerationService tokenGenerationService, IatpParticipant participant, diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java b/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java index 2bed4d644b..05e60e0368 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java +++ b/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/IdentityExtractionTest.java @@ -84,10 +84,10 @@ void verifyCorrectParticipantAgentId_forDsp2025(DataspaceProfileContextRegistry .claim("vc", List.of(createCredential().build())) .build(); - var bpnExtractionFunction = registry.getIdExtractionFunction(DSP_2025); - var id = bpnExtractionFunction.apply(claimtoken); + var didExtractionFunction = registry.getIdExtractionFunction(DSP_2025); + var id = didExtractionFunction.apply(claimtoken); - assertThat(id).isEqualTo("test-id"); + assertThat(id).isEqualTo("did:web:test.example:id"); } @Test @@ -109,9 +109,8 @@ void verifyAgentId_whenNoMembershipCredential_forDsp2025(DataspaceProfileContext .build(); var didExtractionFunction = registry.getIdExtractionFunction(DSP_2025); - - assertThatThrownBy(() -> didExtractionFunction.apply(claimtoken)).isInstanceOf(EdcException.class) - .hasMessage("Required credential type 'MembershipCredential' not present in ClaimToken, cannot extract property 'id'"); + + assertThat(didExtractionFunction.apply(claimtoken)).startsWith("did:web:"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -122,7 +121,7 @@ private VerifiableCredential.Builder createCredential() { .issuanceDate(Instant.now()) .issuer(new Issuer("test-issuer", Map.of())) .credentialSubject(CredentialSubject.Builder.newInstance() - .id("test-id") + .id("did:web:test.example:id") .claim("holderIdentifier", "the-holder") .build()); } diff --git a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DimDispatcher.java b/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DivDispatcher.java similarity index 94% rename from edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DimDispatcher.java rename to edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DivDispatcher.java index 4e16ace22b..e53881e667 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DimDispatcher.java +++ b/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/dispatchers/DivDispatcher.java @@ -40,26 +40,26 @@ import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.SUBJECT; /** - * Mock service for DIM interaction. Underlying it uses the {@link EmbeddedSecureTokenService} for generating SI tokens + * Mock service for DIV interaction. Underlying it uses the {@link EmbeddedSecureTokenService} for generating SI tokens */ -public class DimDispatcher implements ResponseTransformerV2 { +public class DivDispatcher implements ResponseTransformerV2 { private static final TypeManager MAPPER = new JacksonTypeManager(); private final String path; private final Map secureTokenServices; - public DimDispatcher(Map secureTokenServices) { + public DivDispatcher(Map secureTokenServices) { this("/", secureTokenServices); } - public DimDispatcher(String path, Map secureTokenServices) { + public DivDispatcher(String path, Map secureTokenServices) { this.path = path; this.secureTokenServices = secureTokenServices; } @Override public String getName() { - return "dim-dispatcher"; + return "div-dispatcher"; } @Override 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/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/Runtimes.java index ae70d10a55..c19ee622fe 100644 --- a/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/Runtimes.java +++ b/edc-tests/e2e/iatp-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/iatp/runtime/Runtimes.java @@ -35,8 +35,8 @@ public interface Runtimes { - static RuntimeExtension dimRuntime(String name, KeyPair keyPair, Supplier configurationProvider) { - return genericRuntime(name, ":edc-tests:runtime:iatp:runtime-memory-iatp-dim-ih", keyPair, configurationProvider) + static RuntimeExtension divRuntime(String name, KeyPair keyPair, Supplier configurationProvider) { + return genericRuntime(name, ":edc-tests:runtime:iatp:runtime-memory-iatp-div-ih", keyPair, configurationProvider) .registerSystemExtension(ServiceExtension.class, new VaultSeedExtension(Map.of("client_secret_alias", "client_secret"))); } 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 6e52c9aa27..da68180053 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 @@ -39,6 +39,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.List; import java.util.Map; import java.util.stream.Stream; @@ -46,17 +48,18 @@ 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.tractusx.edc.jsonld.JsonLdExtension.CX_ODRL_CONTEXT; -import static org.eclipse.tractusx.edc.jsonld.JsonLdExtension.CX_POLICY_2025_09_CONTEXT; +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; import static org.eclipse.tractusx.edc.tests.TestRuntimeConfiguration.CONSUMER_NAME; 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.ODRL_CONTEXT; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.dataUsageEndDate; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.dataUsageEndDurationDays; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.emptyPolicy; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.frameworkConstraint; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.inForceDateUsagePolicy; import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; @EndToEndTest @@ -187,9 +190,18 @@ private ValidContractPolicyProvider() { @Override public Stream provideArguments(ExtensionContext extensionContext) { return Stream.concat(super.provideArguments(extensionContext), Stream.of( - Arguments.of(emptyPolicy(), "Empty Policy"), - Arguments.of(policyWithEmptyRule("access", this.namespace), "Access policy with empty permission"), - Arguments.of(inForceDateUsagePolicy("gteq", "contractAgreement+0s", "lteq", "contractAgreement+10s"), "In force date policy") + Arguments.of( + emptyPolicy(), + "Empty Policy"), + Arguments.of( + policyWithEmptyRule("access", this.namespace), + "Access policy with empty permission"), + Arguments.of( + dataUsageEndDurationDays(1), + "Enforce data usage end date 1 day in the future"), + Arguments.of( + dataUsageEndDate(Instant.now().plus(1, ChronoUnit.SECONDS).truncatedTo(ChronoUnit.SECONDS).toString()), + "Enforce data usage end date 1 second in the future") )); } } @@ -245,7 +257,7 @@ private static JsonObject policyFromRules(String ruleType, String policyDefiniti rulesArrayBuilder.add(rule); } var contextArrayBuilder = Json.createArrayBuilder(); - contextArrayBuilder.add(CX_ODRL_CONTEXT); + contextArrayBuilder.add(ODRL_CONTEXT); if (!policyDefinition.isBlank()) { contextArrayBuilder.add(policyDefinition); } @@ -264,7 +276,7 @@ private static JsonObject policyWithEmptyRule(String action, String policyContex var rulesArrayBuilder = Json.createArrayBuilder(); rulesArrayBuilder.add(rule); var contextArrayBuilder = Json.createArrayBuilder(); - contextArrayBuilder.add(CX_ODRL_CONTEXT); + contextArrayBuilder.add(ODRL_CONTEXT); contextArrayBuilder.add(policyContext); return Json.createObjectBuilder() 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 36e38f6a0c..0dc7836061 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 @@ -30,6 +30,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Map; import java.util.UUID; @@ -48,8 +50,9 @@ 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.dataProvisioningEndDate; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.dataUsageEndDate; import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.emptyPolicy; -import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.inForceDateUsagePolicy; import static org.eclipse.tractusx.edc.tests.participant.TractusxParticipantBase.ASYNC_TIMEOUT; import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; @@ -89,7 +92,7 @@ void setup() { } @Test - void shouldTerminateTransfer_whenPolicyExpires() { + void shouldTerminateTransfer_whenDataUsageEndDatePolicyExpires() { var assetId = UUID.randomUUID().toString(); Map dataAddress = Map.of( @@ -103,10 +106,43 @@ void shouldTerminateTransfer_whenPolicyExpires() { var accessPolicy = emptyPolicy(); var accessPolicyId = PROVIDER.createPolicyDefinition(accessPolicy); - var usagePolicy = inForceDateUsagePolicy("gteq", "contractAgreement+0s", "lteq", "contractAgreement+10s"); + var usagePolicy = dataUsageEndDate(Instant.now().plusSeconds(30).truncatedTo(ChronoUnit.SECONDS).toString()); var usagePolicyId = PROVIDER.createPolicyDefinition(usagePolicy); PROVIDER.createContractDefinition(assetId, UUID.randomUUID().toString(), accessPolicyId, usagePolicyId); + var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) + .withTransferType("HttpData-PULL") + .withDestination(httpDataDestination()) + .execute(); + await().atMost(ASYNC_TIMEOUT).untilAsserted(() -> { + var state = CONSUMER.getTransferProcessState(transferProcessId); + assertThat(state).isEqualTo(STARTED.name()); + }); + + await().atMost(ASYNC_TIMEOUT).untilAsserted(() -> { + var state = CONSUMER.getTransferProcessState(transferProcessId); + assertThat(state).isEqualTo(TERMINATED.name()); + }); + } + + @Test + void shouldTerminateTransfer_whenDataProvisioningEndDatePolicyExpires() { + var assetId = UUID.randomUUID().toString(); + + Map dataAddress = Map.of( + "name", "transfer-test", + "baseUrl", "http://localhost:8080", + "type", "HttpData", + "contentType", "application/json", + "proxyQueryParams", "true" + ); + PROVIDER.createAsset(assetId, Map.of(), dataAddress); + + var accessPolicy = emptyPolicy(); + var accessPolicyId = PROVIDER.createPolicyDefinition(accessPolicy); + var usagePolicy = dataProvisioningEndDate(Instant.now().plusSeconds(30).truncatedTo(ChronoUnit.SECONDS).toString()); + var usagePolicyId = PROVIDER.createPolicyDefinition(usagePolicy); + PROVIDER.createContractDefinition(assetId, UUID.randomUUID().toString(), accessPolicyId, usagePolicyId); 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/TransferPullEndToEndTest.java b/edc-tests/e2e/transfer-tests/src/test/java/org/eclipse/tractusx/edc/tests/transfer/TransferPullEndToEndTest.java index f658ec1e5c..5083d2b746 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 @@ -34,6 +34,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Map; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; @@ -54,7 +56,7 @@ 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.inForceDateUsagePolicy; +import static org.eclipse.tractusx.edc.tests.helpers.PolicyHelperFunctions.dataProvisioningEndDate; import static org.eclipse.tractusx.edc.tests.runtimes.Runtimes.pgRuntime; @EndToEndTest @@ -154,7 +156,7 @@ void transferData_withTerminate() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(inForcePolicy()); + var contractPolicyId = PROVIDER.createPolicyDefinition(dataProvisioningEndDatePolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("HttpData-PULL") @@ -181,11 +183,10 @@ void transferData_withTerminate() { server.verify(1, getRequestedFor(urlPathEqualTo(MOCK_BACKEND_PATH))); } - protected JsonObject inForcePolicy() { - return inForceDateUsagePolicy("gteq", "contractAgreement+0s", "lteq", "contractAgreement+10s"); + protected JsonObject dataProvisioningEndDatePolicy() { + return dataProvisioningEndDate(Instant.now().plusSeconds(10).truncatedTo(ChronoUnit.SECONDS).toString()); } - @Test void transferData_successful_notReturnOriginalSourceResponseCode_withTerminate() { var assetId = "api-asset-1"; @@ -199,7 +200,7 @@ void transferData_successful_notReturnOriginalSourceResponseCode_withTerminate() PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(inForcePolicy()); + var contractPolicyId = PROVIDER.createPolicyDefinition(dataProvisioningEndDatePolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("HttpData-PULL") @@ -236,7 +237,7 @@ void transferData_unsuccessful_notReturnOriginalSourceResponseCode_withTerminate PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(inForcePolicy()); + var contractPolicyId = PROVIDER.createPolicyDefinition(dataProvisioningEndDatePolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("HttpData-PULL") @@ -269,7 +270,7 @@ void transferData_success_withProxyOriginalResponse() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(inForcePolicy()); + var contractPolicyId = PROVIDER.createPolicyDefinition(dataProvisioningEndDatePolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("HttpData-PULL") @@ -308,7 +309,7 @@ void transferData_success_withProxyOriginalResponse_withoutSourceResponseBody() PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(inForcePolicy()); + var contractPolicyId = PROVIDER.createPolicyDefinition(dataProvisioningEndDatePolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("HttpData-PULL") @@ -347,7 +348,7 @@ void transferData_failing_withProxyOriginalResponse() { PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(inForcePolicy()); + var contractPolicyId = PROVIDER.createPolicyDefinition(dataProvisioningEndDatePolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("HttpData-PULL") @@ -382,7 +383,7 @@ void transferData_failing_withProxyOriginalResponse_withoutSourceResponseBody() PROVIDER.createAsset(assetId, Map.of(), dataAddress); var accessPolicyId = PROVIDER.createPolicyDefinition(createAccessPolicy(CONSUMER.getBpn())); - var contractPolicyId = PROVIDER.createPolicyDefinition(inForcePolicy()); + var contractPolicyId = PROVIDER.createPolicyDefinition(dataProvisioningEndDatePolicy()); PROVIDER.createContractDefinition(assetId, "def-1", accessPolicyId, contractPolicyId); var transferProcessId = CONSUMER.requestAssetFrom(assetId, PROVIDER) .withTransferType("HttpData-PULL") diff --git a/edc-tests/runtime/iatp/runtime-memory-iatp-dim-ih/README.md b/edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/README.md similarity index 100% rename from edc-tests/runtime/iatp/runtime-memory-iatp-dim-ih/README.md rename to edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/README.md diff --git a/edc-tests/runtime/iatp/runtime-memory-iatp-dim-ih/build.gradle.kts b/edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/build.gradle.kts similarity index 93% rename from edc-tests/runtime/iatp/runtime-memory-iatp-dim-ih/build.gradle.kts rename to edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/build.gradle.kts index fce26d0467..31c062c85f 100644 --- a/edc-tests/runtime/iatp/runtime-memory-iatp-dim-ih/build.gradle.kts +++ b/edc-tests/runtime/iatp/runtime-memory-iatp-div-ih/build.gradle.kts @@ -28,10 +28,12 @@ dependencies { implementation(project(":edc-controlplane:edc-controlplane-base")) implementation(project(":edc-extensions:single-participant-vault")) implementation(project(":core:json-ld-core")) + implementation(project(":core:json-ld-cx")) implementation(project(":edc-extensions:cx-policy")) implementation(project(":edc-extensions:cx-policy-legacy")) + implementation(project(":edc-extensions:dcp:cx-dcp")) implementation(project(":edc-extensions:dcp:tx-dcp")) - implementation(project(":edc-extensions:dcp:tx-dcp-sts-dim")) + implementation(project(":edc-extensions:dcp:tx-dcp-sts-div")) implementation(project(":edc-tests:runtime:iatp:iatp-extensions")) 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 d04bacc922..eaf9f7b5e6 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 @@ -30,6 +30,8 @@ dependencies { implementation(project(":edc-extensions:cx-policy")) implementation(project(":edc-extensions:cx-policy-legacy")) implementation(project(":core:json-ld-core")) + implementation(project(":core:json-ld-cx")) + implementation(project(":edc-extensions:dcp:cx-dcp")) implementation(project(":edc-extensions:dcp:tx-dcp")) implementation(project(":edc-tests:runtime:iatp:iatp-extensions")) diff --git a/edc-tests/runtime/iatp/runtime-memory-sts/build.gradle.kts b/edc-tests/runtime/iatp/runtime-memory-sts/build.gradle.kts index a3aa5cd18b..f4d162928b 100644 --- a/edc-tests/runtime/iatp/runtime-memory-sts/build.gradle.kts +++ b/edc-tests/runtime/iatp/runtime-memory-sts/build.gradle.kts @@ -29,6 +29,7 @@ dependencies { implementation(libs.edc.bom.identityhub) 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(libs.edc.iam.mock) diff --git a/edc-tests/runtime/runtime-compatibility/snapshot/connector-snapshot/README.md b/edc-tests/runtime/runtime-compatibility/snapshot/connector-snapshot/README.md index 69ba813a36..c1feb60520 100644 --- a/edc-tests/runtime/runtime-compatibility/snapshot/connector-snapshot/README.md +++ b/edc-tests/runtime/runtime-compatibility/snapshot/connector-snapshot/README.md @@ -1,4 +1,4 @@ # Runtime for compatibility tests with PostgreSQL + tx-dcp extensions -This module provides a very small,runtime using PostgreSQL and tx-dcp/tx-dcp-sts-dim extensions as persistence backend to execute tests against. Not intended for anything other than testing! +This module provides a very small,runtime using PostgreSQL and tx-dcp/tx-dcp-sts-div extensions as persistence backend to execute tests against. Not intended for anything other than testing! diff --git a/edc-extensions/federated-catalog/build.gradle.kts b/edc-tests/runtime/runtime-dcp-tck/build.gradle.kts similarity index 58% rename from edc-extensions/federated-catalog/build.gradle.kts rename to edc-tests/runtime/runtime-dcp-tck/build.gradle.kts index b4d7e0fe59..d9709c62dd 100644 --- a/edc-extensions/federated-catalog/build.gradle.kts +++ b/edc-tests/runtime/runtime-dcp-tck/build.gradle.kts @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft +/******************************************************************************** + * Copyright (c) 2026 SAP SE * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -15,16 +15,25 @@ * under the License. * * SPDX-License-Identifier: Apache-2.0 - */ + ********************************************************************************/ plugins { - `maven-publish` `java-library` + id("application") } + dependencies { - implementation(libs.edc.spi.core) - implementation(libs.edc.fc.spi.crawler) + implementation(project(":edc-controlplane:edc-controlplane-base")) { + exclude(module = "cx-dcp") + } + implementation(project(":edc-extensions:single-participant-vault")) +} + +application { + mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") +} - testImplementation(libs.edc.junit) +edcBuild { + publish.set(false) } diff --git a/edc-tests/runtime/runtime-discovery/runtime-discovery-base/build.gradle.kts b/edc-tests/runtime/runtime-discovery/runtime-discovery-base/build.gradle.kts index 547ba3234a..1b6e438e9a 100644 --- a/edc-tests/runtime/runtime-discovery/runtime-discovery-base/build.gradle.kts +++ b/edc-tests/runtime/runtime-discovery/runtime-discovery-base/build.gradle.kts @@ -25,8 +25,8 @@ plugins { dependencies { implementation(project(":edc-controlplane:edc-controlplane-base")) { - exclude(module = "tx-dcp") - exclude(module = "tx-dcp-sts-dim") + exclude(module = "cx-dcp") + exclude(module = "tx-dcp-sts-div") } implementation(project(":edc-dataplane:edc-dataplane-base")) { 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 f3d8c81a19..456104b07c 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 @@ -25,8 +25,8 @@ plugins { dependencies { implementation(project(":edc-controlplane:edc-controlplane-base")) { - exclude(module = "tx-dcp") - exclude(module = "tx-dcp-sts-dim") + exclude(module = "cx-dcp") + exclude(module = "tx-dcp-sts-div") exclude(module = "dataspace-protocol") exclude(module = "dsp-08") exclude(module = "dsp-2024") 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 ddb0d5e975..87fb81155b 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 @@ -25,8 +25,8 @@ plugins { dependencies { implementation(project(":edc-controlplane:edc-controlplane-base")) { - exclude(module = "tx-dcp") - exclude(module = "tx-dcp-sts-dim") + exclude(module = "cx-dcp") + exclude(module = "tx-dcp-sts-div") exclude(module = "dataspace-protocol") exclude(module= "dsp-2024") exclude(module= "dsp-2025") diff --git a/edc-tests/runtime/runtime-dsp/build.gradle.kts b/edc-tests/runtime/runtime-dsp/build.gradle.kts index f8304cabd0..f5c326313d 100644 --- a/edc-tests/runtime/runtime-dsp/build.gradle.kts +++ b/edc-tests/runtime/runtime-dsp/build.gradle.kts @@ -26,7 +26,6 @@ plugins { dependencies { implementation(project(":edc-tests:runtime:runtime-postgresql")) runtimeOnly(libs.tck.extension) - runtimeOnly(libs.tck.lib) } application { diff --git a/edc-tests/runtime/runtime-postgresql/build.gradle.kts b/edc-tests/runtime/runtime-postgresql/build.gradle.kts index 0652ce4ac8..556bff33fb 100644 --- a/edc-tests/runtime/runtime-postgresql/build.gradle.kts +++ b/edc-tests/runtime/runtime-postgresql/build.gradle.kts @@ -26,8 +26,8 @@ plugins { dependencies { implementation(project(":edc-controlplane:edc-controlplane-postgresql-hashicorp-vault")) { exclude("org.eclipse.edc", "vault-hashicorp") - exclude(module = "tx-dcp") - exclude(module = "tx-dcp-sts-dim") + exclude(module = "cx-dcp") + exclude(module = "tx-dcp-sts-div") } implementation(project(":edc-dataplane:edc-dataplane-hashicorp-vault")) { diff --git a/gradle.properties b/gradle.properties index 76f1831cb7..89f9507794 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,6 @@ group=org.eclipse.tractusx.edc -version=0.12.0-SNAPSHOT +version=0.13.0-SNAPSHOT # configure the build: 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 - -org.gradle.caching=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2e94d49f51..33ed321338 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,27 +3,28 @@ format.version = "1.1" [versions] edc = "0.15.1" +edc-next = "0.16.0" edc-build = "1.1.6" -allure = "2.32.0" +allure = "2.33.0" awaitility = "4.3.0" -aws = "2.41.24" -azure-storage-blob = "12.32.0" +aws = "2.42.12" +azure-storage-blob = "12.33.2" bouncyCastle-jdk18on = "1.83" dcp-tck = "1.0.0-RC6" dsp-tck = "1.0.0-RC6" -flyway = "12.0.0" -jackson = "2.21.0" +flyway = "12.1.1" +jackson = "2.21.1" jakarta-json = "2.1.3" -junit = "6.0.2" -nimbus = "10.7" +junit = "6.0.3" +nimbus = "10.8" okhttp = "5.3.2" -opentelemetry = "2.24.0" -opentelemetry-instrumentation = "2.24.0" -opentelemetry-log4j-appender = "2.25.0-alpha-SNAPSHOT" -postgres = "42.7.9" +opentelemetry = "2.26.0" +opentelemetry-instrumentation = "2.25.0" +opentelemetry-log4j-appender = "2.25.0-alpha" +postgres = "42.7.10" restAssured = "6.0.0" rsApi = "4.0.0" -testcontainers = "2.0.3" +testcontainers = "2.0.4" testcontainers-keycloak = "4.1.1" titanium = "1.7.0" log4j2 = "2.25.3" @@ -38,10 +39,6 @@ edc-bom-dataplane-base = { module = "org.eclipse.edc:dataplane-base-bom", versio edc-bom-dataplane-feature-sql = { module = "org.eclipse.edc:dataplane-feature-sql-bom", version.ref = "edc" } edc-bom-identityhub = { module = "org.eclipse.edc:identityhub-bom", version.ref = "edc" } -edc-bom-federatedcatalog-base = { module = "org.eclipse.edc:federatedcatalog-base-bom", version.ref = "edc" } -edc-bom-federatedcatalog-dcp = { module = "org.eclipse.edc:federatedcatalog-dcp-bom", version.ref = "edc" } -edc-bom-federatedcatalog-feature-sql = { module = "org.eclipse.edc:federatedcatalog-feature-sql-bom", version.ref = "edc" } - edc-spi-auth = { module = "org.eclipse.edc:auth-spi", version.ref = "edc" } edc-spi-boot = { module = "org.eclipse.edc:boot-spi", version.ref = "edc" } edc-spi-catalog = { module = "org.eclipse.edc:catalog-spi", version.ref = "edc" } @@ -86,7 +83,6 @@ edc-core-token = { module = "org.eclipse.edc:token-core", version.ref = "edc" } edc-controlplane-callback-staticendpoint = { module = "org.eclipse.edc:callback-static-endpoint", version.ref = "edc" } edc-junit = { module = "org.eclipse.edc:junit", version.ref = "edc" } edc-api-core = { module = "org.eclipse.edc:api-core", version.ref = "edc" } -edc-api-management-dataplaneselector = { module = "org.eclipse.edc:data-plane-selector-api", version.ref = "edc" } edc-api-management-config = { module = "org.eclipse.edc:management-api-configuration", version.ref = "edc" } edc-api-management = { module = "org.eclipse.edc:management-api", version.ref = "edc" } edc-api-management-test-fixtures = { module = "org.eclipse.edc:management-api-test-fixtures", version.ref = "edc" } @@ -109,6 +105,7 @@ edc-lib-boot = { module = "org.eclipse.edc:boot-lib", version.ref = "edc" } edc-lib-cryptocommon = { module = "org.eclipse.edc:crypto-common-lib", version.ref = "edc" } edc-lib-http = { module = "org.eclipse.edc:http-lib", version.ref = "edc" } edc-lib-jersey-providers = { module = "org.eclipse.edc:jersey-providers-lib", version.ref = "edc" } +edc-lib-management-api = { module = "org.eclipse.edc:management-api-lib", version.ref = "edc" } edc-lib-jws2020 = { module = "org.eclipse.edc:jws2020-lib", version.ref = "edc" } edc-lib-query = { module = "org.eclipse.edc:query-lib", version.ref = "edc" } edc-lib-store = { module = "org.eclipse.edc:store-lib", version.ref = "edc" } @@ -169,17 +166,13 @@ 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 = "0.16.0-20260206-SNAPSHOT" } -tck-lib = { module = "org.eclipse.edc:tck-lib", version = "0.16.0-20260206-SNAPSHOT" } +tck-extension = { module = "org.eclipse.edc:tck-extension", version.ref = "edc-next" } # 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" } -# Federated Catalog modules -edc-fc-spi-crawler = { module = "org.eclipse.edc:crawler-spi", version.ref = "edc" } - ## IH for testing edc-ih-api-presentation = { module = "org.eclipse.edc:presentation-api", version.ref = "edc" } @@ -248,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.1" } -swagger = { id = "io.swagger.core.v3.swagger-gradle-plugin", version = "2.2.42" } +shadow = { id = "com.gradleup.shadow", version = "9.3.2" } +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" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 61285a659d..d997cfc60f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 19a6bdeb84..dbc3ce4a04 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.3.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index adff685a03..0262dcbd52 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/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/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/. diff --git a/resources/Dockerfile b/resources/Dockerfile index 889a397496..077b219a41 100644 --- a/resources/Dockerfile +++ b/resources/Dockerfile @@ -19,7 +19,9 @@ # SPDX-License-Identifier: Apache-2.0 ################################################################################# -FROM eclipse-temurin:25.0.2_10-jre-alpine +FROM eclipse-temurin:25-jre-alpine +RUN apk update && apk upgrade --no-cache + ARG JAR ARG OTEL_JAR ARG ADDITIONAL_FILES diff --git a/settings.gradle.kts b/settings.gradle.kts index 2c0ef76113..80387478e4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -60,6 +60,7 @@ include(":spi:did-document-service-spi") // core modules include(":core:edr-core") include(":core:json-ld-core") +include(":core:json-ld-cx") include(":core:core-utils") // extensions - control plane @@ -75,15 +76,15 @@ 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:federated-catalog") include(":edc-extensions:event-subscriber") include(":edc-extensions:edr:edr-api-v2") include(":edc-extensions:edr:edr-callback") include(":edc-extensions:edr:edr-index-lock-sql") include(":edc-extensions:cx-policy") include(":edc-extensions:cx-policy-legacy") +include(":edc-extensions:dcp:cx-dcp") include(":edc-extensions:dcp:tx-dcp") -include(":edc-extensions:dcp:tx-dcp-sts-dim") +include(":edc-extensions:dcp:tx-dcp-sts-div") include(":edc-extensions:dcp:verifiable-presentation-cache") include(":edc-extensions:data-flow-properties-provider") include(":edc-extensions:validators:empty-asset-selector") @@ -94,7 +95,7 @@ include(":edc-extensions:dataspace-protocol") include(":edc-extensions:dataspace-protocol:cx-dataspace-protocol") include(":edc-extensions:dataspace-protocol:dataspace-protocol-core") include(":edc-extensions:did-document:did-document-service-self-registration") -include(":edc-extensions:did-document:did-document-service-dim") +include(":edc-extensions:did-document:did-document-service-div") include(":edc-extensions:agreements") include(":edc-extensions:agreements:retirement-evaluation-core") @@ -141,11 +142,12 @@ 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-dim-ih") +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:mock-connector") include(":edc-tests:runtime:runtime-postgresql") +include(":edc-tests:runtime:runtime-dcp-tck") include("edc-tests:runtime:runtime-discovery:runtime-discovery-base") include("edc-tests:runtime:runtime-discovery:runtime-discovery-no-protocols") include("edc-tests:runtime:runtime-discovery:runtime-discovery-with-dsp-v08") @@ -170,33 +172,3 @@ include(":edc-dataplane:edc-dataplane-construct-x:con-x-dataplane-postgresql-has include(":samples:testing-with-mocked-connector") -plugins { - id("com.gradle.develocity") version "4.3.2" - id("com.gradle.common-custom-user-data-gradle-plugin") version "2.4.0" -} - -// Develocity -val isCI = System.getenv("CI") != null // adjust to your CI provider - -develocity { - server = "https://develocity-staging.eclipse.org" - projectId = "automotive.tractusx" - buildScan { - uploadInBackground = !isCI - publishing.onlyIf { it.isAuthenticated } - obfuscation { - ipAddresses { addresses -> addresses.map { _ -> "0.0.0.0" } } - } - } -} - -buildCache { - local { - isEnabled = true - } - - remote(develocity.buildCache) { - isEnabled = true - isPush = isCI - } -}