diff --git a/CHANGELOG.md b/CHANGELOG.md index c7d2e8b31..4025bb1b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,19 +7,147 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -## [0.1.6] - 2023-02-20 +## [0.3.0] - 2023-02-20 + +**Important Note**: This version introduces multiple breaking changes. Before updating **always** consolidate the +corresponding [documentation](/docs/migration/Version_0.1.x_0.3.x.md). + +### Added +- Add contract id to data source http call (#732) +- Support also support releases in ci pipeline +- Introduce typed object for oauth2 provisioning +- Add documentation +- Add test case +- Add client to omejdn +- add hydra deployment +- Configure dynamically HTTP Receiver callback endpoints. (#685) +- cp-adapter : code review, rollbacke name change (#664) +- Feature/cp adapter task 355 356 357 (#621) +- Add Validity Mapping in ContractDefinitionStepDefs class +- Add feature and create SendAnOfferwithoutConstraints method in class negotiationSteps +- Add validity attribute in class ContractDefinition +- Add Validity Mapping in ContractDefinitionStepDefs class +- Add feature and create SendAnOfferwithoutConstraints method in class negotiationSteps +- Add validity attribute in class ContractDefinition +- Local TXDC Setup Documentation (#618) +- Feature: Sftp Provisioner and Client (#554) + +### Changed +- Support horizontal edc scaling in cp adapter extension (#678) +- Use upstream jackson version (#741) +- Replace provision-oauth2 with data-plane-http-oauth2 +- docs: Update sample documentation (#671) +- chore: Disable build ci pipeline if just docu was updated (#705) +- Increase trivy timeout +- Remove not useful anymore custom-jsonld extension (#683) +- update setup docu (#654) +- remove trailing slash (#652) +- update alpine from 3.17.0 to 3.17.1 for controlplane-memory-hashicorp-vault (#665) +- Feature/set charts deprecated (#628) +- update setup docu (#627) +- Feature/update txdc deployment downward capabilities (#625) +- remove git submodule (#619) +- Feature/update postman (#624) +- update control plane docu (#623) +- update postgresql version in Chart.yaml supporting-infrastructure (#622) +- update link to edc logo in README.md (#612) +- update description of supporting infrastructure deployment (#616) + +### Fixed +- bugfix: Fix slow AES encryption (#746) +- Fix typo in tractusx-connector values.yaml comment +- Fix not working docu link in README.md +- Fix typo in control-plane adapter README + +### Dependency updates +- Bump EDC to 20220220 (#767) +- Bump alpine (#749) +- Bump alpine (#750) +- Bump alpine (#752) +- Bump alpine in /edc-controlplane/edc-controlplane-memory/src/main/docker (#753) +- Bump maven-deploy-plugin from 3.0.0 to 3.1.0 (#735) +- Bump actions/setup-java from 3.9.0 to 3.10.0 (#730) +- Bump s3 from 2.19.33 to 2.20.0 +- Bump s3 from 2.19.27 to 2.19.33 +- Bump jaxb-runtime from 4.0.1 to 4.0.2 +- Bump spotless-maven-plugin from 2.31.0 to 2.32.0 +- Bump postgresql from 42.5.1 to 42.5.3 +- Bump nimbus-jose-jwt from 9.30 to 9.30.1 +- Bump lombok from 1.18.24 to 1.18.26 +- Bump flyway-core from 9.12.0 to 9.14.1 +- Bump jackson-bom from 2.14.0-rc2 to 2.14.2 +- Bump cucumber.version from 7.11.0 to 7.11.1 +- Bump azure-sdk-bom from 1.2.8 to 1.2.9 +- Bump mockito-bom from 5.0.0 to 5.1.1 +- Bump edc version to 0.0.1-20230131-SNAPSHOT +- Bump s3 from 2.19.18 to 2.19.27 +- Bump docker/build-push-action from 3 to 4 +- Bump nimbus-jose-jwt from 9.29 to 9.30 +- Bump spotless-maven-plugin from 2.30.0 to 2.31.0 +- Bump nimbus-jose-jwt from 9.28 to 9.29 +- Bump mockito-bom from 4.11.0 to 5.0.0 +- Bump edc version to 0.0.1-20230125-SNAPSHOT +- Bump flyway-core from 9.11.0 to 9.12.0 +- Bump s3 from 2.19.15 to 2.19.18 (#684) +- Bump mikefarah/yq from 4.30.6 to 4.30.8 (#682) +- Bump spotless-maven-plugin from 2.29.0 to 2.30.0 +- Bump edc version to 0.0.1-20230115-SNAPSHOT +- Bump cucumber.version from 7.10.1 to 7.11.0 (#672) +- Bump maven-dependency-plugin from 3.4.0 to 3.5.0 (#669) +- Bump s3 from 2.19.11 to 2.19.15 (#668) +- Bump maven-surefire-plugin from 3.0.0-M7 to 3.0.0-M8 (#670) +- Bump edc version to 0.0.1-20230109-SNAPSHOT (#666) +- Bump alpine in /edc-controlplane/edc-controlplane-memory/src/main/docker (#659) +- Bump alpine in /edc-dataplane/edc-dataplane-azure-vault/src/main/docker (#660) +- Bump alpine (#658) +- Bump alpine (#661) +- Bump alpine (#662) +- Bump azure/setup-kubectl from 3.1 to 3.2 (#655) +- Bump junit-bom from 5.9.1 to 5.9.2 (#657) +- Bump s3 from 2.19.2 to 2.19.11 (#648) +- Bump actions/checkout from 3.2.0 to 3.3.0 (#647) +- Bump flyway-core from 9.10.2 to 9.11.0 (#646) +- Bump spotless-maven-plugin from 2.28.0 to 2.29.0 (#641) +- Bump mockito-bom from 4.10.0 to 4.11.0 (#637) +- Bump flyway-core from 9.10.1 to 9.10.2 (#632) +- Bump s3 from 2.19.1 to 2.19.2 (#631) +- Bump s3 from 2.18.41 to 2.19.1 (#626) +- Bump mikefarah/yq from 4.30.5 to 4.30.6 (#613) +- Bump cucumber.version from 7.10.0 to 7.10.1 (#614) +- Bump s3 from 2.18.40 to 2.18.41 (#615) +- Bump azure/setup-helm from 3.4 to 3.5 (#596) +- Bump actions/checkout from 3.1.0 to 3.2.0 (#598) +- Bump mockito-bom from 4.9.0 to 4.10.0 (#607) +- Bump s3 from 2.18.39 to 2.18.40 (#609) +- Bump flyway-core from 9.10.0 to 9.10.1 (#610) +- Bump actions/setup-java from 3.8.0 to 3.9.0 (#605) +- Bump s3 from 2.18.35 to 2.18.39 (#606) + + +## [0.2.0] - 2022-12-15 ### Fixed -- SQL leakage issue -- Catalog pagination +- Fixed Json LD serialization bug which prevented multi-BPN policies to be defined and used. Checkout the [docs](https://github.com/catenax-ng/product-edc/blob/0.2.0/edc-extensions/business-partner-validation/README.md) for more info. -## [0.1.5] - 2023-02-13 +## [0.1.3] - 2022-11-30 + +### Added + +- New Postman collection for developers `/docs/development/postman` +- New EDC Image with HashiCorp Vault and InMemory Storage +- (Experimental) Simplified deployment of the EDC in `/charts/tractusx-connector` + +### Changed + +- Set EDC version to `0.0.1-20221006-SNAPSHOT` +- Business Partner Number Extension no longer supports the 'IN' constraint operator +- HashiCorp Vault Extension now allows sub directories for secrets +- Update package structure/namespace from `net.catenax` to `org.eclipse.tractusx` ### Fixed -- Use patched EDC version: 0.0.1-20220922.2-SNAPSHOT to fix catalog pagination bug -- Data Encryption extension: fixed usage of a blocking algorithm +- S3 Data Transfer ## [0.1.2] - 2022-09-30 @@ -30,8 +158,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Moved helm charts from `deployment/helm` to `charts` -- Replaced distroless image with alpine in all docker images -- Update EDC commit to `740c100ac162bc41b1968c232ad81f7d739aefa9` ## [0.1.1] - 2022-09-04 @@ -48,7 +174,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Connectors with Azure Vault extension are now starting again [link](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1892) +- Connectors with Azure Vault extension are now starting again [link](https://github.com/eclipse-edc/Connector/issues/1892) ## [0.1.0] - 2022-08-19 @@ -57,11 +183,11 @@ corresponding [documentation](/docs/migration/Version_0.0.x_0.1.x.md). ### Added -- Control-Plane extension ([data-plane-selector-client](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/v0.0.1-milestone-5/extensions/data-plane-selector/selector-client)) +- Control-Plane extension ([data-plane-selector-client](https://github.com/eclipse-edc/Connector/tree/v0.0.1-milestone-5/extensions/data-plane-selector/selector-client)) - run the EDC with multiple data planes at once - Control-Plane extension ([dataplane-selector-configuration](edc-extensions/dataplane-selector-configuration)) - add data plane instances to the control plane by configuration -- Data-Plane extension ([s3-data-plane](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/aws/data-plane-s3)) +- Data-Plane extension ([s3-data-plane](https://github.com/eclipse-edc/Connector/tree/main/extensions/aws/data-plane-s3)) - transfer from and to AWS S3 buckets - Control-Plane extension ([data-encryption](edc-extensions/data-encryption)) - Data-Plane authentication attribute transmitted during data-plane-transfer can be encrypted symmetrically (AES) @@ -73,15 +199,15 @@ corresponding [documentation](/docs/migration/Version_0.0.x_0.1.x.md). ### Fixed -- Contract-Offer-Receiving-Connectors must also pass the ContractPolicy of the ContractDefinition before receiving offers([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1331)) -- Deletion of Asset becomes impossible when Contract Negotiation exists([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1403)) -- Deletion of Policy becomes impossible when Contract Definition exists([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1410)) +- Contract-Offer-Receiving-Connectors must also pass the ContractPolicy of the ContractDefinition before receiving offers([issue](https://github.com/eclipse-edc/Connector/issues/1331)) +- Deletion of Asset becomes impossible when Contract Negotiation exists([issue](https://github.com/eclipse-edc/Connector/issues/1403)) +- Deletion of Policy becomes impossible when Contract Definition exists([issue](https://github.com/eclipse-edc/Connector/issues/1410)) ## [0.0.6] - 2022-07-29 ### Fixed -- Fixes [release 0.0.5](https://github.com/eclipse-tractusx/tractusx-edc/releases/tag/0.0.5), which introduced classpath issues due to usage of [net.jodah:failsafe:2.4.3](https://search.maven.org/artifact/net.jodah/failsafe/2.4.3/jar) library +- Fixes [release 0.0.5](https://github.com/catenax-ng/product-edc/releases/tag/0.0.5), which introduced classpath issues due to usage of [net.jodah:failsafe:2.4.3](https://search.maven.org/artifact/net.jodah/failsafe/2.4.3/jar) library ## [0.0.5] - 2022-07-28 @@ -108,7 +234,7 @@ corresponding [documentation](/docs/migration/Version_0.0.x_0.1.x.md). ### Fixed -- [#1515](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1515) SQL: Connector sends out 50 +- [#1515](https://github.com/eclipse-edc/Connector/issues/1515) SQL: Connector sends out 50 contract offers max. ### Removed @@ -122,26 +248,28 @@ corresponding [documentation](/docs/migration/Version_0.0.x_0.1.x.md). ## [0.0.1] - 2022-05-13 -[Unreleased]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.1.6...HEAD +[Unreleased]: https://github.com/catenax-ng/product-edc/compare/0.3.0...HEAD + +[0.3.0]: https://github.com/catenax-ng/product-edc/compare/0.2.0...0.3.0 -[0.1.6]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.1.5...0.1.6 +[0.2.0]: https://github.com/catenax-ng/product-edc/compare/0.1.3...0.2.0 -[0.1.5]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.1.2...0.1.5 +[0.1.3]: https://github.com/catenax-ng/product-edc/compare/0.1.2...0.1.3 -[0.1.2]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.1.1...0.1.2 +[0.1.2]: https://github.com/catenax-ng/product-edc/compare/0.1.1...0.1.2 -[0.1.1]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.1.0...0.1.1 +[0.1.1]: https://github.com/catenax-ng/product-edc/compare/0.1.0...0.1.1 -[0.1.0]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.0.6...0.1.0 +[0.1.0]: https://github.com/catenax-ng/product-edc/compare/0.0.6...0.1.0 -[0.0.6]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.0.5...0.0.6 +[0.0.6]: https://github.com/catenax-ng/product-edc/compare/0.0.5...0.0.6 -[0.0.5]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.0.4...0.0.5 +[0.0.5]: https://github.com/catenax-ng/product-edc/compare/0.0.4...0.0.5 -[0.0.4]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.0.3...0.0.4 +[0.0.4]: https://github.com/catenax-ng/product-edc/compare/0.0.3...0.0.4 -[0.0.3]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.0.2...0.0.3 +[0.0.3]: https://github.com/catenax-ng/product-edc/compare/0.0.2...0.0.3 -[0.0.2]: https://github.com/eclipse-tractusx/tractusx-edc/compare/0.0.1...0.0.2 +[0.0.2]: https://github.com/catenax-ng/product-edc/compare/0.0.1...0.0.2 -[0.0.1]: https://github.com/eclipse-tractusx/tractusx-edc/compare/a02601306fed39a88a3b3b18fae98b80791157b9...0.0.1 +[0.0.1]: https://github.com/catenax-ng/product-edc/compare/a02601306fed39a88a3b3b18fae98b80791157b9...0.0.1 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index b249c6ab5..14db7e6fa 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,6 +1,6 @@ # Community Code of Conduct -**Version 1.2 +**Version 1.2 August 19, 2020** ## Our Pledge diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 99c652ef0..39dd5bdba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,4 +55,4 @@ https://www.eclipse.org/projects/handbook/#resources-commit Contact the project developers via the project's "dev" list. -* https://accounts.eclipse.org/mailing-list/tractusx-dev +* https://accounts.eclipse.org/mailing-list/tractusx-dev \ No newline at end of file diff --git a/DEPENDENCIES b/DEPENDENCIES index c6b2f625b..3479de982 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,169 +1,148 @@ -maven/mavencentral/com.azure/azure-core-http-netty/1.12.0, MIT, approved, clearlydefined -maven/mavencentral/com.azure/azure-core/1.28.0, MIT, approved, clearlydefined -maven/mavencentral/com.azure/azure-identity/1.5.1, MIT, approved, clearlydefined -maven/mavencentral/com.azure/azure-security-keyvault-secrets/4.4.2, MIT, approved, clearlydefined -maven/mavencentral/com.electronwill.night-config/core/3.6.6, NOASSERTION, restricted, clearlydefined -maven/mavencentral/com.electronwill.night-config/toml/3.6.6, NOASSERTION, restricted, clearlydefined -maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.13.3, Apache-2.0, approved, CQ24135 -maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.13.3, Apache-2.0, approved, CQ24134 -maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.13.3, Apache-2.0, approved, CQ24136 -maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-xml/2.13.2, Apache-2.0, restricted, clearlydefined -maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.13.3, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.fasterxml.woodstox/woodstox-core/6.2.7, Apache-2.0, approved, CQ23040 +maven/mavencentral/com.azure/azure-core-http-netty/1.12.7, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-core/1.34.0, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-identity/1.7.0, MIT, approved, clearlydefined +maven/mavencentral/com.azure/azure-security-keyvault-secrets/4.5.2, , restricted, clearlydefined +maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.14.0-rc2, Apache-2.0, approved, #5303 +maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.14.0-rc2, Apache-2.0 AND MIT, approved, #4303 +maven/mavencentral/com.fasterxml.jackson.core/jackson-databind/2.14.0-rc2, Apache-2.0, approved, #4105 +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-toml/2.14.0-rc2, Apache-2.0, restricted, clearlydefined +maven/mavencentral/com.fasterxml.jackson.dataformat/jackson-dataformat-xml/2.14.0-rc2, Apache-2.0, approved, #4300 +maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.14.0-rc2, Apache-2.0, approved, #4699 +maven/mavencentral/com.fasterxml.woodstox/woodstox-core/6.4.0, Apache-2.0, approved, #5309 maven/mavencentral/com.github.stephenc.jcip/jcip-annotations/1.0-1, Apache-2.0, approved, CQ21949 maven/mavencentral/com.microsoft.azure/msal4j-persistence-extension/1.1.0, MIT, approved, clearlydefined -maven/mavencentral/com.microsoft.azure/msal4j/1.12.0, MIT, approved, clearlydefined +maven/mavencentral/com.microsoft.azure/msal4j/1.13.3, MIT, approved, clearlydefined maven/mavencentral/com.nimbusds/content-type/2.2, Apache-2.0, approved, clearlydefined maven/mavencentral/com.nimbusds/lang-tag/1.6, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.nimbusds/nimbus-jose-jwt/9.21, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.nimbusds/nimbus-jose-jwt/9.24.3, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.nimbusds/oauth2-oidc-sdk/9.32, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.nimbusds/nimbus-jose-jwt/8.23, Apache-2.0, approved, clearlydefined +maven/mavencentral/com.nimbusds/oauth2-oidc-sdk/9.35, Apache-2.0, approved, clearlydefined maven/mavencentral/com.squareup.okhttp3/okhttp/4.9.3, Apache-2.0 AND MPL-2.0, approved, #3225 maven/mavencentral/com.squareup.okio/okio/2.8.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/de.fraunhofer.iais.eis.ids.infomodel/java/4.1.3, , restricted, clearlydefined -maven/mavencentral/de.fraunhofer.iais.eis.infomodel/util/4.1.3, , restricted, clearlydefined +maven/mavencentral/de.fraunhofer.iais.eis.ids.infomodel/java/4.1.3, Apache-2.0, approved, #3779 +maven/mavencentral/de.fraunhofer.iais.eis.infomodel/util/4.1.3, Apache-2.0, approved, #3780 maven/mavencentral/dev.failsafe/failsafe/3.2.4, Apache-2.0, approved, clearlydefined maven/mavencentral/io.micrometer/micrometer-core/1.8.2, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.netty/netty-buffer/4.1.76.Final, Apache-2.0, approved, CQ21842 -maven/mavencentral/io.netty/netty-codec-dns/4.1.75.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-http2/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec-socks/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-codec/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-common/4.1.76.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 -maven/mavencentral/io.netty/netty-handler-proxy/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-handler/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-resolver-dns-classes-macos/4.1.75.Final, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.75.Final, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.netty/netty-resolver-dns/4.1.75.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-resolver/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.51.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 -maven/mavencentral/io.netty/netty-tcnative-classes/2.0.51.Final, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.76.Final, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.netty/netty-transport-classes-kqueue/4.1.76.Final, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.netty/netty-transport/4.1.76.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 -maven/mavencentral/io.projectreactor.netty/reactor-netty-core/1.0.18, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.projectreactor.netty/reactor-netty-http/1.0.18, Apache-2.0, approved, clearlydefined -maven/mavencentral/io.projectreactor/reactor-core/3.4.17, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.netty/netty-buffer/4.1.82.Final, Apache-2.0, approved, CQ21842 +maven/mavencentral/io.netty/netty-codec-dns/4.1.81.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-http2/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec-socks/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-codec/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-common/4.1.82.Final, Apache-2.0 AND MIT AND CC0-1.0, approved, CQ21843 +maven/mavencentral/io.netty/netty-handler-proxy/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-handler/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver-dns-classes-macos/4.1.81.Final, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.netty/netty-resolver-dns-native-macos/4.1.81.Final, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.netty/netty-resolver-dns/4.1.81.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-resolver/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-tcnative-boringssl-static/2.0.54.Final, Apache-2.0 OR LicenseRef-Public-Domain OR BSD-2-Clause OR MIT, approved, CQ15280 +maven/mavencentral/io.netty/netty-tcnative-classes/2.0.54.Final, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.netty/netty-transport-classes-epoll/4.1.82.Final, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.netty/netty-transport-classes-kqueue/4.1.82.Final, Apache-2.0, approved, #4107 +maven/mavencentral/io.netty/netty-transport-native-epoll/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-kqueue/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport-native-unix-common/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.netty/netty-transport/4.1.82.Final, Apache-2.0 AND BSD-3-Clause AND MIT, approved, CQ20926 +maven/mavencentral/io.projectreactor.netty/reactor-netty-core/1.0.23, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.projectreactor.netty/reactor-netty-http/1.0.23, Apache-2.0, approved, clearlydefined +maven/mavencentral/io.projectreactor/reactor-core/3.4.23, Apache-2.0, approved, clearlydefined maven/mavencentral/jakarta.ws.rs/jakarta.ws.rs-api/3.1.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.rest maven/mavencentral/javax.validation/validation-api/2.0.1.Final, Apache-2.0, approved, CQ15302 -maven/mavencentral/net.catenax.edc.extensions/business-partner-validation/0.1.1-SNAPSHOT, , restricted, clearlydefined -maven/mavencentral/net.catenax.edc.extensions/cx-oauth2/0.1.1-SNAPSHOT, , restricted, clearlydefined -maven/mavencentral/net.catenax.edc.extensions/data-encryption/0.1.1-SNAPSHOT, , restricted, clearlydefined -maven/mavencentral/net.catenax.edc.extensions/dataplane-selector-configuration/0.1.1-SNAPSHOT, , restricted, clearlydefined -maven/mavencentral/net.catenax.edc.extensions/hashicorp-vault/0.1.1-SNAPSHOT, , restricted, clearlydefined -maven/mavencentral/net.catenax.edc.extensions/postgresql-migration/0.1.1-SNAPSHOT, , restricted, clearlydefined -maven/mavencentral/net.catenax.edc/edc-controlplane-base/0.1.1-SNAPSHOT, , restricted, clearlydefined -maven/mavencentral/net.catenax.edc/edc-controlplane-postgresql/0.1.1-SNAPSHOT, , restricted, clearlydefined -maven/mavencentral/net.catenax.edc/edc-dataplane-base/0.1.1-SNAPSHOT, , restricted, clearlydefined maven/mavencentral/net.java.dev.jna/jna-platform/5.6.0, Apache-2.0 OR LGPL-2.1-or-later, approved, CQ22390 maven/mavencentral/net.java.dev.jna/jna/5.5.0, Apache-2.0 or LGPL-2.1, approved, #1508 -maven/mavencentral/net.minidev/accessors-smart/2.4.8, Apache-2.0, approved, clearlydefined -maven/mavencentral/net.minidev/json-smart/2.4.8, Apache-2.0, approved, #3288 +maven/mavencentral/net.minidev/accessors-smart/2.4.7, Apache-2.0, approved, clearlydefined +maven/mavencentral/net.minidev/json-smart/2.4.7, Apache-2.0, approved, #3288 maven/mavencentral/org.bouncycastle/bcpkix-jdk15on/1.70, MIT, approved, clearlydefined maven/mavencentral/org.bouncycastle/bcprov-jdk15on/1.70, MIT, approved, #1712 maven/mavencentral/org.bouncycastle/bcutil-jdk15on/1.70, MIT, approved, clearlydefined maven/mavencentral/org.codehaus.woodstox/stax2-api/4.2.1, BSD-2-Clause, approved, #2670 -maven/mavencentral/org.eclipse.dataspaceconnector/apache-commons-pool-sql/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/api-configuration/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/api-core/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/asset-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/asset-index-sql/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/auth-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/auth-tokenbased/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/azure-vault/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/catalog-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/catalog-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/common-sql/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/common-util/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/contract-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/contract/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/contractagreement-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/contractdefinition-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/contractdefinition-store-sql/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/contractnegotiation-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/contractnegotiation-store-sql/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/control-plane-core/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/control-plane-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/core-base/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/core-boot/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/core-micrometer/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/core-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-management-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-framework/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-http/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-s3/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-selector-client/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-selector-core/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-selector-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-transfer-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/data-plane-transfer-sync/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/filesystem-configuration/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/http-receiver/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/http/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/ids-api-configuration/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/ids-api-multipart-dispatcher-v1/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/ids-api-multipart-endpoint-v1/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/ids-api-transform-v1/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/ids-core/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/ids-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/jdk-logger-monitor/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/jersey-micrometer/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/jersey/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/jetty-micrometer/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/jetty/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/jwt-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/oauth2-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/observability-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/policy-engine-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/policy-engine/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/policy-evaluator/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/policy-model/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/policy-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/policy-store-sql/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/policydefinition-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/runtime-metamodel/0.0.1-20220929.123028-13, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/s3-core/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/transaction-datasource-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/transaction-local/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/transaction-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/transfer-process-store-sql/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/transfer-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/transfer/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/transferprocess-api/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/transport-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.eclipse.dataspaceconnector/web-spi/0.0.1-20220902-SNAPSHOT, Apache-2.0, approved, technology.dataspaceconnector -maven/mavencentral/org.flywaydb/flyway-core/9.3.1, NOASSERTION, restricted, clearlydefined +maven/mavencentral/org.eclipse.edc/aggregate-service-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/api-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/api-observability/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/asset-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/asset-index-sql/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/auth-tokenbased/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/boot/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/catalog-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/catalog-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/configuration-filesystem/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/connector-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-agreement-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-definition-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-definition-store-sql/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-negotiation-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-negotiation-store-sql/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/contract-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-api-client-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/control-plane-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/core-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-aws-s3/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-framework/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-http/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-client/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-selector-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-transfer-client/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-transfer-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/data-plane-transfer-sync/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/http-receiver/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/http/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/ids-api-configuration/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/ids-api-multipart-dispatcher-v1/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/ids-api-multipart-endpoint-v1/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/ids-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/ids-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/ids-transform-v1/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jersey-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jersey-micrometer/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jetty-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jetty-micrometer/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/jwt-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/management-api-configuration/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/management-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/micrometer-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/monitor-jdk-logger/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/oauth2-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/oauth2-daps/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/oauth2-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-definition-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-definition-store-sql/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-engine-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-model/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/policy-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/runtime-metamodel/0.0.1-20221208.055231-48, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-core/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/sql-pool-apache-commons/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-datasource-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-local/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transaction-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-process-api/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-process-store-sql/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transfer-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/transform-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/util/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/vault-azure/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.edc/web-spi/0.0.1-20221201-20221201.072646-1, Apache-2.0, approved, technology.edc +maven/mavencentral/org.eclipse.tractusx.edc.extensions/business-partner-validation/0.1.4-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.edc.extensions/cx-oauth2/0.1.4-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.edc.extensions/data-encryption/0.1.4-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.edc.extensions/dataplane-selector-configuration/0.1.4-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.edc.extensions/hashicorp-vault/0.1.4-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.edc.extensions/postgresql-migration/0.1.4-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.edc/edc-controlplane-base/0.1.4-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.edc/edc-dataplane-base/0.1.4-SNAPSHOT, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.flywaydb/flyway-core/9.8.3, , restricted, clearlydefined maven/mavencentral/org.hdrhistogram/HdrHistogram/2.1.12, , approved, CQ13192 maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-common/1.4.0, Apache-2.0, approved, clearlydefined maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/1.4.10, Apache-2.0, approved, clearlydefined maven/mavencentral/org.jetbrains/annotations/15.0, Apache-2.0, approved, clearlydefined +maven/mavencentral/org.ow2.asm/asm/9.1, BSD-3-Clause, approved, CQ23029 maven/mavencentral/org.ow2.asm/asm/9.3, BSD-3-Clause, approved, CQ24052 -maven/mavencentral/org.postgresql/postgresql/42.5.0, BSD-2-Clause, approved, #3416 +maven/mavencentral/org.postgresql/postgresql/42.5.1, BSD-2-Clause, approved, #3416 maven/mavencentral/org.projectlombok/lombok/1.18.24, MIT AND LicenseRef-Public-Domain, approved, CQ23907 -maven/mavencentral/org.reactivestreams/reactive-streams/1.0.3, CC0-1.0, approved, CQ16332 -maven/mavencentral/org.slf4j/slf4j-api/2.0.0-beta1, MIT, approved, CQ24150 -maven/mavencentral/software.amazon.awssdk/annotations/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/arns/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/auth/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/aws-core/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/aws-query-protocol/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/aws-xml-protocol/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/http-client-spi/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/iam/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/json-utils/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/metrics-spi/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/profiles/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/protocol-core/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/regions/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/s3/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/sdk-core/2.17.278, Apache-2.0, approved, #3167 -maven/mavencentral/software.amazon.awssdk/sts/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.awssdk/third-party-jackson-core/2.17.278, Apache-2.0, approved, #3166 -maven/mavencentral/software.amazon.awssdk/utils/2.17.278, , restricted, clearlydefined -maven/mavencentral/software.amazon.eventstream/eventstream/1.0.1, Apache-2.0, approved, clearlydefined +maven/mavencentral/org.reactivestreams/reactive-streams/1.0.4, CC0-1.0, approved, CQ16332 +maven/mavencentral/org.slf4j/slf4j-api/2.0.3, MIT, approved, CQ24285 diff --git a/NOTICE.md b/NOTICE.md index fd82f06ce..d9fce018c 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -20,16 +20,18 @@ source code repository logs. 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. +https://www.apache.org/licenses/LICENSE-2.0 SPDX-License-Identifier: Apache-2.0 ## Source Code -The project maintains the following source code repositories +The project maintains the following source code repositories in the GitHub organization https://github.com/eclipse-tractusx: -* https://github.com/eclipse-tractusx/tractusx-edc +* https://github.com/eclipse-tractusx/ +* https://github.com/eclipse-tractusx/ + ## Third-party Content diff --git a/README.md b/README.md index df4b35256..4bb5016de 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,14 @@

Catena-X

- Container images and deployments of the Eclipse Dataspace Connector open source project. + Container images and deployments of the Eclipse Dataspace Components open source project.
- Explore the docs » + Explore the docs »

- View Eclipse Dataspace Connector + View Eclipse Dataspace Components · - Releases + Releases · Report Bug / Request Feature

@@ -53,7 +53,7 @@ ## About The Project -The project provides pre-built control- and data-plane [docker](https://www.docker.com/) images and [helm](https://helm.sh/) charts of the [Eclipse DataSpaceConnector Project](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector). +The project provides pre-built control- and data-plane [docker](https://www.docker.com/) images and [helm](https://helm.sh/) charts of the [Eclipse DataSpaceConnector Project](https://github.com/eclipse-edc/Connector).

(back to top)

@@ -90,32 +90,26 @@ Derivatives of the Data-Plane can be found here ### Build -1. Build EDC Submodule Dependencies +Build Product-EDC together with its Container Images ```shell -git submodule update --init -cd edc && ./gradlew publishToMavenLocal -Pskip.signing=true -PedcVersion=0.0.1-20220902-SNAPSHOT -xjavadoc && cd .. -``` - -2. Build Product-EDC Container Images -```shell -./mvnw package -Pwith-docker-image +./gradlew dockerize ```

(back to top)

## License -Distributed under the Apache 2.0 License. See [LICENSE](https://github.com/eclipse-tractusx/tractusx-edc/blob/main/LICENSE) for more information. +Distributed under the Apache 2.0 License. See [LICENSE](https://github.com/catenax-ng/product-edc/blob/main/LICENSE) for more information.

(back to top)

-[contributors-shield]: https://img.shields.io/github/contributors/eclipse-tractusx/tractusx-edc.svg?style=for-the-badge -[contributors-url]: https://github.com/eclipse-tractusx/tractusx-edc/graphs/contributors -[stars-shield]: https://img.shields.io/github/stars/eclipse-tractusx/tractusx-edc.svg?style=for-the-badge -[stars-url]: https://github.com/eclipse-tractusx/tractusx-edc/stargazers -[license-shield]: https://img.shields.io/github/license/eclipse-tractusx/tractusx-edc.svg?style=for-the-badge -[license-url]: https://github.com/eclipse-tractusx/tractusx-edc/blob/main/LICENSE -[release-shield]: https://img.shields.io/github/v/release/eclipse-tractusx/tractusx-edc.svg?style=for-the-badge -[release-url]: https://github.com/eclipse-tractusx/tractusx-edc/releases +[contributors-shield]: https://img.shields.io/github/contributors/catenax-ng/product-edc.svg?style=for-the-badge +[contributors-url]: https://github.com/catenax-ng/product-edc/graphs/contributors +[stars-shield]: https://img.shields.io/github/stars/catenax-ng/product-edc.svg?style=for-the-badge +[stars-url]: https://github.com/catenax-ng/product-edc/stargazers +[license-shield]: https://img.shields.io/github/license/catenax-ng/product-edc.svg?style=for-the-badge +[license-url]: https://github.com/catenax-ng/product-edc/blob/main/LICENSE +[release-shield]: https://img.shields.io/github/v/release/catenax-ng/product-edc.svg?style=for-the-badge +[release-url]: https://github.com/catenax-ng/product-edc/releases diff --git a/SECURITY.md b/SECURITY.md index ebfd8b30b..7d8fced73 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,63 +1,6 @@ # Security Policy - - - - -## Reporting a bug in Catena-X - - - - -Report security bugs in Catena-X to "dl_CoP_IT_Security@catena-x.net". - -Your report will be acknowledged within 5 days, and you’ll receive a more detailed response to your report within 10 days indicating the next steps in handling your submission. - -After the initial reply to your report, the security team will endeavor to keep you informed of the progress being made towards a fix and full announcement, and may ask for additional information or guidance surrounding the reported issue. - -Please do not report security bugs through public GitHub issues. - - - - -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - -- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - -- Full paths of source file(s) related to the manifestation of the issue - -- The location of the affected source code (tag/branch/commit or direct URL) - -- Any special configuration required to reproduce the issue - -- Step-by-step instructions to reproduce the issue - -- Proof-of-concept or exploit code (if possible) - -- Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - - - - -## Reporting a bug in a third party module - -Security bugs in third party modules should be reported to their respective maintainers. - - - - -## Disclosure policy - -Here is the security disclosure policy for Catena-X. - -- The security report is received and is assigned a primary handler. - -- This person will coordinate the fix and release process. - -- Fixes are prepared for all releases which are still under maintenance. - -- A suggested embargo date for this vulnerability is chosen. Typically the embargo date will be set to 72 hours. However, this may vary depending on the severity of the bug or difficulty in applying a fix. - -This process can take some time, especially when coordination is required with maintainers of other projects. -Every effort will be made to handle the bug in as timely a manner as possible; however, it’s important that we follow the release process above to ensure that the disclosure is handled in a consistent manner. + +## Reporting a Vulnerability + +Please report a found vulnerability here: +[https://www.eclipse.org/security/](https://www.eclipse.org/security/) \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 000000000..c7b27ddd3 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,150 @@ +import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage +import com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin + +plugins { + `java-library` + `maven-publish` + `jacoco-report-aggregation` + id("io.freefair.lombok") version "6.6.2" + id("com.diffplug.spotless") version "6.15.0" + id("com.github.johnrengelman.shadow") version "8.0.0" + id("com.bmuschko.docker-remote-api") version "9.2.1" + id("org.sonarqube") version "4.0.0.2929" +} + +val javaVersion: String by project +val scmConnection: String by project +val websiteUrl: String by project +val scmUrl: String by project +val groupId: String by project +val defaultVersion: String by project +val annotationProcessorVersion: String by project +val metaModelVersion: String by project + +var actualVersion: String = (project.findProperty("version") ?: defaultVersion) as String +if (actualVersion == "unspecified") { + actualVersion = defaultVersion +} + +buildscript { + repositories { + mavenLocal() + } + dependencies { + val edcGradlePluginsVersion: String by project + classpath("org.eclipse.edc.edc-build:org.eclipse.edc.edc-build.gradle.plugin:${edcGradlePluginsVersion}") + } +} + +// include all subprojects in the jacoco report aggregation +project.subprojects.forEach{ + dependencies{ + jacocoAggregation(project(it.path)) + } +} + +// make sure the test report aggregation is done before reporting to sonar +tasks.sonar { + dependsOn(tasks.named("testCodeCoverageReport")) +} + +allprojects { + apply(plugin = "org.eclipse.edc.edc-build") + apply(plugin = "io.freefair.lombok") + apply(plugin = "org.sonarqube") + + repositories { + mavenCentral() + } + dependencies { + implementation("org.projectlombok:lombok:1.18.26") + implementation("org.slf4j:slf4j-api:2.0.5") + } + + // configure which version of the annotation processor to use. defaults to the same version as the plugin + configure { + processorVersion.set(annotationProcessorVersion) + outputDirectory.set(project.buildDir) + } + + configure { + versions { + // override default dependency versions here + projectVersion.set(actualVersion) + metaModel.set(metaModelVersion) + + } + val gid = groupId; + pom { + // this is actually important, so we can publish under the correct GID + groupId = gid + projectName.set(project.name) + description.set("edc :: ${project.name}") + projectUrl.set(websiteUrl) + scmConnection.set(scmConnection) + scmUrl.set(scmUrl) + } + swagger { + title.set((project.findProperty("apiTitle") ?: "Tractus-X REST API") as String) + description = + (project.findProperty("apiDescription") ?: "Tractus-X REST APIs - merged by OpenApiMerger") as String + outputFilename.set(project.name) + outputDirectory.set(file("${rootProject.projectDir.path}/resources/openapi/yaml")) + resourcePackages = setOf("org.eclipse.tractusx.edc") + } + javaLanguageVersion.set(JavaLanguageVersion.of(javaVersion)) + } + + configure { + configFile = rootProject.file("resources/edc-checkstyle-config.xml") + configDirectory.set(rootProject.file("resources")) + } + + + // this is a temporary workaround until we're fully moved to TractusX: + // publishing to OSSRH is handled by the build plugin, but publishing to GH packages + // must be configured separately + publishing{ + repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/catenax-ng/product-edc") + credentials { + username = System.getenv("GITHUB_PACKAGE_USERNAME") + password = System.getenv("GITHUB_PACKAGE_PASSWORD") + } + } + } + } + +} + +// the "dockerize" task is added to all projects that use the `shadowJar` plugin +subprojects { + afterEvaluate { + if (project.plugins.hasPlugin("com.github.johnrengelman.shadow")) { + + //actually apply the plugin to the (sub-)project + + apply(plugin = "com.bmuschko.docker-remote-api") + + // configure the "dockerize" task + val dockerTask = tasks.create("dockerize", DockerBuildImage::class) { + dockerFile.set(file("${project.projectDir}/src/main/docker/Dockerfile")) + images.add("${project.name}:${project.version}") + images.add("${project.name}:latest") + buildArgs.put("JAR", "build/libs/${project.name}.jar") + inputDir.set(file(project.projectDir)) + } + + // make sure "shadowJar" always runs before "dockerize" + dockerTask.dependsOn(tasks.findByName(ShadowJavaPlugin.SHADOW_JAR_TASK_NAME)) + } + } + + sonarqube { + properties { + property("sonar.moduleKey", "${project.group}-${project.name}") + } + } +} diff --git a/charts/edc-controlplane/.helmignore b/charts/edc-controlplane/.helmignore index 148b31d6c..00ca644b2 100644 --- a/charts/edc-controlplane/.helmignore +++ b/charts/edc-controlplane/.helmignore @@ -23,7 +23,3 @@ .vscode/ README.md.gotmpl - -# Accept only values.yaml -values?*.yaml -values?*.yml diff --git a/charts/edc-controlplane/Chart.yaml b/charts/edc-controlplane/Chart.yaml index d75856ad7..09c6201cc 100644 --- a/charts/edc-controlplane/Chart.yaml +++ b/charts/edc-controlplane/Chart.yaml @@ -27,8 +27,9 @@ description: >- EDC Control-Plane - The Eclipse DataSpaceConnector administration layer with responsibility of resource management and govern contracts and data transfers home: https://github.com/eclipse-tractusx/tractusx-edc type: application -appVersion: "0.1.6" -version: 0.1.7 +appVersion: "0.3.0" +version: 0.3.0 +deprecated: true maintainers: [] sources: - https://github.com/eclipse-tractusx/tractusx-edc diff --git a/charts/edc-controlplane/LICENSE b/charts/edc-controlplane/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/charts/edc-controlplane/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://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. diff --git a/charts/edc-controlplane/README.md b/charts/edc-controlplane/README.md index afef893f5..71238a6ac 100644 --- a/charts/edc-controlplane/README.md +++ b/charts/edc-controlplane/README.md @@ -1,15 +1,17 @@ # edc-controlplane -![Version: 0.1.6](https://img.shields.io/badge/Version-0.1.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.1.6](https://img.shields.io/badge/AppVersion-0.1.6-informational?style=flat-square) +> **:exclamation: This Helm Chart is deprecated!** + +![Version: 0.3.0](https://img.shields.io/badge/Version-0.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square) EDC Control-Plane - The Eclipse DataSpaceConnector administration layer with responsibility of resource management and govern contracts and data transfers -- **Homepage:** +**Homepage:** ## TL;DR ```shell $ helm repo add tractusx-edc https://eclipse-tractusx.github.io/charts/dev -$ helm install my-release tractusx-edc/edc-controlplane --version 0.1.6 +$ helm install my-release tractusx-edc/edc-controlplane --version 0.3.0 ``` ## Values @@ -23,7 +25,8 @@ $ helm install my-release tractusx-edc/edc-controlplane --version 0.1.6 | autoscaling.minReplicas | int | `1` | Minimal replicas if resource consumption falls below resource threshholds | | autoscaling.targetCPUUtilizationPercentage | int | `80` | targetAverageUtilization of cpu provided to a pod | | autoscaling.targetMemoryUtilizationPercentage | int | `80` | targetAverageUtilization of memory provided to a pod | -| configuration.properties | string | `"# edc.api.auth.key=\n# edc.atomikos.checkpoint.interval=\n# edc.atomikos.directory=\n# edc.atomikos.logging=\n# edc.atomikos.threaded2pc=\n# edc.atomikos.timeout=\n# edc.aws.access.key=\n# edc.aws.provision.retry.retries.max=\n# edc.aws.provision.role.duration.session.max=\n# edc.aws.secret.access.key=\n# edc.blobstore.endpoint=\n# edc.dataplane.token.validation.endpoint=\n# edc.core.retry.backoff.max=\n# edc.core.retry.backoff.min=\n# edc.core.retry.retries.max=\n# edc.core.system.health.check.liveness-period=\n# edc.core.system.health.check.readiness-period=\n# edc.core.system.health.check.startup-period=\n# edc.core.system.health.check.threadpool-size=\n# edc.dataplane.queue.capacity=\n# edc.dataplane.wait=\n# edc.dataplane.workers=\n# edc.datasource.asset.name=\"default\"\n# edc.datasource.contractdefinition.name=\"default\"\n# edc.datasource.contractnegotiation.name=\"default\"\n# edc.datasource.policy.name=\"default\"\n# edc.datasource.transferprocess.name=\"default\"\n# edc.datasource.default.pool.maxIdleConnections=\n# edc.datasource.default.pool.maxTotalConnections=\n# edc.datasource.default.pool.minIdleConnections=\n# edc.datasource.default.pool.testConnectionOnBorrow=\n# edc.datasource.default.pool.testConnectionOnCreate=\n# edc.datasource.default.pool.testConnectionOnReturn=\n# edc.datasource.default.pool.testConnectionWhileIdle=\n# edc.datasource.default.pool.testQuery=\n# edc.datasource.default.url=\n# edc.datasource.default.user=\n# edc.datasource.default.password=\n# edc.dpf.selector.url=\n# edc.events.topic.endpoint=\n# edc.events.topic.name=\n# edc.fs.config=\n# edc.hostname=\n# edc.identity.did.url=\n# edc.ids.catalog.id=\n# edc.ids.curator=\n# edc.ids.description=\n# edc.ids.endpoint=\n# edc.ids.id=\n# edc.ids.maintainer=\n# edc.ids.security.profile=\n# edc.ids.title=\n# edc.ids.validation.referringconnector=\n# edc.ion.crawler.did-type=\n# edc.ion.crawler.interval-minutes=\n# edc.ion.crawler.ion.url=\n# edc.metrics.enabled=\n# edc.metrics.executor.enabled=\n# edc.metrics.jersey.enabled=\n# edc.metrics.jetty.enabled=\n# edc.metrics.okhttp.enabled=\n# edc.metrics.system.enabled=\n# edc.negotiation.consumer.state-machine.batch-size=\n# edc.negotiation.provider.state-machine.batch-size=\n# edc.oauth.client.id=\n# edc.oauth.private.key.alias=\n# edc.oauth.provider.audience=\n# edc.oauth.provider.jwks.refresh=\n# edc.oauth.provider.jwks.url=\n# edc.oauth.public.key.alias=\n# edc.oauth.token.url=\n# edc.oauth.validation.nbf.leeway=\n# edc.receiver.http.auth-code=\n# edc.receiver.http.auth-key=\n# edc.receiver.http.endpoint=\n# edc.transfer.proxy.endpoint=\n# edc.transfer.proxy.token.validity.seconds=\n# edc.transfer.proxy.token.signer.privatekey.alias=\n# edc.transfer.functions.check.endpoint=\n# edc.transfer.functions.enabled.protocols=\n# edc.transfer.functions.transfer.endpoint=\n# edc.transfer-process-store.database.name=\n# edc.transfer.state-machine.batch-size=\n# edc.vault=\n# edc.vault.certificate=\n# edc.vault.clientid=\n# edc.vault.clientsecret=\n# edc.vault.name=\n# edc.vault.tenantid=\n# edc.vault.hashicorp.url=\n# edc.vault.hashicorp.token=\n# edc.vault.hashicorp.timeout.seconds=\n# edc.webdid.doh.url=\n# edc.web.rest.cors.enabled=\n# edc.web.rest.cors.headers=\n# edc.web.rest.cors.methods=\n# edc.web.rest.cors.origins=\n# ids.webhook.address="` | EDC configuration.properties configuring aspects of the [eclipse-dataspaceconnector](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector) | +| configuration.properties | string | `"# edc.api.auth.key=\n# edc.atomikos.checkpoint.interval=\n# edc.atomikos.directory=\n# edc.atomikos.logging=\n# edc.atomikos.threaded2pc=\n# edc.atomikos.timeout=\n# edc.aws.access.key=\n# edc.aws.provision.retry.retries.max=\n# edc.aws.provision.role.duration.session.max=\n# edc.aws.secret.access.key=\n# edc.blobstore.endpoint=\n# edc.dataplane.token.validation.endpoint=\n# edc.core.retry.backoff.max=\n# edc.core.retry.backoff.min=\n# edc.core.retry.retries.max=\n# edc.core.system.health.check.liveness-period=\n# edc.core.system.health.check.readiness-period=\n# edc.core.system.health.check.startup-period=\n# edc.core.system.health.check.threadpool-size=\n# edc.dataplane.queue.capacity=\n# edc.dataplane.wait=\n# edc.dataplane.workers=\n# edc.datasource.asset.name=\"default\"\n# edc.datasource.contractdefinition.name=\"default\"\n# edc.datasource.contractnegotiation.name=\"default\"\n# edc.datasource.policy.name=\"default\"\n# edc.datasource.transferprocess.name=\"default\"\n# edc.datasource.default.pool.maxIdleConnections=\n# edc.datasource.default.pool.maxTotalConnections=\n# edc.datasource.default.pool.minIdleConnections=\n# edc.datasource.default.pool.testConnectionOnBorrow=\n# edc.datasource.default.pool.testConnectionOnCreate=\n# edc.datasource.default.pool.testConnectionOnReturn=\n# edc.datasource.default.pool.testConnectionWhileIdle=\n# edc.datasource.default.pool.testQuery=\n# edc.datasource.default.url=\n# edc.datasource.default.user=\n# edc.datasource.default.password=\n# edc.dpf.selector.url=\n# edc.events.topic.endpoint=\n# edc.events.topic.name=\n# edc.fs.config=\n# edc.hostname=\n# edc.identity.did.url=\n# edc.ids.catalog.id=\n# edc.ids.curator=\n# edc.ids.description=\n# edc.ids.endpoint=\n# edc.ids.id=\n# edc.ids.maintainer=\n# edc.ids.security.profile=\n# edc.ids.title=\n# edc.ids.validation.referringconnector=\n# edc.ion.crawler.did-type=\n# edc.ion.crawler.interval-minutes=\n# edc.ion.crawler.ion.url=\n# edc.metrics.enabled=\n# edc.metrics.executor.enabled=\n# edc.metrics.jersey.enabled=\n# edc.metrics.jetty.enabled=\n# edc.metrics.okhttp.enabled=\n# edc.metrics.system.enabled=\n# edc.negotiation.consumer.state-machine.batch-size=\n# edc.negotiation.provider.state-machine.batch-size=\n# edc.oauth.client.id=\n# edc.oauth.private.key.alias=\n# edc.oauth.provider.audience=\n# edc.oauth.provider.jwks.refresh=\n# edc.oauth.provider.jwks.url=\n# edc.oauth.public.key.alias=\n# edc.oauth.token.url=\n# edc.oauth.validation.nbf.leeway=\n# edc.receiver.http.auth-code=\n# edc.receiver.http.auth-key=\n# edc.receiver.http.endpoint=\n# edc.transfer.proxy.endpoint=\n# edc.transfer.proxy.token.validity.seconds=\n# edc.transfer.proxy.token.signer.privatekey.alias=\n# edc.transfer.functions.check.endpoint=\n# edc.transfer.functions.enabled.protocols=\n# edc.transfer.functions.transfer.endpoint=\n# edc.transfer-process-store.database.name=\n# edc.transfer.state-machine.batch-size=\n# edc.vault=\n# edc.vault.certificate=\n# edc.vault.clientid=\n# edc.vault.clientsecret=\n# edc.vault.name=\n# edc.vault.tenantid=\n# edc.vault.hashicorp.url=\n# edc.vault.hashicorp.token=\n# edc.vault.hashicorp.timeout.seconds=\n# edc.webdid.doh.url=\n# edc.web.rest.cors.enabled=\n# edc.web.rest.cors.headers=\n# edc.web.rest.cors.methods=\n# edc.web.rest.cors.origins=\n# ids.webhook.address="` | EDC configuration.properties configuring aspects of the [eclipse-dataspaceconnector](https://github.com/eclipse-edc/Connector) | +| customLabels | object | `{}` | Additional custom Labels to add | | edc.endpoints.control.path | string | `"/api/controlplane/control"` | The path mapping the "control" api is going to be exposed at | | edc.endpoints.control.port | string | `"9999"` | The network port, which the "control" api is going to be exposed by the container, pod and service | | edc.endpoints.data.path | string | `"/data"` | The path mapping the "data" management api is going to be exposed at | @@ -40,7 +43,7 @@ $ helm install my-release tractusx-edc/edc-controlplane --version 0.1.6 | envSecretName | string | `nil` | [Kubernetes Secret Resource](https://kubernetes.io/docs/concepts/configuration/secret/) name to load environment variables from | | fullnameOverride | string | `""` | Overrides the releases full name | | image.pullPolicy | string | `"IfNotPresent"` | [Kubernetes image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) to use | -| image.repository | string | `"ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-postgresql-hashicorp-vault"` | Which derivate of the edc control-plane to use. One of: [ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-postgresql-hashicorp-vault, ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-postgresql, ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-memory] | +| image.repository | string | `"ghcr.io/catenax-ng/product-edc/edc-controlplane-postgresql-hashicorp-vault"` | Which derivate of the edc control-plane to use. One of: [ghcr.io/catenax-ng/product-edc/edc-controlplane-postgresql-hashicorp-vault, ghcr.io/catenax-ng/product-edc/edc-controlplane-postgresql, ghcr.io/catenax-ng/product-edc/edc-controlplane-memory] | | image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion. | | imagePullSecret.dockerconfigjson | string | `""` | Image pull secret to create to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) Note: This value needs to adhere to the [(base64 encoded) .dockerconfigjson format](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials). Furthermore, if 'imagePullSecret.dockerconfigjson' is defined, it takes precedence over 'imagePullSecrets'. | | 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) | @@ -65,7 +68,7 @@ $ helm install my-release tractusx-edc/edc-controlplane --version 0.1.6 | ingresses[1].tls.enabled | bool | `false` | Enables TLS on the ingress resource | | ingresses[1].tls.secretName | string | `""` | If present overwrites the default secret name | | livenessProbe.enabled | bool | `true` | Whether to enable kubernetes [liveness-probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) | -| logging.properties | string | `".level=INFO\norg.eclipse.dataspaceconnector.level=ALL\nhandlers=java.util.logging.ConsoleHandler\njava.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter\njava.util.logging.ConsoleHandler.level=ALL\njava.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n"` | EDC logging.properties configuring the [java.util.logging subsystem](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.8) | +| logging.properties | string | `".level=INFO\norg.eclipse.edc.level=ALL\nhandlers=java.util.logging.ConsoleHandler\njava.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter\njava.util.logging.ConsoleHandler.level=ALL\njava.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n"` | EDC logging.properties configuring the [java.util.logging subsystem](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.8) | | nameOverride | string | `""` | Overrides the charts name | | nodeSelector | object | `{}` | [Node-Selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) to constrain the Pod to nodes with specific labels. | | opentelemetry.properties | string | `"otel.javaagent.enabled=true\notel.javaagent.debug=false"` | opentelemetry.properties configuring the [opentelemetry agent](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/) | @@ -91,6 +94,8 @@ $ helm install my-release tractusx-edc/edc-controlplane --version 0.1.6 | startupProbe.failureThreshold | int | `12` | Minimum consecutive failures for the probe to be considered failed after having succeeded | | startupProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before liveness probes are initiated. | | tolerations | list | `[]` | [Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) are applied to Pods to schedule onto nodes with matching taints. | +| volumeMounts | list | `[]` | Additional volumeMounts to the controlplane main container | +| volumes | list | `[]` | Additional volumes to the controlplane pod | ---------------------------------------------- Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0) diff --git a/charts/edc-controlplane/templates/_helpers.tpl b/charts/edc-controlplane/templates/_helpers.tpl index b1d1c7d15..272a0f27d 100644 --- a/charts/edc-controlplane/templates/_helpers.tpl +++ b/charts/edc-controlplane/templates/_helpers.tpl @@ -36,6 +36,7 @@ Common labels {{- define "edc-controlplane.labels" -}} helm.sh/chart: {{ include "edc-controlplane.chart" . }} {{ include "edc-controlplane.selectorLabels" . }} +{{ include "edc-controlplane.customLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} @@ -50,6 +51,15 @@ app.kubernetes.io/name: {{ include "edc-controlplane.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} +{{/* +Custom labels +*/}} +{{- define "edc-controlplane.customLabels" -}} +{{- with .Values.customLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + {{/* Create the name of the service account to use */}} diff --git a/charts/edc-controlplane/templates/deployment.yaml b/charts/edc-controlplane/templates/deployment.yaml index 880844a67..4fd762d0b 100644 --- a/charts/edc-controlplane/templates/deployment.yaml +++ b/charts/edc-controlplane/templates/deployment.yaml @@ -123,6 +123,9 @@ spec: - name: configuration mountPath: /app/logging.properties subPath: logging.properties + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} volumes: - name: configuration configMap: @@ -134,6 +137,9 @@ spec: path: opentelemetry.properties - key: logging.properties path: logging.properties + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/charts/edc-controlplane/values.yaml b/charts/edc-controlplane/values.yaml index 34cd2128b..f3443773f 100644 --- a/charts/edc-controlplane/values.yaml +++ b/charts/edc-controlplane/values.yaml @@ -31,8 +31,8 @@ replicaCount: 1 image: # -- Which derivate of the edc control-plane to use. - # One of: [ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-postgresql-hashicorp-vault, ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-postgresql, ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-memory] - repository: ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-postgresql-hashicorp-vault + # One of: [ghcr.io/catenax-ng/product-edc/edc-controlplane-postgresql-hashicorp-vault, ghcr.io/catenax-ng/product-edc/edc-controlplane-postgresql, ghcr.io/catenax-ng/product-edc/edc-controlplane-memory] + repository: ghcr.io/catenax-ng/product-edc/edc-controlplane-postgresql-hashicorp-vault # -- [Kubernetes image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) to use pullPolicy: IfNotPresent # -- Overrides the image tag whose default is the chart appVersion. @@ -53,6 +53,9 @@ nameOverride: "" # -- Overrides the releases full name fullnameOverride: "" +# -- Additional custom Labels to add +customLabels: {} + serviceAccount: # -- Specifies whether a [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) should be created per release create: true @@ -112,6 +115,12 @@ startupProbe: # -- Number of seconds after the container has started before liveness probes are initiated. initialDelaySeconds: 10 +# -- Additional volumeMounts to the controlplane main container +volumeMounts: [] + +# -- Additional volumes to the controlplane pod +volumes: [] + ## EDC endpoints exposed by the control-plane edc: endpoints: @@ -255,7 +264,7 @@ logging: # -- EDC logging.properties configuring the [java.util.logging subsystem](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.8) properties: |- .level=INFO - org.eclipse.dataspaceconnector.level=ALL + org.eclipse.edc.level=ALL handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.level=ALL @@ -268,7 +277,7 @@ opentelemetry: otel.javaagent.debug=false configuration: - # -- EDC configuration.properties configuring aspects of the [eclipse-dataspaceconnector](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector) + # -- EDC configuration.properties configuring aspects of the [eclipse-dataspaceconnector](https://github.com/eclipse-edc/Connector) properties: |- # edc.api.auth.key= # edc.atomikos.checkpoint.interval= diff --git a/charts/edc-dataplane/.helmignore b/charts/edc-dataplane/.helmignore index 148b31d6c..00ca644b2 100644 --- a/charts/edc-dataplane/.helmignore +++ b/charts/edc-dataplane/.helmignore @@ -23,7 +23,3 @@ .vscode/ README.md.gotmpl - -# Accept only values.yaml -values?*.yaml -values?*.yml diff --git a/charts/edc-dataplane/Chart.yaml b/charts/edc-dataplane/Chart.yaml index cb1a456fb..e6c5c00bf 100644 --- a/charts/edc-dataplane/Chart.yaml +++ b/charts/edc-dataplane/Chart.yaml @@ -27,8 +27,9 @@ description: >- EDC Data-Plane - The Eclipse DataSpaceConnector data layer with responsibility of transferring and receiving data streams home: https://github.com/eclipse-tractusx/tractusx-edc type: application -appVersion: "0.1.6" -version: 0.1.7 +appVersion: "0.3.0" +version: 0.3.0 +deprecated: true maintainers: [] sources: - https://github.com/eclipse-tractusx/tractusx-edc diff --git a/charts/edc-dataplane/LICENSE b/charts/edc-dataplane/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/charts/edc-dataplane/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://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. diff --git a/charts/edc-dataplane/README.md b/charts/edc-dataplane/README.md index 45ca25af0..da5f4afd3 100644 --- a/charts/edc-dataplane/README.md +++ b/charts/edc-dataplane/README.md @@ -1,15 +1,17 @@ # edc-dataplane -![Version: 0.1.6](https://img.shields.io/badge/Version-0.1.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.1.6](https://img.shields.io/badge/AppVersion-0.1.6-informational?style=flat-square) +> **:exclamation: This Helm Chart is deprecated!** + +![Version: 0.3.0](https://img.shields.io/badge/Version-0.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square) EDC Data-Plane - The Eclipse DataSpaceConnector data layer with responsibility of transferring and receiving data streams -- **Homepage:** +**Homepage:** ## TL;DR ```shell $ helm repo add tractusx-edc https://eclipse-tractusx.github.io/charts/dev -$ helm install my-release tractusx-edc/edc-dataplane --version 0.1.6 +$ helm install my-release tractusx-edc/edc-dataplane --version 0.3.0 ``` ## Values @@ -23,7 +25,8 @@ $ helm install my-release tractusx-edc/edc-dataplane --version 0.1.6 | autoscaling.minReplicas | int | `1` | Minimal replicas if resource consumption falls below resource threshholds | | autoscaling.targetCPUUtilizationPercentage | int | `80` | targetAverageUtilization of cpu provided to a pod | | autoscaling.targetMemoryUtilizationPercentage | int | `80` | targetAverageUtilization of memory provided to a pod | -| configuration.properties | string | `"# edc.atomikos.checkpoint.interval=\n# edc.atomikos.directory=\n# edc.atomikos.logging=\n# edc.atomikos.threaded2pc=\n# edc.atomikos.timeout=\n# edc.aws.access.key=\n# edc.aws.provision.retry.retries.max=\n# edc.aws.provision.role.duration.session.max=\n# edc.aws.secret.access.key=\n# edc.blobstore.endpoint=\n# edc.dataplane.token.validation.endpoint=\n# edc.core.retry.backoff.max=\n# edc.core.retry.backoff.min=\n# edc.core.retry.retries.max=\n# edc.core.system.health.check.liveness-period=\n# edc.core.system.health.check.readiness-period=\n# edc.core.system.health.check.startup-period=\n# edc.core.system.health.check.threadpool-size=\n# edc.dataplane.queue.capacity=\n# edc.dataplane.wait=\n# edc.dataplane.workers=\n# edc.datasource.asset.name=\"default\"\n# edc.datasource.contractdefinition.name=\"default\"\n# edc.datasource.contractnegotiation.name=\"default\"\n# edc.datasource.policy.name=\"default\"\n# edc.datasource.transferprocess.name=\"default\"\n# edc.datasource.default.pool.maxIdleConnections=\n# edc.datasource.default.pool.maxTotalConnections=\n# edc.datasource.default.pool.minIdleConnections=\n# edc.datasource.default.pool.testConnectionOnBorrow=\n# edc.datasource.default.pool.testConnectionOnCreate=\n# edc.datasource.default.pool.testConnectionOnReturn=\n# edc.datasource.default.pool.testConnectionWhileIdle=\n# edc.datasource.default.pool.testQuery=\n# edc.datasource.default.url=\n# edc.datasource.default.user=\n# edc.datasource.default.password=\n# edc.dpf.selector.url=\n# edc.events.topic.endpoint=\n# edc.events.topic.name=\n# edc.fs.config=\n# edc.hostname=\n# edc.identity.did.url=\n# edc.ids.catalog.id=\n# edc.ids.curator=\n# edc.ids.description=\n# edc.ids.endpoint=\n# edc.ids.endpoint.audience=\n# edc.ids.id=\n# edc.ids.maintainer=\n# edc.ids.security.profile=\n# edc.ids.title=\n# edc.ids.validation.referringconnector=\n# edc.ion.crawler.did-type=\n# edc.ion.crawler.interval-minutes=\n# edc.ion.crawler.ion.url=\n# edc.metrics.enabled=\n# edc.metrics.executor.enabled=\n# edc.metrics.jersey.enabled=\n# edc.metrics.jetty.enabled=\n# edc.metrics.okhttp.enabled=\n# edc.metrics.system.enabled=\n# edc.negotiation.consumer.state-machine.batch-size=\n# edc.negotiation.provider.state-machine.batch-size=\n# edc.oauth.client.id=\n# edc.oauth.private.key.alias=\n# edc.oauth.provider.jwks.refresh=\n# edc.oauth.provider.jwks.url=\n# edc.oauth.public.key.alias=\n# edc.oauth.token.url=\n# edc.oauth.validation.nbf.leeway=\n# edc.receiver.http.auth-code=\n# edc.receiver.http.auth-key=\n# edc.receiver.http.endpoint=\n# edc.transfer.functions.check.endpoint=\n# edc.transfer.functions.enabled.protocols=\n# edc.transfer.functions.transfer.endpoint=\n# edc.transfer-process-store.database.name=\n# edc.transfer.state-machine.batch-size=\n# edc.vault=\n# edc.vault.certificate=\n# edc.vault.clientid=\n# edc.vault.clientsecret=\n# edc.vault.name=\n# edc.vault.tenantid=\n# edc.vault.hashicorp.url=\n# edc.vault.hashicorp.token=\n# edc.vault.hashicorp.timeout.seconds=\n# edc.webdid.doh.url=\n# edc.web.rest.cors.enabled=\n# edc.web.rest.cors.headers=\n# edc.web.rest.cors.methods=\n# edc.web.rest.cors.origins="` | EDC configuration.properties configuring aspects of the [eclipse-dataspaceconnector](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector) | +| configuration.properties | string | `"# edc.atomikos.checkpoint.interval=\n# edc.atomikos.directory=\n# edc.atomikos.logging=\n# edc.atomikos.threaded2pc=\n# edc.atomikos.timeout=\n# edc.aws.access.key=\n# edc.aws.provision.retry.retries.max=\n# edc.aws.provision.role.duration.session.max=\n# edc.aws.secret.access.key=\n# edc.blobstore.endpoint=\n# edc.dataplane.token.validation.endpoint=\n# edc.core.retry.backoff.max=\n# edc.core.retry.backoff.min=\n# edc.core.retry.retries.max=\n# edc.core.system.health.check.liveness-period=\n# edc.core.system.health.check.readiness-period=\n# edc.core.system.health.check.startup-period=\n# edc.core.system.health.check.threadpool-size=\n# edc.dataplane.queue.capacity=\n# edc.dataplane.wait=\n# edc.dataplane.workers=\n# edc.datasource.asset.name=\"default\"\n# edc.datasource.contractdefinition.name=\"default\"\n# edc.datasource.contractnegotiation.name=\"default\"\n# edc.datasource.policy.name=\"default\"\n# edc.datasource.transferprocess.name=\"default\"\n# edc.datasource.default.pool.maxIdleConnections=\n# edc.datasource.default.pool.maxTotalConnections=\n# edc.datasource.default.pool.minIdleConnections=\n# edc.datasource.default.pool.testConnectionOnBorrow=\n# edc.datasource.default.pool.testConnectionOnCreate=\n# edc.datasource.default.pool.testConnectionOnReturn=\n# edc.datasource.default.pool.testConnectionWhileIdle=\n# edc.datasource.default.pool.testQuery=\n# edc.datasource.default.url=\n# edc.datasource.default.user=\n# edc.datasource.default.password=\n# edc.dpf.selector.url=\n# edc.events.topic.endpoint=\n# edc.events.topic.name=\n# edc.fs.config=\n# edc.hostname=\n# edc.identity.did.url=\n# edc.ids.catalog.id=\n# edc.ids.curator=\n# edc.ids.description=\n# edc.ids.endpoint=\n# edc.ids.endpoint.audience=\n# edc.ids.id=\n# edc.ids.maintainer=\n# edc.ids.security.profile=\n# edc.ids.title=\n# edc.ids.validation.referringconnector=\n# edc.ion.crawler.did-type=\n# edc.ion.crawler.interval-minutes=\n# edc.ion.crawler.ion.url=\n# edc.metrics.enabled=\n# edc.metrics.executor.enabled=\n# edc.metrics.jersey.enabled=\n# edc.metrics.jetty.enabled=\n# edc.metrics.okhttp.enabled=\n# edc.metrics.system.enabled=\n# edc.negotiation.consumer.state-machine.batch-size=\n# edc.negotiation.provider.state-machine.batch-size=\n# edc.oauth.client.id=\n# edc.oauth.private.key.alias=\n# edc.oauth.provider.jwks.refresh=\n# edc.oauth.provider.jwks.url=\n# edc.oauth.public.key.alias=\n# edc.oauth.token.url=\n# edc.oauth.validation.nbf.leeway=\n# edc.receiver.http.auth-code=\n# edc.receiver.http.auth-key=\n# edc.receiver.http.endpoint=\n# edc.transfer.functions.check.endpoint=\n# edc.transfer.functions.enabled.protocols=\n# edc.transfer.functions.transfer.endpoint=\n# edc.transfer-process-store.database.name=\n# edc.transfer.state-machine.batch-size=\n# edc.vault=\n# edc.vault.certificate=\n# edc.vault.clientid=\n# edc.vault.clientsecret=\n# edc.vault.name=\n# edc.vault.tenantid=\n# edc.vault.hashicorp.url=\n# edc.vault.hashicorp.token=\n# edc.vault.hashicorp.timeout.seconds=\n# edc.webdid.doh.url=\n# edc.web.rest.cors.enabled=\n# edc.web.rest.cors.headers=\n# edc.web.rest.cors.methods=\n# edc.web.rest.cors.origins="` | EDC configuration.properties configuring aspects of the [eclipse-dataspaceconnector](https://github.com/eclipse-edc/Connector) | +| customLabels | object | `{}` | Additional custom Labels to add | | edc.endpoints.control.path | string | `"/api/dataplane/control"` | The path mapping the "control" api is going to be exposed by | | edc.endpoints.control.port | string | `"9999"` | The network port, which the "control" api is going to be exposed by the container, pod and service | | edc.endpoints.default.path | string | `"/api"` | The path mapping the "default" api is going to be exposed by | @@ -36,7 +39,7 @@ $ helm install my-release tractusx-edc/edc-dataplane --version 0.1.6 | envSecretName | string | `nil` | [Kubernetes Secret Resource](https://kubernetes.io/docs/concepts/configuration/secret/) name to load environment variables from | | fullnameOverride | string | `""` | Overrides the releases full name | | image.pullPolicy | string | `"IfNotPresent"` | [Kubernetes image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) to use | -| image.repository | string | `"ghcr.io/eclipse-tractusx/tractusx-edc/edc-dataplane-hashicorp-vault"` | Which derivate of the edc data-plane to use. One of: [ghcr.io/eclipse-tractusx/tractusx-edc/edc-dataplane-hashicorp-vault, ghcr.io/eclipse-tractusx/tractusx-edc/edc-dataplane-azure-vault] | +| image.repository | string | `"ghcr.io/catenax-ng/product-edc/edc-dataplane-hashicorp-vault"` | Which derivate of the edc data-plane to use. One of: [ghcr.io/catenax-ng/product-edc/edc-dataplane-hashicorp-vault, ghcr.io/catenax-ng/product-edc/edc-dataplane-azure-vault] | | image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion | | imagePullSecret.dockerconfigjson | string | `""` | Image pull secret to create to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) Note: This value needs to adhere to the [(base64 encoded) .dockerconfigjson format](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials). Furthermore, if 'imagePullSecret.dockerconfigjson' is defined, it takes precedence over 'imagePullSecrets'. | | 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) | @@ -51,7 +54,7 @@ $ helm install my-release tractusx-edc/edc-dataplane --version 0.1.6 | ingresses[0].tls.enabled | bool | `false` | Enables TLS on the ingress resource | | ingresses[0].tls.secretName | string | `""` | If present overwrites the default secret name | | livenessProbe.enabled | bool | `true` | Whether to enable kubernetes [liveness-probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) | -| logging.properties | string | `".level=INFO\norg.eclipse.dataspaceconnector.level=ALL\nhandlers=java.util.logging.ConsoleHandler\njava.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter\njava.util.logging.ConsoleHandler.level=ALL\njava.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n"` | EDC logging.properties configuring the [java.util.logging subsystem](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.8) | +| logging.properties | string | `".level=INFO\norg.eclipse.edc.level=ALL\nhandlers=java.util.logging.ConsoleHandler\njava.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter\njava.util.logging.ConsoleHandler.level=ALL\njava.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n"` | EDC logging.properties configuring the [java.util.logging subsystem](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.8) | | nameOverride | string | `""` | Overrides the charts name | | nodeSelector | object | `{}` | [Node-Selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) to constrain the Pod to nodes with specific labels. | | opentelemetry.properties | string | `"otel.javaagent.enabled=true\notel.javaagent.debug=false"` | opentelemetry.properties configuring the [opentelemetry agent](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/) | diff --git a/charts/edc-dataplane/templates/_helpers.tpl b/charts/edc-dataplane/templates/_helpers.tpl index c6e3bc131..3615298cd 100644 --- a/charts/edc-dataplane/templates/_helpers.tpl +++ b/charts/edc-dataplane/templates/_helpers.tpl @@ -36,6 +36,7 @@ Common labels {{- define "edc-dataplane.labels" -}} helm.sh/chart: {{ include "edc-dataplane.chart" . }} {{ include "edc-dataplane.selectorLabels" . }} +{{ include "edc-dataplane.customLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} @@ -50,6 +51,15 @@ app.kubernetes.io/name: {{ include "edc-dataplane.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} +{{/* +Custom labels +*/}} +{{- define "edc-dataplane.customLabels" -}} +{{- with .Values.customLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + {{/* Create the name of the service account to use */}} diff --git a/charts/edc-dataplane/values.yaml b/charts/edc-dataplane/values.yaml index b9c2bcf29..926032306 100644 --- a/charts/edc-dataplane/values.yaml +++ b/charts/edc-dataplane/values.yaml @@ -31,8 +31,8 @@ replicaCount: 1 image: # -- Which derivate of the edc data-plane to use. - # One of: [ghcr.io/eclipse-tractusx/tractusx-edc/edc-dataplane-hashicorp-vault, ghcr.io/eclipse-tractusx/tractusx-edc/edc-dataplane-azure-vault] - repository: ghcr.io/eclipse-tractusx/tractusx-edc/edc-dataplane-hashicorp-vault + # One of: [ghcr.io/catenax-ng/product-edc/edc-dataplane-hashicorp-vault, ghcr.io/catenax-ng/product-edc/edc-dataplane-azure-vault] + repository: ghcr.io/catenax-ng/product-edc/edc-dataplane-hashicorp-vault # -- [Kubernetes image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) to use pullPolicy: IfNotPresent # -- Overrides the image tag whose default is the chart appVersion @@ -53,6 +53,9 @@ nameOverride: "" # -- Overrides the releases full name fullnameOverride: "" +# -- Additional custom Labels to add +customLabels: {} + serviceAccount: # -- Specifies whether a [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) should be created per release create: true @@ -218,7 +221,7 @@ logging: # -- EDC logging.properties configuring the [java.util.logging subsystem](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.8) properties: |- .level=INFO - org.eclipse.dataspaceconnector.level=ALL + org.eclipse.edc.level=ALL handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.level=ALL @@ -231,7 +234,7 @@ opentelemetry: otel.javaagent.debug=false configuration: - # -- EDC configuration.properties configuring aspects of the [eclipse-dataspaceconnector](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector) + # -- EDC configuration.properties configuring aspects of the [eclipse-dataspaceconnector](https://github.com/eclipse-edc/Connector) properties: |- # edc.atomikos.checkpoint.interval= # edc.atomikos.directory= diff --git a/charts/tractusx-connector/.helmignore b/charts/tractusx-connector/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/charts/tractusx-connector/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/tractusx-connector/Chart.yaml b/charts/tractusx-connector/Chart.yaml new file mode 100644 index 000000000..7057f1599 --- /dev/null +++ b/charts/tractusx-connector/Chart.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: v2 +name: tractusx-connector +description: A Helm chart for Tractus-X Eclipse Data Space Connector +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +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.3.0 +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.3.0" diff --git a/charts/tractusx-connector/README.md b/charts/tractusx-connector/README.md new file mode 100644 index 000000000..0624381bf --- /dev/null +++ b/charts/tractusx-connector/README.md @@ -0,0 +1,230 @@ +# tractusx-connector + +![Version: 0.3.0](https://img.shields.io/badge/Version-0.3.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square) + +A Helm chart for Tractus-X Eclipse Data Space Connector + +## TL;DR +```shell +$ helm repo add catenax-ng-product-edc https://catenax-ng.github.io/product-edc +$ helm install tractusx-connector catenax-ng-product-edc/tractusx-connector --version 0.3.0 +``` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| backendService.httpProxyTokenReceiverUrl | string | `""` | | +| controlplane.affinity | object | `{}` | | +| controlplane.autoscaling.enabled | bool | `false` | Enables [horizontal pod autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) | +| controlplane.autoscaling.maxReplicas | int | `100` | Maximum replicas if resource consumption exceeds resource threshholds | +| controlplane.autoscaling.minReplicas | int | `1` | Minimal replicas if resource consumption falls below resource threshholds | +| controlplane.autoscaling.targetCPUUtilizationPercentage | int | `80` | targetAverageUtilization of cpu provided to a pod | +| controlplane.autoscaling.targetMemoryUtilizationPercentage | int | `80` | targetAverageUtilization of memory provided to a pod | +| controlplane.debug.enabled | bool | `false` | | +| controlplane.debug.port | int | `1044` | | +| controlplane.debug.suspendOnStart | bool | `false` | | +| controlplane.endpoints | object | `{"control":{"path":"/control","port":8083},"data":{"authKey":"","path":"/data","port":8081},"default":{"path":"/api","port":8080},"ids":{"path":"/api/v1/ids","port":8084},"metrics":{"path":"/metrics","port":8085},"validation":{"path":"/validation","port":8082}}` | 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 | +| controlplane.endpoints.data | object | `{"authKey":"","path":"/data","port":8081}` | data management api, used by internal users, can be added to an ingress and must not be internet facing | +| controlplane.endpoints.data.authKey | string | `""` | authentication key, must be attached to each 'X-Api-Key' request header | +| controlplane.endpoints.data.path | string | `"/data"` | path for incoming api calls | +| controlplane.endpoints.data.port | int | `8081` | port for incoming api calls | +| controlplane.endpoints.default | object | `{"path":"/api","port":8080}` | default api for health checks, should not be added to any ingress | +| controlplane.endpoints.default.path | string | `"/api"` | path for incoming api calls | +| controlplane.endpoints.default.port | int | `8080` | port for incoming api calls | +| controlplane.endpoints.ids | object | `{"path":"/api/v1/ids","port":8084}` | ids api, used for inter connector communication and must be internet facing | +| controlplane.endpoints.ids.path | string | `"/api/v1/ids"` | path for incoming api calls | +| controlplane.endpoints.ids.port | int | `8084` | port for incoming api calls | +| controlplane.endpoints.metrics | object | `{"path":"/metrics","port":8085}` | metrics api, used for application metrics, must not be internet facing | +| controlplane.endpoints.metrics.path | string | `"/metrics"` | path for incoming api calls | +| controlplane.endpoints.metrics.port | int | `8085` | port for incoming api calls | +| controlplane.endpoints.validation | object | `{"path":"/validation","port":8082}` | validation api, only used by the data plane and should not be added to any ingress | +| controlplane.endpoints.validation.path | string | `"/validation"` | path for incoming api calls | +| controlplane.endpoints.validation.port | int | `8082` | port for incoming api calls | +| controlplane.env | object | `{}` | | +| controlplane.envConfigMapNames | list | `[]` | | +| controlplane.envSecretNames | list | `[]` | | +| controlplane.envValueFrom | object | `{}` | | +| controlplane.image.pullPolicy | string | `"IfNotPresent"` | [Kubernetes image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) to use | +| controlplane.image.repository | string | `""` | Which derivate of the control plane to use. when left empty the deployment will select the correct image automatically | +| controlplane.image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion | +| controlplane.ingresses[0].annotations | object | `{}` | Additional ingress annotations to add | +| controlplane.ingresses[0].certManager.clusterIssuer | string | `""` | If preset enables certificate generation via cert-manager cluster-wide issuer | +| controlplane.ingresses[0].certManager.issuer | string | `""` | If preset enables certificate generation via cert-manager namespace scoped issuer | +| controlplane.ingresses[0].className | string | `""` | Defines the [ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) to use | +| controlplane.ingresses[0].enabled | bool | `false` | | +| controlplane.ingresses[0].endpoints | list | `["ids"]` | EDC endpoints exposed by this ingress resource | +| controlplane.ingresses[0].hostname | string | `"edc-control.local"` | The hostname to be used to precisely map incoming traffic onto the underlying network service | +| controlplane.ingresses[0].tls | object | `{"enabled":false,"secretName":""}` | TLS [tls class](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) applied to the ingress resource | +| controlplane.ingresses[0].tls.enabled | bool | `false` | Enables TLS on the ingress resource | +| controlplane.ingresses[0].tls.secretName | string | `""` | If present overwrites the default secret name | +| controlplane.ingresses[1].annotations | object | `{}` | Additional ingress annotations to add | +| controlplane.ingresses[1].certManager.clusterIssuer | string | `""` | If preset enables certificate generation via cert-manager cluster-wide issuer | +| controlplane.ingresses[1].certManager.issuer | string | `""` | If preset enables certificate generation via cert-manager namespace scoped issuer | +| controlplane.ingresses[1].className | string | `""` | Defines the [ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) to use | +| controlplane.ingresses[1].enabled | bool | `false` | | +| controlplane.ingresses[1].endpoints | list | `["data","control"]` | EDC endpoints exposed by this ingress resource | +| controlplane.ingresses[1].hostname | string | `"edc-control.intranet"` | The hostname to be used to precisely map incoming traffic onto the underlying network service | +| controlplane.ingresses[1].tls | object | `{"enabled":false,"secretName":""}` | TLS [tls class](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) applied to the ingress resource | +| controlplane.ingresses[1].tls.enabled | bool | `false` | Enables TLS on the ingress resource | +| controlplane.ingresses[1].tls.secretName | string | `""` | If present overwrites the default secret name | +| controlplane.initContainers | list | `[]` | | +| controlplane.internationalDataSpaces.catalogId | string | `"TXDC-Catalog"` | | +| controlplane.internationalDataSpaces.curator | string | `""` | | +| controlplane.internationalDataSpaces.description | string | `"Tractus-X Eclipse IDS Data Space Connector"` | | +| controlplane.internationalDataSpaces.id | string | `"TXDC"` | | +| controlplane.internationalDataSpaces.maintainer | string | `""` | | +| controlplane.internationalDataSpaces.title | string | `""` | | +| controlplane.livenessProbe.enabled | bool | `true` | Whether to enable kubernetes [liveness-probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) | +| controlplane.livenessProbe.failureThreshold | int | `6` | when a probe fails kubernetes will try 6 times before giving up | +| controlplane.livenessProbe.initialDelaySeconds | int | `30` | seconds to wait before performing the first liveness check | +| controlplane.livenessProbe.periodSeconds | int | `10` | this fields specifies that kubernetes should perform a liveness check every 10 seconds | +| controlplane.livenessProbe.successThreshold | int | `1` | number of consecutive successes for the probe to be considered successful after having failed | +| controlplane.livenessProbe.timeoutSeconds | int | `5` | number of seconds after which the probe times out | +| controlplane.logging | string | `".level=INFO\nhandlers=java.util.logging.ConsoleHandler\njava.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter\njava.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n"` | configuration of the [Java Util Logging Facade](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html) | +| controlplane.nodeSelector | object | `{}` | | +| controlplane.opentelemetry | string | `"otel.javaagent.enabled=false\notel.javaagent.debug=false"` | configuration of the [Open Telemetry Agent](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/) to collect and expose metrics | +| controlplane.podAnnotations | object | `{}` | additional annotations for the pod | +| controlplane.podLabels | object | `{}` | additional labels for the pod | +| controlplane.podSecurityContext | object | `{"fsGroup":10001,"runAsGroup":10001,"runAsUser":10001,"seccompProfile":{"type":"RuntimeDefault"}}` | The [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) defines privilege and access control settings for a Pod within the deployment | +| controlplane.podSecurityContext.fsGroup | int | `10001` | The owner for volumes and any files created within volumes will belong to this guid | +| controlplane.podSecurityContext.runAsGroup | int | `10001` | Processes within a pod will belong to this guid | +| controlplane.podSecurityContext.runAsUser | int | `10001` | Runs all processes within a pod with a special uid | +| controlplane.podSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | Restrict a Container's Syscalls with seccomp | +| controlplane.readinessProbe.enabled | bool | `true` | Whether to enable kubernetes [readiness-probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) | +| controlplane.readinessProbe.failureThreshold | int | `6` | when a probe fails kubernetes will try 6 times before giving up | +| controlplane.readinessProbe.initialDelaySeconds | int | `30` | seconds to wait before performing the first readiness check | +| controlplane.readinessProbe.periodSeconds | int | `10` | this fields specifies that kubernetes should perform a readiness check every 10 seconds | +| controlplane.readinessProbe.successThreshold | int | `1` | number of consecutive successes for the probe to be considered successful after having failed | +| controlplane.readinessProbe.timeoutSeconds | int | `5` | number of seconds after which the probe times out | +| controlplane.replicaCount | int | `1` | | +| controlplane.resources | object | `{}` | [resource management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the container | +| controlplane.securityContext.allowPrivilegeEscalation | bool | `false` | Controls [Privilege Escalation](https://kubernetes.io/docs/concepts/security/pod-security-policy/#privilege-escalation) enabling setuid binaries changing the effective user ID | +| controlplane.securityContext.capabilities.add | list | `[]` | Specifies which capabilities to add to issue specialized syscalls | +| controlplane.securityContext.capabilities.drop | list | `["ALL"]` | Specifies which capabilities to drop to reduce syscall attack surface | +| controlplane.securityContext.readOnlyRootFilesystem | bool | `true` | Whether the root filesystem is mounted in read-only mode | +| controlplane.securityContext.runAsNonRoot | bool | `true` | Requires the container to run without root privileges | +| controlplane.securityContext.runAsUser | int | `10001` | The container's process will run with the specified uid | +| controlplane.service.annotations | object | `{}` | | +| controlplane.service.type | string | `"ClusterIP"` | [Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to expose the running application on a set of Pods as a network service. | +| controlplane.tolerations | list | `[]` | | +| controlplane.url.ids | string | `""` | Explicitly declared url for reaching the ids api (e.g. if ingresses not used) | +| controlplane.volumeMounts | list | `[]` | declare where to mount [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) into the container | +| controlplane.volumes | list | `[]` | [volume](https://kubernetes.io/docs/concepts/storage/volumes/) directories | +| customLabels | object | `{}` | | +| daps.clientId | string | `""` | | +| daps.paths.jwks | string | `"/jwks.json"` | | +| daps.paths.token | string | `"/token"` | | +| daps.url | string | `""` | | +| dataplane.affinity | object | `{}` | | +| dataplane.autoscaling.enabled | bool | `false` | Enables [horizontal pod autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) | +| dataplane.autoscaling.maxReplicas | int | `100` | Maximum replicas if resource consumption exceeds resource threshholds | +| dataplane.autoscaling.minReplicas | int | `1` | Minimal replicas if resource consumption falls below resource threshholds | +| dataplane.autoscaling.targetCPUUtilizationPercentage | int | `80` | targetAverageUtilization of cpu provided to a pod | +| dataplane.autoscaling.targetMemoryUtilizationPercentage | int | `80` | targetAverageUtilization of memory provided to a pod | +| dataplane.aws.accessKeyId | string | `""` | | +| dataplane.aws.endpointOverride | string | `""` | | +| dataplane.aws.secretAccessKey | string | `""` | | +| dataplane.debug.enabled | bool | `false` | | +| dataplane.debug.port | int | `1044` | | +| dataplane.debug.suspendOnStart | bool | `false` | | +| dataplane.endpoints.control.path | string | `"/api/dataplane/control"` | | +| dataplane.endpoints.control.port | int | `8083` | | +| dataplane.endpoints.default.path | string | `"/api"` | | +| dataplane.endpoints.default.port | int | `8080` | | +| dataplane.endpoints.metrics.path | string | `"/metrics"` | | +| dataplane.endpoints.metrics.port | int | `8084` | | +| dataplane.endpoints.public.path | string | `"/api/public"` | | +| dataplane.endpoints.public.port | int | `8081` | | +| dataplane.endpoints.validation.path | string | `"/validation"` | | +| dataplane.endpoints.validation.port | int | `8082` | | +| dataplane.env | object | `{}` | | +| dataplane.envConfigMapNames | list | `[]` | | +| dataplane.envSecretNames | list | `[]` | | +| dataplane.envValueFrom | object | `{}` | | +| dataplane.image.pullPolicy | string | `"IfNotPresent"` | [Kubernetes image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) to use | +| dataplane.image.repository | string | `""` | Which derivate of the data plane to use. when left empty the deployment will select the correct image automatically | +| dataplane.image.tag | string | `""` | Overrides the image tag whose default is the chart appVersion | +| dataplane.ingresses[0].annotations | object | `{}` | Additional ingress annotations to add | +| dataplane.ingresses[0].certManager.clusterIssuer | string | `""` | If preset enables certificate generation via cert-manager cluster-wide issuer | +| dataplane.ingresses[0].certManager.issuer | string | `""` | If preset enables certificate generation via cert-manager namespace scoped issuer | +| dataplane.ingresses[0].className | string | `""` | Defines the [ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) to use | +| dataplane.ingresses[0].enabled | bool | `false` | | +| dataplane.ingresses[0].endpoints | list | `["public"]` | EDC endpoints exposed by this ingress resource | +| dataplane.ingresses[0].hostname | string | `"edc-data.local"` | The hostname to be used to precisely map incoming traffic onto the underlying network service | +| dataplane.ingresses[0].tls | object | `{"enabled":false,"secretName":""}` | TLS [tls class](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) applied to the ingress resource | +| dataplane.ingresses[0].tls.enabled | bool | `false` | Enables TLS on the ingress resource | +| dataplane.ingresses[0].tls.secretName | string | `""` | If present overwrites the default secret name | +| dataplane.initContainers | list | `[]` | | +| dataplane.livenessProbe.enabled | bool | `true` | Whether to enable kubernetes [liveness-probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) | +| dataplane.livenessProbe.failureThreshold | int | `6` | when a probe fails kubernetes will try 6 times before giving up | +| dataplane.livenessProbe.initialDelaySeconds | int | `30` | seconds to wait before performing the first liveness check | +| dataplane.livenessProbe.periodSeconds | int | `10` | this fields specifies that kubernetes should perform a liveness check every 10 seconds | +| dataplane.livenessProbe.successThreshold | int | `1` | number of consecutive successes for the probe to be considered successful after having failed | +| dataplane.livenessProbe.timeoutSeconds | int | `5` | number of seconds after which the probe times out | +| dataplane.logging | string | `".level=INFO\nhandlers=java.util.logging.ConsoleHandler\njava.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter\njava.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n"` | configuration of the [Java Util Logging Facade](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html) | +| dataplane.nodeSelector | object | `{}` | | +| dataplane.opentelemetry | string | `"otel.javaagent.enabled=false\notel.javaagent.debug=false"` | configuration of the [Open Telemetry Agent](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/) to collect and expose metrics | +| dataplane.podAnnotations | object | `{}` | additional annotations for the pod | +| dataplane.podLabels | object | `{}` | additional labels for the pod | +| dataplane.podSecurityContext | object | `{"fsGroup":10001,"runAsGroup":10001,"runAsUser":10001,"seccompProfile":{"type":"RuntimeDefault"}}` | The [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) defines privilege and access control settings for a Pod within the deployment | +| dataplane.podSecurityContext.fsGroup | int | `10001` | The owner for volumes and any files created within volumes will belong to this guid | +| dataplane.podSecurityContext.runAsGroup | int | `10001` | Processes within a pod will belong to this guid | +| dataplane.podSecurityContext.runAsUser | int | `10001` | Runs all processes within a pod with a special uid | +| dataplane.podSecurityContext.seccompProfile.type | string | `"RuntimeDefault"` | Restrict a Container's Syscalls with seccomp | +| dataplane.readinessProbe.enabled | bool | `true` | Whether to enable kubernetes [readiness-probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) | +| dataplane.readinessProbe.failureThreshold | int | `6` | when a probe fails kubernetes will try 6 times before giving up | +| dataplane.readinessProbe.initialDelaySeconds | int | `30` | seconds to wait before performing the first readiness check | +| dataplane.readinessProbe.periodSeconds | int | `10` | this fields specifies that kubernetes should perform a liveness check every 10 seconds | +| dataplane.readinessProbe.successThreshold | int | `1` | number of consecutive successes for the probe to be considered successful after having failed | +| dataplane.readinessProbe.timeoutSeconds | int | `5` | number of seconds after which the probe times out | +| dataplane.replicaCount | int | `1` | | +| dataplane.resources | object | `{}` | [resource management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the container | +| dataplane.securityContext.allowPrivilegeEscalation | bool | `false` | Controls [Privilege Escalation](https://kubernetes.io/docs/concepts/security/pod-security-policy/#privilege-escalation) enabling setuid binaries changing the effective user ID | +| dataplane.securityContext.capabilities.add | list | `[]` | Specifies which capabilities to add to issue specialized syscalls | +| dataplane.securityContext.capabilities.drop | list | `["ALL"]` | Specifies which capabilities to drop to reduce syscall attack surface | +| dataplane.securityContext.readOnlyRootFilesystem | bool | `true` | Whether the root filesystem is mounted in read-only mode | +| dataplane.securityContext.runAsNonRoot | bool | `true` | Requires the container to run without root privileges | +| dataplane.securityContext.runAsUser | int | `10001` | The container's process will run with the specified uid | +| dataplane.service.port | int | `80` | | +| dataplane.service.type | string | `"ClusterIP"` | [Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to expose the running application on a set of Pods as a network service. | +| dataplane.tolerations | list | `[]` | | +| dataplane.url.public | string | `""` | Explicitly declared url for reaching the public api (e.g. if ingresses not used) | +| dataplane.volumeMounts | list | `[]` | declare where to mount [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) into the container | +| dataplane.volumes | list | `[]` | [volume](https://kubernetes.io/docs/concepts/storage/volumes/) directories | +| fullnameOverride | string | `""` | | +| imagePullSecrets | list | `[]` | Existing image pull secret to use to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) | +| nameOverride | string | `""` | | +| postgresql.enabled | bool | `false` | | +| postgresql.jdbcUrl | string | `""` | | +| postgresql.password | string | `""` | | +| postgresql.username | string | `""` | | +| serviceAccount.annotations | object | `{}` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.imagePullSecrets | list | `[]` | Existing image pull secret bound to the service account to use to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) | +| serviceAccount.name | string | `""` | | +| vault.azure.certificate | string | `""` | | +| vault.azure.client | string | `""` | | +| vault.azure.enabled | bool | `false` | | +| vault.azure.name | string | `""` | | +| vault.azure.secret | string | `""` | | +| vault.azure.tenant | string | `""` | | +| vault.hashicorp.enabled | bool | `false` | | +| vault.hashicorp.healthCheck.enabled | bool | `true` | | +| vault.hashicorp.healthCheck.standbyOk | bool | `true` | | +| vault.hashicorp.paths.health | string | `"/v1/sys/health"` | | +| vault.hashicorp.paths.secret | string | `"/v1/secret"` | | +| vault.hashicorp.timeout | int | `30` | | +| vault.hashicorp.token | string | `""` | | +| vault.hashicorp.url | string | `""` | | +| vault.secretNames.dapsPrivateKey | string | `"daps-private-key"` | | +| vault.secretNames.dapsPublicKey | string | `"daps-public-key"` | | +| vault.secretNames.transferProxyTokenEncryptionAesKey | string | `"transfer-proxy-token-encryption-aes-key"` | | +| vault.secretNames.transferProxyTokenSignerPrivateKey | string | `"transfer-proxy-token-signer-private-key"` | | +| vault.secretNames.transferProxyTokenSignerPublicKey | string | `"transfer-proxy-token-signer-public-key"` | | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.10.0](https://github.com/norwoodj/helm-docs/releases/v1.10.0) diff --git a/charts/tractusx-connector/README.md.gotmpl b/charts/tractusx-connector/README.md.gotmpl new file mode 100644 index 000000000..47ef15755 --- /dev/null +++ b/charts/tractusx-connector/README.md.gotmpl @@ -0,0 +1,25 @@ +{{ template "chart.header" . }} + +{{ template "chart.deprecationWarning" . }} + +{{ template "chart.badgesSection" . }} + +{{ template "chart.description" . }} + +{{ template "chart.homepageLine" . }} + +## TL;DR +```shell +$ helm repo add catenax-ng-product-edc https://catenax-ng.github.io/product-edc +$ helm install tractusx-connector catenax-ng-product-edc/tractusx-connector --version {{ .Version }} +``` + +{{ template "chart.maintainersSection" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +{{ template "helm-docs.versionFooter" . }} diff --git a/charts/tractusx-connector/templates/NOTES.txt b/charts/tractusx-connector/templates/NOTES.txt new file mode 100644 index 000000000..254cf9c67 --- /dev/null +++ b/charts/tractusx-connector/templates/NOTES.txt @@ -0,0 +1,45 @@ +1. Get the control plane URL by running these commands: +{{ with index .Values.controlplane.ingresses 0}} +{{- if .enabled }} +{{- range .paths }} + http{{ if .tls }}s{{ end }}://{{ .hostname }}{{ .path }} +{{- end }} +{{- else if contains "NodePort" $.Values.controlplane.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ $.Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "txdc.fullname" $ }}) + export NODE_IP=$(kubectl get nodes --namespace {{ $.Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" $.Values.controlplane.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "txdc.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "txdc.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ $.Values.controlplane.service.port }} +{{- else if contains "ClusterIP" $.Values.controlplane.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ $.Release.Namespace }} -l "app.kubernetes.io/name={{ include "txdc.name" $ }},app.kubernetes.io/instance={{ $.Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ $.Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ $.Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} +{{- end }} + +2. Get the data plane URL by running these commands: +{{ with index .Values.controlplane.ingresses 0}} +{{- if .enabled }} +{{- range .paths }} + http{{ if .tls }}s{{ end }}://{{ .hostname }}{{ .path }} +{{- end }} +{{- else if contains "NodePort" $.Values.dataplane.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ $.Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "txdc.fullname" $ }}) + export NODE_IP=$(kubectl get nodes --namespace {{ $.Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" $.Values.dataplane.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ $.Release.Namespace }} svc -w {{ include "txdc.fullname" $ }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "txdc.fullname" $ }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" $.Values.dataplane.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ $.Release.Namespace }} -l "app.kubernetes.io/name={{ include "txdc.name" $ }},app.kubernetes.io/instance={{ $.Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ $.Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ $.Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} +{{- end }} diff --git a/charts/tractusx-connector/templates/_helpers.tpl b/charts/tractusx-connector/templates/_helpers.tpl new file mode 100644 index 000000000..ecc8ff1d2 --- /dev/null +++ b/charts/tractusx-connector/templates/_helpers.tpl @@ -0,0 +1,175 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "txdc.name" -}} +{{- default .Chart.Name .Values.nameOverride | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "txdc.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "txdc.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Control Common labels +*/}} +{{- define "txdc.labels" -}} +helm.sh/chart: {{ include "txdc.chart" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Control Common labels +*/}} +{{- define "txdc.controlplane.labels" -}} +helm.sh/chart: {{ include "txdc.chart" . }} +{{ include "txdc.controlplane.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: edc-controlplane +app.kubernetes.io/part-of: edc +{{- end }} + +{{/* +Data Common labels +*/}} +{{- define "txdc.dataplane.labels" -}} +helm.sh/chart: {{ include "txdc.chart" . }} +{{ include "txdc.dataplane.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: edc-dataplane +app.kubernetes.io/part-of: edc +{{- end }} + +{{/* +Control Selector labels +*/}} +{{- define "txdc.controlplane.selectorLabels" -}} +app.kubernetes.io/name: {{ include "txdc.name" . }}-controlplane +app.kubernetes.io/instance: {{ .Release.Name }}-controlplane +{{- end }} + +{{/* +Data Selector labels +*/}} +{{- define "txdc.dataplane.selectorLabels" -}} +app.kubernetes.io/name: {{ include "txdc.name" . }}-dataplane +app.kubernetes.io/instance: {{ .Release.Name }}-dataplane +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "txdc.controlplane.serviceaccount.name" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "txdc.fullname" . ) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "txdc.dataplane.serviceaccount.name" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "txdc.fullname" . ) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Control IDS URL +*/}} +{{- define "txdc.controlplane.url.ids" -}} +{{- if .Values.controlplane.url.ids }}{{/* if ids api url has been specified explicitly */}} +{{- .Values.controlplane.url.ids }} +{{- else }}{{/* else when ids api url has not been specified explicitly */}} +{{- with (index .Values.controlplane.ingresses 0) }} +{{- if .enabled }}{{/* if ingress enabled */}} +{{- if .tls.enabled }}{{/* if TLS enabled */}} +{{- printf "https://%s" .hostname -}} +{{- else }}{{/* else when TLS not enabled */}} +{{- printf "http://%s" .hostname -}} +{{- end }}{{/* end if tls */}} +{{- else }}{{/* else when ingress not enabled */}} +{{- printf "http://%s-controlplane:%v" ( include "txdc.fullname" $ ) $.Values.controlplane.endpoints.ids.port -}} +{{- end }}{{/* end if ingress */}} +{{- end }}{{/* end with ingress */}} +{{- end }}{{/* end if .Values.controlplane.url.ids */}} +{{- end }} + +{{/* +Validation URL +*/}} +{{- define "txdc.controlplane.url.validation" -}} +{{- printf "http://%s-controlplane:%v%s/token" ( include "txdc.fullname" $ ) $.Values.controlplane.endpoints.validation.port $.Values.controlplane.endpoints.validation.path -}} +{{- end }} + +{{/* +Data Control URL +*/}} +{{- define "txdc.dataplane.url.control" -}} +{{- printf "http://%s-dataplane:%v%s" (include "txdc.fullname" . ) .Values.dataplane.endpoints.control.port .Values.dataplane.endpoints.control.path -}} +{{- end }} + +{{/* +Data Public URL +*/}} +{{- define "txdc.dataplane.url.public" -}} +{{- if .Values.dataplane.url.public }}{{/* if public api url has been specified explicitly */}} +{{- .Values.dataplane.url.public }} +{{- else }}{{/* else when public api url has not been specified explicitly */}} +{{- with (index .Values.dataplane.ingresses 0) }} +{{- if .enabled }}{{/* if ingress enabled */}} +{{- if .tls.enabled }}{{/* if TLS enabled */}} +{{- printf "https://%s%s" .hostname $.Values.dataplane.endpoints.public.path -}} +{{- else }}{{/* else when TLS not enabled */}} +{{- printf "http://%s%s" .hostname $.Values.dataplane.endpoints.public.path -}} +{{- end }}{{/* end if tls */}} +{{- else }}{{/* else when ingress not enabled */}} +{{- printf "http://%s-dataplane:%v%s" (include "txdc.fullname" $ ) $.Values.dataplane.endpoints.public.port $.Values.dataplane.endpoints.public.path -}} +{{- end }}{{/* end if ingress */}} +{{- end }}{{/* end with ingress */}} +{{- end }}{{/* end if .Values.dataplane.url.public */}} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "txdc.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "txdc.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/tractusx-connector/templates/configmap-controlplane.yaml b/charts/tractusx-connector/templates/configmap-controlplane.yaml new file mode 100644 index 000000000..493426aa2 --- /dev/null +++ b/charts/tractusx-connector/templates/configmap-controlplane.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "txdc.fullname" . }}-controlplane + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "txdc.controlplane.labels" . | nindent 4 }} +data: + opentelemetry.properties: |- + {{- .Values.controlplane.opentelemetry | nindent 4 }} + + logging.properties: |- + {{- .Values.controlplane.logging | nindent 4 }} diff --git a/charts/tractusx-connector/templates/configmap-dataplane.yaml b/charts/tractusx-connector/templates/configmap-dataplane.yaml new file mode 100644 index 000000000..4f4c1a456 --- /dev/null +++ b/charts/tractusx-connector/templates/configmap-dataplane.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "txdc.fullname" . }}-dataplane + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "txdc.dataplane.labels" . | nindent 4 }} +data: + opentelemetry.properties: |- + {{- .Values.dataplane.opentelemetry | nindent 4 }} + + logging.properties: |- + {{- .Values.dataplane.logging | nindent 4 }} diff --git a/charts/tractusx-connector/templates/deployment-controlplane.yaml b/charts/tractusx-connector/templates/deployment-controlplane.yaml new file mode 100644 index 000000000..0d0b9c157 --- /dev/null +++ b/charts/tractusx-connector/templates/deployment-controlplane.yaml @@ -0,0 +1,365 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "txdc.fullname" . }}-controlplane + labels: + {{- include "txdc.controlplane.labels" . | nindent 4 }} +spec: + {{- if not .Values.controlplane.autoscaling.enabled }} + replicas: {{ .Values.controlplane.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "txdc.controlplane.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.controlplane.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "txdc.controlplane.selectorLabels" . | nindent 8 }} + {{- with .Values.controlplane.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "txdc.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.controlplane.podSecurityContext | nindent 8 }} + initContainers: + {{- toYaml .Values.controlplane.initContainers | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.controlplane.securityContext | nindent 12 }} + {{- if .Values.controlplane.image.repository }} + image: "{{ .Values.controlplane.image.repository }}:{{ .Values.controlplane.image.tag | default .Chart.AppVersion }}" + {{- else if and .Values.postgresql.enabled .Values.vault.hashicorp.enabled }} + image: "ghcr.io/catenax-ng/product-edc/edc-controlplane-postgresql-hashicorp-vault:{{ .Values.controlplane.image.tag | default .Chart.AppVersion }}" + {{- else if and .Values.postgresql.enabled .Values.vault.azure.enabled }} + image: "ghcr.io/catenax-ng/product-edc/edc-controlplane-postgresql-vault:{{ .Values.controlplane.image.tag | default .Chart.AppVersion }}" + {{- else if .Values.vault.hashicorp.enabled }} + image: "ghcr.io/catenax-ng/product-edc/edc-controlplane-memory-hashicorp-vault:{{ .Values.controlplane.image.tag | default .Chart.AppVersion }}" + {{- else if .Values.vault.azure.enabled }} + image: "ghcr.io/catenax-ng/product-edc/edc-controlplane-memory:{{ .Values.controlplane.image.tag | default .Chart.AppVersion }}" + {{- else }} + {{- fail "cannot choose control-plane image automatically based on configuration" }} + {{- end }} + imagePullPolicy: {{ .Values.controlplane.image.pullPolicy }} + ports: + {{- range $key,$value := .Values.controlplane.endpoints }} + - name: {{ $key }} + containerPort: {{ $value.port }} + protocol: TCP + {{- end }} + {{- if .Values.controlplane.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.controlplane.endpoints.default.path }}/check/liveness + port: {{ .Values.controlplane.endpoints.default.port }} + initialDelaySeconds: {{ .Values.controlplane.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.controlplane.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.controlplane.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.controlplane.livenessProbe.failureThreshold }} + successThreshold: {{ .Values.controlplane.livenessProbe.successThreshold }} + {{- end }} + {{- if .Values.controlplane.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.controlplane.endpoints.default.path }}/check/readiness + port: {{ .Values.controlplane.endpoints.default.port }} + initialDelaySeconds: {{ .Values.controlplane.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.controlplane.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.controlplane.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.controlplane.readinessProbe.failureThreshold }} + successThreshold: {{ .Values.controlplane.readinessProbe.successThreshold }} + {{- end }} + resources: + {{- toYaml .Values.controlplane.resources | nindent 12 }} + env: + {{- if .Values.controlplane.debug.enabled }} + - name: "JAVA_TOOL_OPTIONS" + {{- if and .Values.controlplane.debug.enabled .Values.controlplane.debug.suspendOnStart }} + value: >- + {{ printf "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=%v" .Values.controlplane.debug.port }} + {{- else }} + value: >- + {{ printf "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=%v" .Values.controlplane.debug.port }} + {{- end }} + {{- end }} + + ######################## + ## DAPS CONFIGURATION ## + ######################## + + # see extension https://github.com/eclipse-edc/Connector/tree/main/extensions/iam/oauth2/oauth2-core + - name: EDC_OAUTH_CLIENT_ID + value: {{ .Values.daps.clientId | required ".Values.daps.clientId is required" | quote }} + - name: EDC_OAUTH_PROVIDER_JWKS_URL + value: {{ printf "%s%s" .Values.daps.url .Values.daps.paths.jwks }} + - name: EDC_OAUTH_TOKEN_URL + value: {{ printf "%s%s" .Values.daps.url .Values.daps.paths.token }} + - name: EDC_OAUTH_PRIVATE_KEY_ALIAS + value: {{ .Values.vault.secretNames.dapsPrivateKey | required ".Values.vault.secretNames.dapsPrivateKey is required" | quote }} + - name: EDC_OAUTH_PUBLIC_KEY_ALIAS + value: {{ .Values.vault.secretNames.dapsPublicKey | required ".Values.vault.secretNames.dapsPublicKey is required" | quote }} + + ####### + # API # + ####### + - name: "EDC_API_AUTH_KEY" + value: {{ .Values.controlplane.endpoints.data.authKey | required ".Values.controlplane.endpoints.data.authKey is required" | quote }} + - name: "WEB_HTTP_DEFAULT_PORT" + value: {{ .Values.controlplane.endpoints.default.port | quote }} + - name: "WEB_HTTP_DEFAULT_PATH" + value: {{ .Values.controlplane.endpoints.default.path | quote }} + {{- if or (eq (substr 0 3 .Values.controlplane.image.tag) "0.1") (eq (substr 0 3 .Values.controlplane.image.tag) "0.2") }} + # WEB_HTTP_DATA_PORT is renamed to WEB_HTTP_MANAGEMENT_PORT from version 0.2.1 and newer + # we will keep both settings for downward capabilities + - name: "WEB_HTTP_DATA_PORT" + value: {{ .Values.controlplane.endpoints.data.port | quote }} + # WEB_HTTP_DATA_PATH is renamed to WEB_HTTP_MANAGEMENT_PATH from version 0.2.1 and newer + # we will keep both settings for downward capabilities + - name: "WEB_HTTP_DATA_PATH" + value: {{ .Values.controlplane.endpoints.data.path | quote }} + {{- else }} + - name: "WEB_HTTP_MANAGEMENT_PORT" + value: {{ .Values.controlplane.endpoints.data.port | quote }} + - name: "WEB_HTTP_MANAGEMENT_PATH" + value: {{ .Values.controlplane.endpoints.data.path | quote }} + {{- end }} + - name: "WEB_HTTP_VALIDATION_PORT" + value: {{ .Values.controlplane.endpoints.validation.port | quote }} + - name: "WEB_HTTP_VALIDATION_PATH" + value: {{ .Values.controlplane.endpoints.validation.path | quote }} + - name: "WEB_HTTP_CONTROL_PORT" + value: {{ .Values.controlplane.endpoints.control.port | quote }} + - name: "WEB_HTTP_CONTROL_PATH" + value: {{ .Values.controlplane.endpoints.control.path | quote }} + - name: "WEB_HTTP_IDS_PORT" + value: {{ .Values.controlplane.endpoints.ids.port | quote }} + - name: "WEB_HTTP_IDS_PATH" + value: {{ .Values.controlplane.endpoints.ids.path | quote }} + + ######### + ## IDS ## + ######### + - name: "IDS_WEBHOOK_ADDRESS" + value: {{ include "txdc.controlplane.url.ids" . | quote }} + - name: "EDC_IDS_ENDPOINT" + value: {{ printf "%s%s" (include "txdc.controlplane.url.ids" .) .Values.controlplane.endpoints.ids.path | quote }} + - name: "EDC_IDS_ID" + value: {{ printf "urn:connector:%s" (lower .Values.controlplane.internationalDataSpaces.id) | quote }} + - name: "EDC_IDS_DESCRIPTION" + value: {{ .Values.controlplane.internationalDataSpaces.description | quote }} + - name: "EDC_IDS_TITLE" + value: {{ .Values.controlplane.internationalDataSpaces.title | quote }} + - name: "EDC_IDS_MAINTAINER" + value: {{ .Values.controlplane.internationalDataSpaces.maintainer | quote }} + - name: "EDC_IDS_CURATOR" + value: {{ .Values.controlplane.internationalDataSpaces.curator | quote }} + - name: "EDC_IDS_CATALOG_ID" + value: {{ printf "urn:catalog:%s" (lower .Values.controlplane.internationalDataSpaces.catalogId) | quote }} + - name: "EDC_OAUTH_PROVIDER_AUDIENCE" + value: "idsc:IDS_CONNECTORS_ALL" + - name: "EDC_OAUTH_ENDPOINT_AUDIENCE" + value: {{ printf "%s%s%s" (include "txdc.controlplane.url.ids" . ) .Values.controlplane.endpoints.ids.path "/data" | quote }} + # this is the old setting name for 'EDC_OAUTH_ENDPOINT_AUDIENCE' and is mandatory for Produce EDC v0.1.2 and older + - name: "EDC_IDS_ENDPOINT_AUDIENCE" + value: {{ printf "%s%s%s" (include "txdc.controlplane.url.ids" . ) .Values.controlplane.endpoints.ids.path "/data" | quote }} + + {{- if .Values.postgresql.enabled }} + + ################ + ## POSTGRESQL ## + ################ + + # see extension https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/store/sql/asset-index-sql + - name: "EDC_DATASOURCE_ASSET_NAME" + value: "asset" + - name: "EDC_DATASOURCE_ASSET_USER" + value: {{ .Values.postgresql.username | required ".Values.postgresql.username is required" | quote }} + - name: "EDC_DATASOURCE_ASSET_PASSWORD" + value: {{ .Values.postgresql.password | required ".Values.postgresql.password is required" | quote }} + - name: "EDC_DATASOURCE_ASSET_URL" + value: {{ .Values.postgresql.jdbcUrl | required ".Values.postgresql.jdbcUrl is required" | quote }} + + # see extension https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/store/sql/contract-definition-store-sql + - name: "EDC_DATASOURCE_CONTRACTDEFINITION_NAME" + value: "contractdefinition" + - name: "EDC_DATASOURCE_CONTRACTDEFINITION_USER" + value: {{ .Values.postgresql.username | required ".Values.postgresql.username is required" | quote }} + - name: "EDC_DATASOURCE_CONTRACTDEFINITION_PASSWORD" + value: {{ .Values.postgresql.password | required ".Values.postgresql.password is required" | quote }} + - name: "EDC_DATASOURCE_CONTRACTDEFINITION_URL" + value: {{ .Values.postgresql.jdbcUrl | required ".Values.postgresql.jdbcUrl is required" | quote }} + + # see extension https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/store/sql/contract-negotiation-store-sql + - name: "EDC_DATASOURCE_CONTRACTNEGOTIATION_NAME" + value: "contractnegotiation" + - name: "EDC_DATASOURCE_CONTRACTNEGOTIATION_USER" + value: {{ .Values.postgresql.username | required ".Values.postgresql.username is required" | quote }} + - name: "EDC_DATASOURCE_CONTRACTNEGOTIATION_PASSWORD" + value: {{ .Values.postgresql.password | required ".Values.postgresql.password is required" | quote }} + - name: "EDC_DATASOURCE_CONTRACTNEGOTIATION_URL" + value: {{ .Values.postgresql.jdbcUrl | required ".Values.postgresql.jdbcUrl is required" | quote }} + + # see extension https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/store/sql/policy-store-sql + - name: "EDC_DATASOURCE_POLICY_NAME" + value: "policy" + - name: "EDC_DATASOURCE_POLICY_USER" + value: {{ .Values.postgresql.username | required ".Values.postgresql.username is required" | quote }} + - name: "EDC_DATASOURCE_POLICY_PASSWORD" + value: {{ .Values.postgresql.password | required ".Values.postgresql.password is required" | quote }} + - name: "EDC_DATASOURCE_POLICY_URL" + value: {{ .Values.postgresql.jdbcUrl | required ".Values.postgresql.jdbcUrl is required" | quote }} + + # see extension https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/store/sql/transfer-process-store-sql + - name: "EDC_DATASOURCE_TRANSFERPROCESS_NAME" + value: "transferprocess" + - name: "EDC_DATASOURCE_TRANSFERPROCESS_USER" + value: {{ .Values.postgresql.username | required ".Values.postgresql.username is required" | quote }} + - name: "EDC_DATASOURCE_TRANSFERPROCESS_PASSWORD" + value: {{ .Values.postgresql.password | required ".Values.postgresql.password is required" | quote }} + - name: "EDC_DATASOURCE_TRANSFERPROCESS_URL" + value: {{ .Values.postgresql.jdbcUrl | required ".Values.postgresql.jdbcUrl is required" | quote }} + {{- end }} + + ################ + ## DATA PLANE ## + ################ + + # see extension https://github.com/catenax-ng/product-edc/tree/develop/edc-extensions/dataplane-selector-configuration + - name: "EDC_DATAPLANE_SELECTOR_DEFAULTPLANE_URL" + value: {{ include "txdc.dataplane.url.control" . }}/transfer + - name: "EDC_DATAPLANE_SELECTOR_DEFAULTPLANE_SOURCETYPES" + value: "HttpData,AmazonS3" + - name: "EDC_DATAPLANE_SELECTOR_DEFAULTPLANE_DESTINATIONTYPES" + value: "HttpProxy,AmazonS3" + - name: "EDC_DATAPLANE_SELECTOR_DEFAULTPLANE_PROPERTIES" + value: |- + {{ printf "{ \"publicApiUrl\": \"%s\" }" (include "txdc.dataplane.url.public" . ) }} + + # see extension https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/data-plane-transfer + - name: "EDC_TRANSFER_PROXY_ENDPOINT" + value: {{ include "txdc.dataplane.url.public" . }} + - name: "EDC_TRANSFER_PROXY_TOKEN_SIGNER_PRIVATEKEY_ALIAS" + value: {{ .Values.vault.secretNames.transferProxyTokenSignerPrivateKey | quote }} + - name: "EDC_TRANSFER_PROXY_TOKEN_VERIFIER_PUBLICKEY_ALIAS" + value: {{ .Values.vault.secretNames.transferProxyTokenSignerPublicKey | quote }} + + # see extension https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/http-receiver + + - name: "EDC_RECEIVER_HTTP_ENDPOINT" + value: {{ .Values.backendService.httpProxyTokenReceiverUrl | required ".Values.backendService.httpProxyTokenReceiverUrl is required" | quote }} + + ########### + ## VAULT ## + ########### + + {{- if .Values.vault.hashicorp.enabled }} + # see extension https://github.com/catenax-ng/product-edc/tree/develop/edc-extensions/hashicorp-vault + - name: "EDC_VAULT_HASHICORP_URL" + value: {{ .Values.vault.hashicorp.url | required ".Values.vault.hashicorp.url is required" | quote }} + - name: "EDC_VAULT_HASHICORP_TOKEN" + value: {{ .Values.vault.hashicorp.token | required ".Values.vault.hashicorp.token is required" | quote }} + - name: "EDC_VAULT_HASHICORP_TIMEOUT_SECONDS" + value: {{ .Values.vault.hashicorp.timeout | quote }} + - name: "EDC_VAULT_HASHICORP_HEALTH_CHECK_ENABLED" + value: {{ .Values.vault.hashicorp.healthCheck.enabled | quote }} + - name: "EDC_VAULT_HASHICORP_HEALTH_CHECK_STANDBY_OK" + value: {{ .Values.vault.hashicorp.healthCheck.standbyOk | quote }} + - name: "EDC_VAULT_HASHICORP_API_SECRET_PATH" + value: {{ .Values.vault.hashicorp.paths.secret | quote }} + - name: "EDC_VAULT_HASHICORP_API_HEALTH_CHECK_PATH" + value: {{ .Values.vault.hashicorp.paths.health | quote }} + {{- end }} + + {{- if .Values.vault.azure.enabled }} + - name: "EDC_VAULT_CLIENTID" + value: {{ .Values.vault.azure.client | required ".Values.vault.azure.client is required" | quote }} + - name: "EDC_VAULT_TENANTID" + value: {{ .Values.vault.azure.tenant | required ".Values.vault.azure.tenant is required" | quote }} + - name: "EDC_VAULT_NAME" + value: {{ .Values.vault.azure.name | required ".Values.vault.azure.name is required" | quote }} + - name: "EDC_VAULT_CLIENTSECRET" + value: {{ .Values.vault.azure.secret | quote }} + - name: "EDC_VAULT_CERTIFICATE" + value: {{ .Values.vault.azure.certificate | quote }} + {{- end }} + + ##################### + + ## DATA ENCRYPTION ## + ##################### + + # see extension https://github.com/catenax-ng/product-edc/tree/develop/edc-extensions/data-encryption + - name: "EDC_DATA_ENCRYPTION_KEYS_ALIAS" + value: {{ .Values.vault.secretNames.transferProxyTokenEncryptionAesKey | quote }} + - name: "EDC_DATA_ENCRYPTION_ALGORITHM" + value: "AES" + + ########################### + ## AAS WRAPPER EXTENSION ## + ########################### + - name: "EDC_CP_ADAPTER_CACHE_CATALOG_EXPIRE_AFTER" + value: "0" + - name: "EDC_CP_ADAPTER_REUSE_CONTRACT_AGREEMENT" + value: "0" + + ###################################### + ## Additional environment variables ## + ###################################### + {{- range $key, $value := .Values.controlplane.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 16 }} + {{- end }} + {{- range $key, $value := .Values.controlplane.env }} + - name: {{ $key | quote }} + value: {{ $value | quote }} + {{- end }} + {{- if and (or .Values.controlplane.envSecretNames .Values.controlplane.envConfigMapNames) (or (gt (len .Values.controlplane.envSecretNames) 0) (gt (len .Values.controlplane.envConfigMapNames) 0)) }} + envFrom: + {{- range $value := .Values.controlplane.envSecretNames }} + - secretRef: + name: {{ $value | quote }} + {{- end }} + {{- range $value := .Values.controlplane.envConfigMapNames }} + - configMapRef: + name: {{ $value | quote }} + {{- end }} + {{- end }} + volumeMounts: + - name: "configuration" + mountPath: "/app/opentelemetry.properties" + subPath: "opentelemetry.properties" + - name: "configuration" + mountPath: "/app/logging.properties" + subPath: "logging.properties" + volumes: + - name: "configuration" + configMap: + name: {{ include "txdc.fullname" . }}-controlplane + items: + - key: "opentelemetry.properties" + path: "opentelemetry.properties" + - key: "logging.properties" + path: "logging.properties" + {{- with .Values.controlplane.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controlplane.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controlplane.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/tractusx-connector/templates/deployment-dataplane.yaml b/charts/tractusx-connector/templates/deployment-dataplane.yaml new file mode 100644 index 000000000..cafb50909 --- /dev/null +++ b/charts/tractusx-connector/templates/deployment-dataplane.yaml @@ -0,0 +1,215 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "txdc.fullname" . }}-dataplane + labels: + {{- include "txdc.dataplane.labels" . | nindent 4 }} +spec: + {{- if not .Values.dataplane.autoscaling.enabled }} + replicas: {{ .Values.dataplane.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "txdc.dataplane.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.dataplane.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "txdc.dataplane.selectorLabels" . | nindent 8 }} + {{- with .Values.dataplane.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "txdc.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.dataplane.podSecurityContext | nindent 8 }} + initContainers: + {{- toYaml .Values.dataplane.initContainers | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.dataplane.securityContext | nindent 12 }} + {{- if .Values.dataplane.image.repository }} + image: "{{ .Values.dataplane.image.repository }}:{{ .Values.dataplane.image.tag | default .Chart.AppVersion }}" + {{- else if and .Values.vault.hashicorp }} + image: "ghcr.io/catenax-ng/product-edc/edc-dataplane-hashicorp-vault:{{ .Values.dataplane.image.tag | default .Chart.AppVersion }}" + {{- else if .Values.vault.azure }} + image: "ghcr.io/catenax-ng/product-edc/edc-dataplane-azure-vault:{{ .Values.dataplane.image.tag | default .Chart.AppVersion }}" + {{- else }} + {{- fail "cannot choose data-plane image automatically based on configuration" }} + {{- end }} + imagePullPolicy: {{ .Values.dataplane.image.pullPolicy }} + ports: + {{- range $key,$value := .Values.dataplane.endpoints }} + - name: {{ $key }} + containerPort: {{ $value.port }} + protocol: TCP + {{- end }} + {{- if .Values.dataplane.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.dataplane.endpoints.default.path }}/check/liveness + port: {{ .Values.dataplane.endpoints.default.port }} + initialDelaySeconds: {{ .Values.dataplane.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.dataplane.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.dataplane.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.dataplane.livenessProbe.failureThreshold }} + successThreshold: {{ .Values.dataplane.livenessProbe.successThreshold }} + {{- end }} + {{- if .Values.dataplane.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.dataplane.endpoints.default.path }}/check/readiness + port: {{ .Values.dataplane.endpoints.default.port }} + initialDelaySeconds: {{ .Values.dataplane.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.dataplane.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.dataplane.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.dataplane.readinessProbe.failureThreshold }} + successThreshold: {{ .Values.dataplane.readinessProbe.successThreshold }} + {{- end }} + resources: + {{- toYaml .Values.dataplane.resources | nindent 12 }} + env: + {{- if .Values.dataplane.debug.enabled }} + - name: "JAVA_TOOL_OPTIONS" + {{- if and .Values.dataplane.debug.enabled .Values.dataplane.debug.suspendOnStart }} + value: >- + {{ printf "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=%v" .Values.dataplane.debug.port }} + {{- else }} + value: >- + {{ printf "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=%v" .Values.dataplane.debug.port }} + {{- end }} + {{- end }} + + ####### + # API # + ####### + - name: "WEB_HTTP_DEFAULT_PORT" + value: {{ .Values.dataplane.endpoints.default.port | quote }} + - name: "WEB_HTTP_DEFAULT_PATH" + value: {{ .Values.dataplane.endpoints.default.path | quote }} + - name: "WEB_HTTP_CONTROL_PORT" + value: {{ .Values.dataplane.endpoints.control.port | quote }} + - name: "WEB_HTTP_CONTROL_PATH" + value: {{ .Values.dataplane.endpoints.control.path | quote }} + - name: "WEB_HTTP_VALIDATION_PORT" + value: {{ .Values.dataplane.endpoints.validation.port | quote }} + - name: "WEB_HTTP_VALIDATION_PATH" + value: {{ .Values.dataplane.endpoints.validation.path | quote }} + - name: "WEB_HTTP_PUBLIC_PORT" + value: {{ .Values.dataplane.endpoints.public.port | quote }} + - name: "WEB_HTTP_PUBLIC_PATH" + value: {{ .Values.dataplane.endpoints.public.path | quote }} + - name: "EDC_DATAPLANE_TOKEN_VALIDATION_ENDPOINT" + value: {{ include "txdc.controlplane.url.validation" .}} + + ####### + # AWS # + ####### + {{- if .Values.dataplane.aws.endpointOverride }} + - name: "EDC_AWS_ENDPOINT_OVERRIDE" + value: {{ .Values.dataplane.aws.endpointOverride | quote }} + {{- end }} + {{- if .Values.dataplane.aws.secretAccessKey }} + - name: "AWS_SECRET_ACCESS_KEY" + value: {{ .Values.dataplane.aws.secretAccessKey | quote }} + {{- end }} + {{- if .Values.dataplane.aws.accessKeyId }} + - name: "AWS_ACCESS_KEY_ID" + value: {{ .Values.dataplane.aws.accessKeyId | quote }} + {{- end }} + + ########### + ## VAULT ## + ########### + + {{- if .Values.vault.hashicorp.enabled }} + # see extension https://github.com/catenax-ng/product-edc/tree/develop/edc-extensions/hashicorp-vault + - name: "EDC_VAULT_HASHICORP_URL" + value: {{ .Values.vault.hashicorp.url | required ".Values.vault.hashicorp.url is required" | quote }} + - name: "EDC_VAULT_HASHICORP_TOKEN" + value: {{ .Values.vault.hashicorp.token | required ".Values.vault.hashicorp.token is required" | quote }} + - name: "EDC_VAULT_HASHICORP_TIMEOUT_SECONDS" + value: {{ .Values.vault.hashicorp.timeout | quote }} + - name: "EDC_VAULT_HASHICORP_HEALTH_CHECK_ENABLED" + value: {{ .Values.vault.hashicorp.healthCheck.enabled | quote }} + - name: "EDC_VAULT_HASHICORP_HEALTH_CHECK_STANDBY_OK" + value: {{ .Values.vault.hashicorp.healthCheck.standbyOk | quote }} + - name: "EDC_VAULT_HASHICORP_API_SECRET_PATH" + value: {{ .Values.vault.hashicorp.paths.secret | quote }} + - name: "EDC_VAULT_HASHICORP_API_HEALTH_CHECK_PATH" + value: {{ .Values.vault.hashicorp.paths.health | quote }} + {{- end }} + + {{- if .Values.vault.azure.enabled }} + - name: "EDC_VAULT_CLIENTID" + value: {{ .Values.vault.azure.client | quote }} + - name: "EDC_VAULT_TENANTID" + value: {{ .Values.vault.azure.tenant | quote }} + - name: "EDC_VAULT_NAME" + value: {{ .Values.vault.azure.name | quote }} + - name: "EDC_VAULT_CLIENTSECRET" + value: {{ .Values.vault.azure.secret | quote }} + - name: "EDC_VAULT_CERTIFICATE" + value: {{ .Values.vault.azure.certificate | quote }} + {{- end }} + + ###################################### + ## Additional environment variables ## + ###################################### + {{- range $key, $value := .Values.dataplane.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 16 }} + {{- end }} + {{- range $key, $value := .Values.dataplane.env }} + - name: {{ $key | quote }} + value: {{ $value | quote }} + {{- end }} + {{- if and (or .Values.dataplane.envSecretNames .Values.dataplane.envConfigMapNames) (or (gt (len .Values.dataplane.envSecretNames) 0) (gt (len .Values.dataplane.envConfigMapNames) 0)) }} + envFrom: + {{- range $value := .Values.dataplane.envSecretNames }} + - secretRef: + name: {{ $value | quote }} + {{- end }} + {{- range $value := .Values.dataplane.envConfigMapNames }} + - configMapRef: + name: {{ $value | quote }} + {{- end }} + {{- end }} + volumeMounts: + - name: "configuration" + mountPath: "/app/opentelemetry.properties" + subPath: "opentelemetry.properties" + - name: "configuration" + mountPath: "/app/logging.properties" + subPath: "logging.properties" + volumes: + - name: "configuration" + configMap: + name: {{ include "txdc.fullname" . }}-dataplane + items: + - key: "opentelemetry.properties" + path: "opentelemetry.properties" + - key: "logging.properties" + path: "logging.properties" + {{- with .Values.dataplane.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dataplane.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dataplane.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/tractusx-connector/templates/hpa-controlplane.yaml b/charts/tractusx-connector/templates/hpa-controlplane.yaml new file mode 100644 index 000000000..36fe8fae0 --- /dev/null +++ b/charts/tractusx-connector/templates/hpa-controlplane.yaml @@ -0,0 +1,29 @@ +{{- if .Values.controlplane.autoscaling.enabled }} +--- +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "txdc.fullname" . }}-controlplane + labels: + {{- include "txdc.controlplane.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "txdc.fullname" . }}-controlplane + minReplicas: {{ .Values.controlplane.autoscaling.minReplicas }} + maxReplicas: {{ .Values.controlplane.autoscaling.maxReplicas }} + metrics: + {{- if .Values.controlplane.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.controlplane.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.controlplane.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.controlplane.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/tractusx-connector/templates/hpa-dataplane.yaml b/charts/tractusx-connector/templates/hpa-dataplane.yaml new file mode 100644 index 000000000..abad34fcc --- /dev/null +++ b/charts/tractusx-connector/templates/hpa-dataplane.yaml @@ -0,0 +1,29 @@ +{{- if .Values.controlplane.autoscaling.enabled }} +--- +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "txdc.fullname" . }}-dataplane + labels: + {{- include "txdc.dataplane.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "txdc.fullname" . }}-dataplane + minReplicas: {{ .Values.dataplane.autoscaling.minReplicas }} + maxReplicas: {{ .Values.dataplane.autoscaling.maxReplicas }} + metrics: + {{- if .Values.dataplane.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.dataplane.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.dataplane.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.dataplane.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/tractusx-connector/templates/ingress-controlplane.yaml b/charts/tractusx-connector/templates/ingress-controlplane.yaml new file mode 100644 index 000000000..a2325b17c --- /dev/null +++ b/charts/tractusx-connector/templates/ingress-controlplane.yaml @@ -0,0 +1,77 @@ +{{- $fullName := include "txdc.fullname" . }} +{{- $controlLabels := include "txdc.controlplane.labels" . | nindent 4 }} +{{- $controlEdcEndpoints := .Values.controlplane.endpoints }} +{{- $gitVersion := .Capabilities.KubeVersion.GitVersion }} +{{- $namespace := .Release.Namespace }} + +{{- range .Values.controlplane.ingresses }} +{{- if and .enabled .endpoints }} +{{- $controlIngressName := printf "%s-controlplane-%s" $fullName .hostname }} +--- +{{- if semverCompare ">=1.19-0" $gitVersion }} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" $gitVersion }} +apiVersion: networking.k8s.io/v1beta1 +{{- else }} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $controlIngressName }} + namespace: {{ $namespace | default "default" | quote }} + labels: + {{- $controlLabels | nindent 2 }} + annotations: + {{- if and .className (not (semverCompare ">=1.18-0" $gitVersion)) }} + {{- if not (hasKey .annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .annotations "kubernetes.io/ingress.class" .className}} + {{- end }} + {{- end }} + {{- if .certManager }} + {{- if .certManager.issuer }} + {{- $_ := set .annotations "cert-manager.io/issuer" .certManager.issuer}} + {{- end }} + {{- if .certManager.clusterIssuer }} + {{- $_ := set .annotations "cert-manager.io/cluster-issuer" .certManager.clusterIssuer}} + {{- end }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .className (semverCompare ">=1.18-0" $gitVersion) }} + ingressClassName: {{ .className }} + {{- end }} + {{- if .hostname }} + {{- if .tls.enabled }} + tls: + - hosts: + - {{ .hostname }} + {{- if .tls.secretName }} + secretName: {{ .tls.secretName }} + {{- else }} + secretName: {{ $controlIngressName }}-tls + {{- end }} + {{- end }} + rules: + - host: {{ .hostname }} + http: + paths: + {{- $ingressEdcEndpoints := .endpoints }} + {{- range $name, $mapping := $controlEdcEndpoints }} + {{- if (has $name $ingressEdcEndpoints) }} + - path: {{ $mapping.path }} + pathType: Prefix + backend: + {{- if semverCompare ">=1.19-0" $gitVersion }} + service: + name: {{ $fullName }}-controlplane + port: + number: {{ $mapping.port }} + {{- else }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }}{{- /* end: if .enabled */}} +{{- end }}{{- /* end: range .Values.ingresses */}} diff --git a/charts/tractusx-connector/templates/ingress-dataplane.yaml b/charts/tractusx-connector/templates/ingress-dataplane.yaml new file mode 100644 index 000000000..1f79d09c1 --- /dev/null +++ b/charts/tractusx-connector/templates/ingress-dataplane.yaml @@ -0,0 +1,77 @@ +{{- $fullName := include "txdc.fullname" . }} +{{- $dataLabels := include "txdc.dataplane.labels" . | nindent 4 }} +{{- $dataEdcEndpoints := .Values.dataplane.endpoints }} +{{- $gitVersion := .Capabilities.KubeVersion.GitVersion }} +{{- $namespace := .Release.Namespace }} + +{{- range .Values.dataplane.ingresses }} +{{- if and .enabled .endpoints }} +{{- $dataIngressName := printf "%s-dataplane-%s" $fullName .hostname }} +--- +{{- if semverCompare ">=1.19-0" $gitVersion }} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" $gitVersion }} +apiVersion: networking.k8s.io/v1beta1 +{{- else }} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $dataIngressName }} + namespace: {{ $namespace | default "default" | quote }} + labels: + {{- $dataLabels | nindent 2 }} + annotations: + {{- if and .className (not (semverCompare ">=1.18-0" $gitVersion)) }} + {{- if not (hasKey .annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .annotations "kubernetes.io/ingress.class" .className}} + {{- end }} + {{- end }} + {{- if .certManager }} + {{- if .certManager.issuer }} + {{- $_ := set .annotations "cert-manager.io/issuer" .certManager.issuer}} + {{- end }} + {{- if .certManager.clusterIssuer }} + {{- $_ := set .annotations "cert-manager.io/cluster-issuer" .certManager.clusterIssuer}} + {{- end }} + {{- end }} + {{- with .annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .className (semverCompare ">=1.18-0" $gitVersion) }} + ingressClassName: {{ .className }} + {{- end }} + {{- if .hostname }} + {{- if .tls.enabled }} + tls: + - hosts: + - {{ .hostname }} + {{- if .tls.secretName }} + secretName: {{ .tls.secretName }} + {{- else }} + secretName: {{ $dataIngressName }}-tls + {{- end }} + {{- end }} + rules: + - host: {{ .hostname }} + http: + paths: + {{- $ingressEdcEndpoints := .endpoints }} + {{- range $name, $mapping := $dataEdcEndpoints }} + {{- if (has $name $ingressEdcEndpoints) }} + - path: {{ $mapping.path }} + pathType: Prefix + backend: + {{- if semverCompare ">=1.19-0" $gitVersion }} + service: + name: {{ $fullName }}-dataplane + port: + number: {{ $mapping.port }} + {{- else }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }}{{- /* end: if .enabled */}} +{{- end }}{{- /* end: range .Values.ingresses */}} diff --git a/charts/tractusx-connector/templates/service-controlplane.yaml b/charts/tractusx-connector/templates/service-controlplane.yaml new file mode 100644 index 000000000..3c4f70888 --- /dev/null +++ b/charts/tractusx-connector/templates/service-controlplane.yaml @@ -0,0 +1,37 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "txdc.fullname" . }}-controlplane + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "txdc.controlplane.labels" . | nindent 4 }} +spec: + type: {{ .Values.controlplane.service.type }} + ports: + - port: {{ .Values.controlplane.endpoints.default.port }} + targetPort: default + protocol: TCP + name: default + - port: {{ .Values.controlplane.endpoints.control.port }} + targetPort: control + protocol: TCP + name: control + - port: {{ .Values.controlplane.endpoints.data.port }} + targetPort: data + protocol: TCP + name: data + - port: {{ .Values.controlplane.endpoints.validation.port }} + targetPort: validation + protocol: TCP + name: validation + - port: {{ .Values.controlplane.endpoints.ids.port }} + targetPort: ids + protocol: TCP + name: ids + - port: {{ .Values.controlplane.endpoints.metrics.port }} + targetPort: metrics + protocol: TCP + name: metrics + selector: + {{- include "txdc.controlplane.selectorLabels" . | nindent 4 }} diff --git a/charts/tractusx-connector/templates/service-dataplane.yaml b/charts/tractusx-connector/templates/service-dataplane.yaml new file mode 100644 index 000000000..26fa9c203 --- /dev/null +++ b/charts/tractusx-connector/templates/service-dataplane.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "txdc.fullname" . }}-dataplane + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "txdc.dataplane.labels" . | nindent 4 }} +spec: + type: {{ .Values.dataplane.service.type }} + ports: + - port: {{ .Values.dataplane.endpoints.default.port }} + targetPort: default + protocol: TCP + name: default + - port: {{ .Values.dataplane.endpoints.control.port }} + targetPort: control + protocol: TCP + name: control + - port: {{ .Values.dataplane.endpoints.public.port }} + targetPort: public + protocol: TCP + name: public + - port: {{ .Values.dataplane.endpoints.metrics.port }} + targetPort: metrics + protocol: TCP + name: metrics + selector: + {{- include "txdc.dataplane.selectorLabels" . | nindent 4 }} diff --git a/charts/tractusx-connector/templates/serviceaccount.yaml b/charts/tractusx-connector/templates/serviceaccount.yaml new file mode 100644 index 000000000..c650bcd68 --- /dev/null +++ b/charts/tractusx-connector/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "txdc.serviceAccountName" . }} + labels: + {{- include "txdc.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.serviceAccount.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/tractusx-connector/values.yaml b/charts/tractusx-connector/values.yaml new file mode 100644 index 000000000..25a646147 --- /dev/null +++ b/charts/tractusx-connector/values.yaml @@ -0,0 +1,509 @@ +--- +# Default values for eclipse-dataspace-connector. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +fullnameOverride: "" +nameOverride: "" + +# -- 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) +imagePullSecrets: [] + +customLabels: {} + +controlplane: + image: + # -- Which derivate of the control plane to use. when left empty the deployment will select the correct image automatically + repository: "" + # -- [Kubernetes image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) to use + pullPolicy: IfNotPresent + # -- Overrides the image tag whose default is the chart appVersion + tag: "" + initContainers: [] + debug: + enabled: false + port: 1044 + suspendOnStart: false + internationalDataSpaces: + id: TXDC + description: Tractus-X Eclipse IDS Data Space Connector + title: "" + maintainer: "" + curator: "" + catalogId: TXDC-Catalog + livenessProbe: + # -- Whether to enable kubernetes [liveness-probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + enabled: true + # -- seconds to wait before performing the first liveness check + initialDelaySeconds: 30 + # -- this fields specifies that kubernetes should perform a liveness check every 10 seconds + periodSeconds: 10 + # -- number of seconds after which the probe times out + timeoutSeconds: 5 + # -- when a probe fails kubernetes will try 6 times before giving up + failureThreshold: 6 + # -- number of consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + readinessProbe: + # -- Whether to enable kubernetes [readiness-probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + enabled: true + # -- seconds to wait before performing the first readiness check + initialDelaySeconds: 30 + # -- this fields specifies that kubernetes should perform a readiness check every 10 seconds + periodSeconds: 10 + # -- number of seconds after which the probe times out + timeoutSeconds: 5 + # -- when a probe fails kubernetes will try 6 times before giving up + failureThreshold: 6 + # -- number of consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # -- endpoints of the control plane + endpoints: + # -- default api for health checks, should not be added to any ingress + default: + # -- port for incoming api calls + port: 8080 + # -- path for incoming api calls + path: /api + # -- data management api, used by internal users, can be added to an ingress and must not be internet facing + data: + # -- port for incoming api calls + port: 8081 + # -- path for incoming api calls + path: /data + # -- authentication key, must be attached to each 'X-Api-Key' request header + authKey: "" + # -- validation api, only used by the data plane and should not be added to any ingress + validation: + # -- port for incoming api calls + port: 8082 + # -- path for incoming api calls + path: /validation + # -- control api, used for internal control calls. can be added to the internal ingress, but should probably not + control: + # -- port for incoming api calls + port: 8083 + # -- path for incoming api calls + path: /control + # -- ids api, used for inter connector communication and must be internet facing + ids: + # -- port for incoming api calls + port: 8084 + # -- path for incoming api calls + path: /api/v1/ids + # -- metrics api, used for application metrics, must not be internet facing + metrics: + # -- port for incoming api calls + port: 9090 + # -- path for incoming api calls + path: /metrics + service: + # -- [Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to expose the running application on a set of Pods as a network service. + type: ClusterIP + annotations: {} + # -- additional labels for the pod + podLabels: {} + # -- additional annotations for the pod + podAnnotations: {} + # -- The [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) defines privilege and access control settings for a Pod within the deployment + podSecurityContext: + seccompProfile: + # -- Restrict a Container's Syscalls with seccomp + type: RuntimeDefault + # -- Runs all processes within a pod with a special uid + runAsUser: 10001 + # -- Processes within a pod will belong to this guid + runAsGroup: 10001 + # -- The owner for volumes and any files created within volumes will belong to this guid + fsGroup: 10001 + # The [container security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) defines privilege and access control settings for a Container within a pod + securityContext: + capabilities: + # -- Specifies which capabilities to drop to reduce syscall attack surface + drop: + - ALL + # -- Specifies which capabilities to add to issue specialized syscalls + add: [] + # -- Whether the root filesystem is mounted in read-only mode + readOnlyRootFilesystem: true + # -- Controls [Privilege Escalation](https://kubernetes.io/docs/concepts/security/pod-security-policy/#privilege-escalation) enabling setuid binaries changing the effective user ID + allowPrivilegeEscalation: false + # -- Requires the container to run without root privileges + runAsNonRoot: true + # -- The container's process will run with the specified uid + runAsUser: 10001 + # Extra environment variables that will be pass onto deployment pods + env: {} + # ENV_NAME: value + + # "valueFrom" environment variable references that will be added to deployment pods. Name is templated. + # ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core + envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + # secretKeyRef: + # name: secret-name + # key: value_key + + # [Kubernetes Secret Resource](https://kubernetes.io/docs/concepts/configuration/secret/) names to load environment variables from + envSecretNames: [] + # - first-secret + # - second-secret + + # [Kubernetes ConfigMap Resource](https://kubernetes.io/docs/concepts/configuration/configmap/) names to load environment variables from + envConfigMapNames: [] + # - first-config-map + # - second-config-map + + ## Ingress declaration to expose the network service. + ingresses: + ## Public / Internet facing Ingress + - enabled: false + # -- The hostname to be used to precisely map incoming traffic onto the underlying network service + hostname: "edc-control.local" + # -- Additional ingress annotations to add + annotations: {} + # -- EDC endpoints exposed by this ingress resource + endpoints: + - ids + # -- Defines the [ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) to use + className: "" + # -- TLS [tls class](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) applied to the ingress resource + tls: + # -- Enables TLS on the ingress resource + enabled: false + # -- If present overwrites the default secret name + secretName: "" + ## Adds [cert-manager](https://cert-manager.io/docs/) annotations to the ingress resource + certManager: + # -- If preset enables certificate generation via cert-manager namespace scoped issuer + issuer: "" + # -- If preset enables certificate generation via cert-manager cluster-wide issuer + clusterIssuer: "" + ## Private / Intranet facing Ingress + - enabled: false + # -- The hostname to be used to precisely map incoming traffic onto the underlying network service + hostname: "edc-control.intranet" + # -- Additional ingress annotations to add + annotations: {} + # -- EDC endpoints exposed by this ingress resource + endpoints: + - data + - control + # -- Defines the [ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) to use + className: "" + # -- TLS [tls class](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) applied to the ingress resource + tls: + # -- Enables TLS on the ingress resource + enabled: false + # -- If present overwrites the default secret name + secretName: "" + ## Adds [cert-manager](https://cert-manager.io/docs/) annotations to the ingress resource + certManager: + # -- If preset enables certificate generation via cert-manager namespace scoped issuer + issuer: "" + # -- If preset enables certificate generation via cert-manager cluster-wide issuer + clusterIssuer: "" + # -- declare where to mount [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) into the container + volumeMounts: [] + # -- [volume](https://kubernetes.io/docs/concepts/storage/volumes/) directories + volumes: [] + # -- [resource management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the container + resources: + {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + replicaCount: 1 + autoscaling: + # -- Enables [horizontal pod autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) + enabled: false + # -- Minimal replicas if resource consumption falls below resource threshholds + minReplicas: 1 + # -- Maximum replicas if resource consumption exceeds resource threshholds + maxReplicas: 100 + # -- targetAverageUtilization of cpu provided to a pod + targetCPUUtilizationPercentage: 80 + # -- targetAverageUtilization of memory provided to a pod + targetMemoryUtilizationPercentage: 80 + # -- configuration of the [Open Telemetry Agent](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/) to collect and expose metrics + opentelemetry: |- + otel.javaagent.enabled=false + otel.javaagent.debug=false + # -- configuration of the [Java Util Logging Facade](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html) + logging: |- + .level=INFO + org.eclipse.dataspaceconnector.level=ALL + handlers=java.util.logging.ConsoleHandler + java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter + java.util.logging.ConsoleHandler.level=ALL + java.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n + + # [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) to constrain pods to nodes + nodeSelector: {} + # [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to configure preferred nodes + tolerations: [] + # [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) to configure which nodes the pods can be scheduled on + affinity: {} + + url: + # -- Explicitly declared url for reaching the ids api (e.g. if ingresses not used) + ids: "" + +dataplane: + image: + # -- Which derivate of the data plane to use. when left empty the deployment will select the correct image automatically + repository: "" + # -- [Kubernetes image pull policy](https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy) to use + pullPolicy: IfNotPresent + # -- Overrides the image tag whose default is the chart appVersion + tag: "" + initContainers: [] + debug: + enabled: false + port: 1044 + suspendOnStart: false + livenessProbe: + # -- Whether to enable kubernetes [liveness-probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + enabled: true + # -- seconds to wait before performing the first liveness check + initialDelaySeconds: 30 + # -- this fields specifies that kubernetes should perform a liveness check every 10 seconds + periodSeconds: 10 + # -- number of seconds after which the probe times out + timeoutSeconds: 5 + # -- when a probe fails kubernetes will try 6 times before giving up + failureThreshold: 6 + # -- number of consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + readinessProbe: + # -- Whether to enable kubernetes [readiness-probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + enabled: true + # -- seconds to wait before performing the first readiness check + initialDelaySeconds: 30 + # -- this fields specifies that kubernetes should perform a liveness check every 10 seconds + periodSeconds: 10 + # -- number of seconds after which the probe times out + timeoutSeconds: 5 + # -- when a probe fails kubernetes will try 6 times before giving up + failureThreshold: 6 + # -- number of consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + service: + # -- [Service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) to expose the running application on a set of Pods as a network service. + type: ClusterIP + port: 80 + endpoints: + default: + port: 8080 + path: /api + public: + port: 8081 + path: /api/public + validation: + port: 8082 + path: /validation + control: + port: 8083 + path: /api/dataplane/control + metrics: + port: 9090 + path: /metrics + aws: + endpointOverride: "" + accessKeyId: "" + secretAccessKey: "" + # -- additional labels for the pod + podLabels: {} + # -- additional annotations for the pod + podAnnotations: {} + # -- The [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) defines privilege and access control settings for a Pod within the deployment + podSecurityContext: + seccompProfile: + # -- Restrict a Container's Syscalls with seccomp + type: RuntimeDefault + # -- Runs all processes within a pod with a special uid + runAsUser: 10001 + # -- Processes within a pod will belong to this guid + runAsGroup: 10001 + # -- The owner for volumes and any files created within volumes will belong to this guid + fsGroup: 10001 + # The [container security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) defines privilege and access control settings for a Container within a pod + securityContext: + capabilities: + # -- Specifies which capabilities to drop to reduce syscall attack surface + drop: + - ALL + # -- Specifies which capabilities to add to issue specialized syscalls + add: [] + # -- Whether the root filesystem is mounted in read-only mode + readOnlyRootFilesystem: true + # -- Controls [Privilege Escalation](https://kubernetes.io/docs/concepts/security/pod-security-policy/#privilege-escalation) enabling setuid binaries changing the effective user ID + allowPrivilegeEscalation: false + # -- Requires the container to run without root privileges + runAsNonRoot: true + # -- The container's process will run with the specified uid + runAsUser: 10001 + # Extra environment variables that will be pass onto deployment pods + env: {} + # ENV_NAME: value + + # "valueFrom" environment variable references that will be added to deployment pods. Name is templated. + # ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core + envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + # secretKeyRef: + # name: secret-name + # key: value_key + + # [Kubernetes Secret Resource](https://kubernetes.io/docs/concepts/configuration/secret/) names to load environment variables from + envSecretNames: [] + # - first-secret + # - second-secret + + # [Kubernetes ConfigMap Resource](https://kubernetes.io/docs/concepts/configuration/configmap/) names to load environment variables from + envConfigMapNames: [] + # - first-config-map + # - second-config-map + + ## Ingress declaration to expose the network service. + ingresses: + ## Public / Internet facing Ingress + - enabled: false + # -- The hostname to be used to precisely map incoming traffic onto the underlying network service + hostname: "edc-data.local" + # -- Additional ingress annotations to add + annotations: {} + # -- EDC endpoints exposed by this ingress resource + endpoints: + - public + # -- Defines the [ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) to use + className: "" + # -- TLS [tls class](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) applied to the ingress resource + tls: + # -- Enables TLS on the ingress resource + enabled: false + # -- If present overwrites the default secret name + secretName: "" + ## Adds [cert-manager](https://cert-manager.io/docs/) annotations to the ingress resource + certManager: + # -- If preset enables certificate generation via cert-manager namespace scoped issuer + issuer: "" + # -- If preset enables certificate generation via cert-manager cluster-wide issuer + clusterIssuer: "" + # -- declare where to mount [volumes](https://kubernetes.io/docs/concepts/storage/volumes/) into the container + volumeMounts: [] + # -- [volume](https://kubernetes.io/docs/concepts/storage/volumes/) directories + volumes: [] + # -- [resource management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the container + resources: + {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + replicaCount: 1 + autoscaling: + # -- Enables [horizontal pod autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) + enabled: false + # -- Minimal replicas if resource consumption falls below resource threshholds + minReplicas: 1 + # -- Maximum replicas if resource consumption exceeds resource threshholds + maxReplicas: 100 + # -- targetAverageUtilization of cpu provided to a pod + targetCPUUtilizationPercentage: 80 + # -- targetAverageUtilization of memory provided to a pod + targetMemoryUtilizationPercentage: 80 + # -- configuration of the [Open Telemetry Agent](https://opentelemetry.io/docs/instrumentation/java/automatic/agent-config/) to collect and expose metrics + opentelemetry: |- + otel.javaagent.enabled=false + otel.javaagent.debug=false + # -- configuration of the [Java Util Logging Facade](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html) + logging: |- + .level=INFO + org.eclipse.dataspaceconnector.level=ALL + handlers=java.util.logging.ConsoleHandler + java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter + java.util.logging.ConsoleHandler.level=ALL + java.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n + # [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) to constrain pods to nodes + nodeSelector: {} + # [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to configure preferred nodes + tolerations: [] + # [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) to configure which nodes the pods can be scheduled on + affinity: {} + + url: + # -- Explicitly declared url for reaching the public api (e.g. if ingresses not used) + public: "" + +postgresql: + enabled: false + jdbcUrl: "" + username: "" + password: "" + +vault: + hashicorp: + enabled: false + url: "" + token: "" + timeout: 30 + healthCheck: + enabled: true + standbyOk: true + paths: + secret: /v1/secret + health: /v1/sys/health + azure: + enabled: false + name: "" + client: "" + tenant: "" + secret: "" + certificate: "" + secretNames: + transferProxyTokenSignerPrivateKey: transfer-proxy-token-signer-private-key + transferProxyTokenSignerPublicKey: transfer-proxy-token-signer-public-key + transferProxyTokenEncryptionAesKey: transfer-proxy-token-encryption-aes-key + dapsPrivateKey: daps-private-key + dapsPublicKey: daps-public-key + +daps: + url: "" + clientId: "" + paths: + jwks: /jwks.json + token: /token + +backendService: + httpProxyTokenReceiverUrl: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + # -- Existing image pull secret bound to the service account to use to [obtain the container image from private registries](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry) + imagePullSecrets: [] diff --git a/ct.yaml b/ct.yaml index 4c716ff7d..1b81ec6ce 100644 --- a/ct.yaml +++ b/ct.yaml @@ -1,4 +1,4 @@ --- validate-maintainers: false chart-dirs: - - deployment/helm + - charts diff --git a/docs/README.md b/docs/README.md index b5bb8d338..ebcc9942c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # Product EDC -The Catena-X Product EDC Repository creates runnable applications out of EDC extensions from the [Eclipse DataSpace Connector](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector) repository. +The Catena-X Product EDC Repository creates runnable applications out of EDC extensions from the [Eclipse DataSpace Connector](https://github.com/eclipse-edc/Connector) repository. When running a EDC connector from the Product EDC repository there are three setups to choose from. They only vary by using different extensions for - Resolving of Connector-Identities @@ -9,26 +9,33 @@ When running a EDC connector from the Product EDC repository there are three set ## Connector Setup -The three supported setups are. +The four supported setups are. - Setup 1: In Memory & Azure Vault - [Control Plane](../edc-controlplane/edc-controlplane-memory/README.md) - - [IDS DAPS Extensions](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/iam/oauth2/daps) + - [IDS DAPS Extensions](https://github.com/eclipse-edc/Connector/tree/main/extensions/common/iam/oauth2/daps) - In Memory Persistence done by using no extension - - [Azure Key Vault Extension](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/vault/azure-vault) + - [Azure Key Vault Extension](https://github.com/eclipse-edc/Connector/tree/main/extensions/common/vault/azure-vault) - [Data Plane](../edc-dataplane/edc-dataplane-azure-vault/README.md) - - [Azure Key Vault Extension](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/vault/azure-vault) + - [Azure Key Vault Extension](https://github.com/eclipse-edc/Connector/tree/main/extensions/common/vault/azure-vault) +- Setup 2: In Memory & HashiCorp Vault +- [Control Plane](../edc-controlplane/edc-controlplane-memory/README.md) + - [IDS DAPS Extensions](https://github.com/eclipse-edc/Connector/tree/main/extensions/common/iam/oauth2/daps) + - In Memory Persistence done by using no extension + - [HashiCorp Vault Extension](../edc-extensions/hashicorp-vault/README.md) +- [Data Plane](../edc-dataplane/edc-dataplane-azure-vault/README.md) + - [HashiCorp Vault Extension](../edc-extensions/hashicorp-vault/README.md) - Setup 2: PostgreSQL & Azure Vault - [Control Plane](../edc-controlplane/edc-controlplane-postgresql/README.md) - - [IDS DAPS Extensions](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/iam/oauth2/daps) - - [PostgreSQL Persistence Extensions](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql) - - [Azure Key Vault Extension](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/vault/azure-vault) + - [IDS DAPS Extensions](https://github.com/eclipse-edc/Connector/tree/main/extensions/common/iam/oauth2/daps) + - [PostgreSQL Persistence Extensions](https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/store/sql) + - [Azure Key Vault Extension](https://github.com/eclipse-edc/Connector/tree/main/extensions/common/vault/azure-vault) - [Data Plane](../edc-dataplane/edc-dataplane-azure-vault/README.md) - - [Azure Key Vault Extension](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/vault/azure-vault) + - [Azure Key Vault Extension](https://github.com/eclipse-edc/Connector/tree/main/extensions/common/vault/azure-vault) - Setup 3: PostgreSQL & HashiCorp Vault - [Control Plane](../edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/README.md) - - [IDS DAPS Extensions](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/iam/oauth2/daps) - - [PostgreSQL Persistence Extensions](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql) + - [IDS DAPS Extensions](https://github.com/eclipse-edc/Connector/tree/main/extensions/common/iam/oauth2/daps) + - [PostgreSQL Persistence Extensions](https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/store/sql) - [HashiCorp Vault Extension](../edc-extensions/hashicorp-vault/README.md) - [Data Plane](../edc-dataplane/edc-dataplane-hashicorp-vault/README.md) - [HashiCorp Vault Extension](../edc-extensions/hashicorp-vault/README.md) @@ -42,13 +49,14 @@ The three supported setups are. - [Application: Data Plane](../edc-dataplane) - [Extension: Business Partner Numbers](../edc-extensions/business-partner-validation/README.md) - [Example: Connector Configuration (Helm)](../edc-tests/src/main/resources/deployment/helm/all-in-one/README.md) -- [Example: Data Transfer](./data-transfer/Transfer%20Data.md) +- [Example: Local TXDC Setup](samples/Local%20TXDC%20Setup.md) +- [Example: Data Transfer](samples/Transfer%20Data.md) **Eclipse Dataspace Connector** -- [EDC Domain Model](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/blob/main/docs/developer/architecture/domain-model.md) -- [EDC Open API Spec](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/blob/main/resources/openapi/openapi.yaml) -- [HTTP Receiver Extension](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/http-receiver) +- [EDC Domain Model](https://github.com/eclipse-edc/Connector/blob/main/docs/developer/architecture/domain-model.md) +- [EDC Open API Spec](https://github.com/eclipse-edc/Connector/blob/main/resources/openapi/openapi.yaml) +- [HTTP Receiver Extension](https://github.com/eclipse-edc/Connector/tree/main/extensions/control-plane/http-receiver) **Catena-X** diff --git a/docs/data-transfer/Transfer Data.md b/docs/data-transfer/Transfer Data.md deleted file mode 100644 index 5de4b3111..000000000 --- a/docs/data-transfer/Transfer Data.md +++ /dev/null @@ -1,269 +0,0 @@ -# Transfer Data - -This document will showcase a data transfer between two connectors. It uses two connectors from the *All-in-one deployment* of this repository. - ---- - -Before running the commands setup the all-in-one deployment from the. This is documented in it's -[README.md](../../edc-tests/src/main/resources/deployment/helm/all-in-one/README.md). - -Please install [jq](https://stedolan.github.io/jq/), as it is used in the bash calls of this document. - ---- - -For this transfer connector **Plato** will act as data provider, and connector **Sokrates** will act as data -consumer. But the roles could be inverse as well. - -**Contents** - -0. Before running the demo - 1. Ensure all pods are running - 2. Set environment variables -1. Setup Data Offer -2. Request Contract Offers -3. Negotiate Contract -4. Transfer Data -5. Verify Data Transfer - -## 0. Before Running the demo - -### 0.1 Wait until all pods are running - -Get all the pods and wait until all pods are in a `Running` state before executing the next steps. -Please ignore that the EDC applications will crash 2-3 times during the start-up phase. This is normal. - -**Run** - -```bash -minikube kubectl -- -n edc-all-in-one get pods -``` - -### 0.2 Set environment variables used in subsequent calls - -Initialize the following environment variables, that are used in the upcoming API calls. - -**Run** - -```bash -export PLATO_DATAMGMT_URL=$(minikube service plato-edc-controlplane -n edc-all-in-one --url | sed -n 3p) -export PLATO_IDS_URL="http://plato-edc-controlplane:8282" -export SOKRATES_DATAMGMT_URL=$(minikube service sokrates-edc-controlplane -n edc-all-in-one --url | sed -n 3p) -export SOKRATES_BACKEND_URL=$(minikube service sokrates-backend-application -n edc-all-in-one --url | sed -n 2p) -``` - -Please note: The IDS URL is used for DAPS Token Audience validation. Therefore it must be the internal IDS url, that is configured inside the connector. - -## 1. Setup Data Offer - -Set up a data offer in **Plato**, so that **Sokrates** has something to consume. - -In case you are unfamiliar with the EDC terms `Asset`, `Policy` or `ContractDefinition` please have a look at the official open -source documentation ([link](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/blob/main/docs/developer/architecture/domain-model.md)). - -![Sequence 1](diagrams/transfer_sequence_1.png) - -**Run** - - -The following commands will create an Asset, a Policy and a Contract Definition. -For simplicity `https://jsonplaceholder.typicode.com/todos/1` is used as data source of the asset, but could be any -other API, that is reachable from the Provider Data Plane. - -```bash -curl -X POST "$PLATO_DATAMGMT_URL/data/assets" \ - --header 'X-Api-Key: password' \ - --header 'Content-Type: application/json' \ - --data '{ - "asset": { - "properties": { - "asset:prop:id": "1", - "asset:prop:description": "Product EDC Demo Asset" - } - }, - "dataAddress": { - "properties": { - "type": "HttpData", - "baseUrl": "https://jsonplaceholder.typicode.com/todos/1" - } - } - }' \ - -s -o /dev/null -w 'Response Code: %{http_code}\n' -``` - -```bash -curl -X POST "${PLATO_DATAMGMT_URL}/data/policydefinitions" \ - --header 'X-Api-Key: password' \ - --header 'Content-Type: application/json' \ - --data '{ - "id": "1", - "policy": { - "prohibitions": [], - "obligations": [], - "permissions": [ - { - "edctype": "dataspaceconnector:permission", - "action": { "type": "USE" }, - "constraints": [] - } - ] - } - }' \ - -s -o /dev/null -w 'Response Code: %{http_code}\n' -``` - - -```bash -curl -X POST "${PLATO_DATAMGMT_URL}/data/contractdefinitions" \ - --header 'X-Api-Key: password' \ - --header 'Content-Type: application/json' \ - --data '{ - "id": "1", - "criteria": [ - { - "operandLeft": "asset:prop:id", - "operator": "=", - "operandRight": "1" - } - ], - "accessPolicyId": "1", - "contractPolicyId": "1" - }' \ - -s -o /dev/null -w 'Response Code: %{http_code}\n' -``` - -## 2. Request Contract Offer Catalog - -In this step Sokrates gets told to request contract offers from another connector (in this case Plato). Sokrates will -then request the catalog over IDS messaging. - -For IDS messaging connectors will identify each other using the configured IDS DAPS. Therefore, it is important that -connectors, that intent to send messages to each other, have the same DAPS instance configured. - -![Sequence 1](diagrams/transfer_sequence_2.png) - -**Run** - -```bash -curl -G -X GET "${SOKRATES_DATAMGMT_URL}/data/catalog" \ - --data-urlencode "providerUrl=${PLATO_IDS_URL}/api/v1/ids/data" \ - --header 'X-Api-Key: password' \ - --header 'Content-Type: application/json' \ - -s | jq -``` - -## 3. Negotiate Contract - -Initiate a contract negotiation for the asset (from step 1). Part of the negotiation payload is the contract -offer (received in step 2). - -In the diagram the IDS contract negotiation is marked as simplified, because the EDC is exchanging multiple messages -during contract negotiation. But the inter-controlplane communication is not in the scope of this document. - -After the negotiation is initiated ensure that is has concluded. This is done by requesting the negotiation from the API -and checking whether the `contractAgreementId` is set. This might take a few seconds. - -![Sequence 1](diagrams/transfer_sequence_3.png) - -**Run** - -```bash -export NEGOTIATION_ID=$( \ - curl -X POST "${SOKRATES_DATAMGMT_URL}/data/contractnegotiations" \ - --header "X-Api-Key: password" \ - --header "Content-Type: application/json" \ - --data "{ - \"connectorId\": \"foo\", - \"connectorAddress\": \"${PLATO_IDS_URL}/api/v1/ids/data\", - \"offer\": { - \"offerId\": \"1:foo\", - \"assetId\": \"1\", - \"policy\": { - \"uid\": \"1\", - \"prohibitions\": [], - \"obligations\": [], - \"permissions\": [ - { - \"edctype\": \"dataspaceconnector:permission\", - \"action\": { \"type\": \"USE\" }, - \"target\": \"1\", - \"constraints\": [] - } - ] - } - } - }" \ - -s | jq -r '.id') -``` - - -```bash -curl -X GET "${SOKRATES_DATAMGMT_URL}/data/contractnegotiations/${NEGOTIATION_ID}" \ - --header 'X-Api-Key: password' \ - --header 'Content-Type: application/json' \ - -s | jq -``` - -## 4. Transfer Data - -Initiate a data transfer using the contract agreement from the negotiation (from step 3). Then wait until the state of -the transfer process is `COMPLETED`. - -![Sequence 1](diagrams/transfer_sequence_4.png) - -**Run** - -```bash -export CONTRACT_AGREEMENT_ID=$( \ - curl -X GET "$SOKRATES_DATAMGMT_URL/data/contractnegotiations/$NEGOTIATION_ID" \ - --header 'X-Api-Key: password' \ - --header 'Content-Type: application/json' \ - -s | jq -r '.contractAgreementId') -``` - -```bash -export TRANSFER_PROCESS_ID=$(tr -dc '[:alnum:]' < /dev/urandom | head -c20) -export TRANSFER_ID=$( \ - curl -X POST "${SOKRATES_DATAMGMT_URL}/data/transferprocess" \ - --header "X-Api-Key: password" \ - --header "Content-Type: application/json" \ - --data "{ - \"id\": \"${TRANSFER_PROCESS_ID}\", - \"connectorId\": \"foo\", - \"connectorAddress\": \"${PLATO_IDS_URL}/api/v1/ids/data\", - \"contractId\": \"${CONTRACT_AGREEMENT_ID}\", - \"assetId\": \"1\", - \"managedResources\": \"false\", - \"dataDestination\": { \"type\": \"HttpProxy\" } - }" \ - -s | jq -r '.id') -``` - -```bash -curl -X GET "$SOKRATES_DATAMGMT_URL/data/transferprocess/$TRANSFER_ID" \ - --header 'X-Api-Key: password' \ - --header 'Content-Type: application/json' \ - -s | jq -``` - -## 5. Verify Data Transfer - -After the transfer is complete the Backend Application has downloaded the data. The Backend Application stores the data -locally. In this demo the transfer can be verified by executing a simple `cat` call in the Pod. - -![Sequence 1](diagrams/transfer_sequence_5.png) - -```bash -curl -X GET "${SOKRATES_BACKEND_URL}/${TRANSFER_PROCESS_ID}" \ - --header 'Accept: application/octet-stream' \ - -s | jq -``` - -# Delete All Data - -```bash -minikube kubectl -- delete pvc -n edc-all-in-one --all -``` - -```bash -minikube kubectl -- delete pv -n edc-all-in-one --all -``` diff --git a/docs/data-transfer/diagrams/transfer_sequence_1.png b/docs/data-transfer/diagrams/transfer_sequence_1.png deleted file mode 100644 index f52ecbb70..000000000 Binary files a/docs/data-transfer/diagrams/transfer_sequence_1.png and /dev/null differ diff --git a/docs/data-transfer/diagrams/transfer_sequence_1.puml b/docs/data-transfer/diagrams/transfer_sequence_1.puml deleted file mode 100644 index a159447ee..000000000 --- a/docs/data-transfer/diagrams/transfer_sequence_1.puml +++ /dev/null @@ -1,34 +0,0 @@ -@startuml - -!define sokratesColor 66CCFF -!define platoColor CCFF99 -!define dapsColor FFFF99 -!define noteColor 9999FF - -actor User as "User" - -box Sokrates - participant SokratesControlPlane as "Control Plane" #sokratesColor - participant SokratesBackendService as "Backend Application" #sokratesColor - participant SokratesDataPlane as "Data Plane" #sokratesColor -end box - -box Plato - participant PlatoControlPlane as "Control Plane" #platoColor - participant PlatoDataPlane as "Data Plane" #platoColor -end box - -participant JsonPlaceHolder as "JsonPlaceHolder" - - -User -> PlatoControlPlane ++ : Create Asset -return 204 - -User -> PlatoControlPlane ++ : Create Policy -return 204 - -User -> PlatoControlPlane ++ : Create Contract Definition -return 204 - - -@enduml diff --git a/docs/data-transfer/diagrams/transfer_sequence_2.png b/docs/data-transfer/diagrams/transfer_sequence_2.png deleted file mode 100644 index ed2f4dd90..000000000 Binary files a/docs/data-transfer/diagrams/transfer_sequence_2.png and /dev/null differ diff --git a/docs/data-transfer/diagrams/transfer_sequence_2.puml b/docs/data-transfer/diagrams/transfer_sequence_2.puml deleted file mode 100644 index 805bcbeec..000000000 --- a/docs/data-transfer/diagrams/transfer_sequence_2.puml +++ /dev/null @@ -1,28 +0,0 @@ -@startuml - -!define sokratesColor 66CCFF -!define platoColor CCFF99 -!define dapsColor FFFF99 -!define noteColor 9999FF - -actor User as "User" - -box Sokrates - participant SokratesControlPlane as "Control Plane" #sokratesColor - participant SokratesBackendService as "Backend Application" #sokratesColor - participant SokratesDataPlane as "Data Plane" #sokratesColor -end box - -box Plato - participant PlatoControlPlane as "Control Plane" #platoColor - participant PlatoDataPlane as "Data Plane" #platoColor -end box - -participant JsonPlaceHolder as "JsonPlaceHolder" - -User -> SokratesControlPlane ++ : Request Contract Offers from Plato - SokratesControlPlane -> PlatoControlPlane ++ : IDS Description Request Message - return Description -return Contract Offers - -@enduml diff --git a/docs/data-transfer/diagrams/transfer_sequence_3.png b/docs/data-transfer/diagrams/transfer_sequence_3.png deleted file mode 100644 index b1d56ec6c..000000000 Binary files a/docs/data-transfer/diagrams/transfer_sequence_3.png and /dev/null differ diff --git a/docs/data-transfer/diagrams/transfer_sequence_3.puml b/docs/data-transfer/diagrams/transfer_sequence_3.puml deleted file mode 100644 index 43707af36..000000000 --- a/docs/data-transfer/diagrams/transfer_sequence_3.puml +++ /dev/null @@ -1,33 +0,0 @@ -@startuml - -!define sokratesColor 66CCFF -!define platoColor CCFF99 -!define dapsColor FFFF99 -!define noteColor 9999FF - -actor User as "User" - -box Sokrates - participant SokratesControlPlane as "Control Plane" #sokratesColor - participant SokratesBackendService as "Backend Application" #sokratesColor - participant SokratesDataPlane as "Data Plane" #sokratesColor -end box - -box Plato - participant PlatoControlPlane as "Control Plane" #platoColor - participant PlatoDataPlane as "Data Plane" #platoColor -end box - -participant JsonPlaceHolder as "JsonPlaceHolder" - - -User -> SokratesControlPlane ++ : Negotiate Contract for Offer X -SokratesControlPlane --> User: Negotiation ID - SokratesControlPlane -> PlatoControlPlane ++ : IDS Contract Negotiation (simplified) - return Contract Agreement -deactivate SokratesControlPlane - -User -> SokratesControlPlane ++ : Request Negotiation by ID -return Contract Negotiation - -@enduml diff --git a/docs/data-transfer/diagrams/transfer_sequence_4.png b/docs/data-transfer/diagrams/transfer_sequence_4.png deleted file mode 100644 index 43701e1ba..000000000 Binary files a/docs/data-transfer/diagrams/transfer_sequence_4.png and /dev/null differ diff --git a/docs/data-transfer/diagrams/transfer_sequence_4.puml b/docs/data-transfer/diagrams/transfer_sequence_4.puml deleted file mode 100644 index 704938917..000000000 --- a/docs/data-transfer/diagrams/transfer_sequence_4.puml +++ /dev/null @@ -1,44 +0,0 @@ -@startuml - -!define sokratesColor 66CCFF -!define platoColor CCFF99 -!define dapsColor FFFF99 -!define noteColor 9999FF - -actor User as "User" - -box Sokrates - participant SokratesControlPlane as "Control Plane" #sokratesColor - participant SokratesBackendService as "Backend Application" #sokratesColor - participant SokratesDataPlane as "Data Plane" #sokratesColor -end box - -box Plato - participant PlatoControlPlane as "Control Plane" #platoColor - participant PlatoDataPlane as "Data Plane" #platoColor -end box - -participant JsonPlaceHolder as "JsonPlaceHolder" - -User -> SokratesControlPlane ++ : Request Negotiation by ID -return Contract Negotiation\n(containing Contract Agreement ID) - -User -> SokratesControlPlane ++ : Initiate Transfer with Agreement ID -SokratesControlPlane --> User : Transfer Process ID - SokratesControlPlane -> PlatoControlPlane ++ : IDS Data Transfer (simplified) -return -SokratesControlPlane -> SokratesBackendService ++ : Data Plane Endpoint + Token - SokratesBackendService -> SokratesDataPlane ++ : Request Data with Token - SokratesDataPlane -> PlatoDataPlane ++ : Request Data - PlatoDataPlane -> JsonPlaceHolder ++ : Request Data - return data - return data - return data - SokratesBackendService -> SokratesBackendService : Write Data to File -return ok -deactivate SokratesControlPlane - -User -> SokratesControlPlane ++ : Request Transfer Process by ID -return Transfer Process - -@enduml diff --git a/docs/data-transfer/diagrams/transfer_sequence_5.png b/docs/data-transfer/diagrams/transfer_sequence_5.png deleted file mode 100644 index 080c26335..000000000 Binary files a/docs/data-transfer/diagrams/transfer_sequence_5.png and /dev/null differ diff --git a/docs/data-transfer/diagrams/transfer_sequence_5.puml b/docs/data-transfer/diagrams/transfer_sequence_5.puml deleted file mode 100644 index b64f2222b..000000000 --- a/docs/data-transfer/diagrams/transfer_sequence_5.puml +++ /dev/null @@ -1,27 +0,0 @@ -@startuml - -!define sokratesColor 66CCFF -!define platoColor CCFF99 -!define dapsColor FFFF99 -!define noteColor 9999FF - -actor User as "User" - -box Sokrates - participant SokratesControlPlane as "Control Plane" #sokratesColor - participant SokratesBackendService as "Backend Application" #sokratesColor - participant SokratesDataPlane as "Data Plane" #sokratesColor -end box - -box Plato - participant PlatoControlPlane as "Control Plane" #platoColor - participant PlatoDataPlane as "Data Plane" #platoColor -end box - -participant JsonPlaceHolder as "JsonPlaceHolder" - -User -> SokratesBackendService ++ : Get File Content -return data - - -@enduml diff --git a/docs/development/Release.md b/docs/development/Release.md index 2b8e09d07..8628bddfa 100644 --- a/docs/development/Release.md +++ b/docs/development/Release.md @@ -5,36 +5,39 @@ [![Apache Maven][maven-shield]][maven-url] ## Update DEPENDENCIES file -### 1. Setup Eclipse Dash License Tool Maven Plugin locally -At the time of writing the maven plugin could not be downloaded from the repository. -As alternative check out the repository and build the plugin locally, so that its added to the local maven repository. +### 1. Setup Eclipse Dash License Tool locally -#### 1.1 Checkout repository +For instructions on how to download the Eclipse Dash Tool executable, refer to the +project's [GitHub page](https://github.com/eclipse/dash-licenses#get-it). -`git clone https://github.com/eclipse/dash-licenses.git` - -#### 1.2 Install Plugin in local maven repository +### 2. Generate DEPENDENCIES file -`mvn clean install` +This call generates the dependencies file. This list is populated by deriving dependencies using the build tool (i.e., +gradle), analysing them using an IP tool (i.e., Eclipse Dash Tool), and decorating the resulting report with additional +information using a custom script. -### 2. Generate DEPENDENCIES file +Execute the gradle task `allDependencies` for creating an integrated dependency report over all sub-modules of the +project (including isolated modules). To process the dependencies of a specific module (e.g., an individual launcher) +execute the standard `dependencies` task: -This call generates the dependencies file. If there is a value set for `dash.iplab.token` it will also automatically create new issues for all unknown dependencies at the Eclipse Intellectual Property board -https://gitlab.eclipse.org/eclipsefdn/emo-team/iplab/-/issues +- First, the dependencies of this module are calculated with gradle and passed to the Dash tool: -```bash -./mvnw org.eclipse.dash:license-tool-plugin:license-check \ - -Ddash.summary=DEPENDENCIES \ - -Ddash.projectId=automotive.tractusx \ - -Ddash.iplab.token= +```shell +gradle allDependencies | grep -Poh "(?<=\s)[\w.-]+:[\w.-]+:[^:\s]+" | sort | uniq | java -jar /path/org.eclipse.dash.licenses-0.0.1-SNAPSHOT.jar - -summary DEPENDENCIES ``` -

- - * see dash documentation on how to get a token - -

+_Note: on some machines (e.g. macOS) [the ack tool](https://beyondgrep.com/install/) should be used instead of `grep`._ + +### 3. Resolve restricted Dependencies + +If a dependency is `restricted`, it is not approved by the Eclipse Foundation, yet. +The Eclipse Bot is able to approve dependencies automatically, if the license can be resolved by ClearlyDefined. + +1. (optional) Visit [https://clearlydefined.io/harvest](https://clearlydefined.io/harvest) and harvest the dependency + from maven central. +2. Create the Eclipse IP Issues or ask an Eclipse Commiter to do this for you. [maven-shield]: https://img.shields.io/badge/Apache%20Maven-URL-blue + [maven-url]: https://maven.apache.org \ No newline at end of file diff --git a/docs/development/Run-business-tests-local.md b/docs/development/Run-business-tests-local.md new file mode 100644 index 000000000..8a87ace24 --- /dev/null +++ b/docs/development/Run-business-tests-local.md @@ -0,0 +1,139 @@ +# Run and debug Business-Tests local within IDE +**Prerequisites:** +- You need a local kubernetes cluster to install the services (Docker Desktop is recommended). +- You need kubectl and helm command line tools installed. + +### 1. Build all modules with maven and produce docker images + +```shell +./gradlew dockerize +``` + +### 2. Install the all-in-one supporting infrastructure environment (Daps, Vault, PostgreSql, Minio, Backend-Service) +```shel +helm install infrastructure edc-tests/src/main/resources/deployment/helm/supporting-infrastructure -n business-tests --create-namespace +``` + +To access the PostgreSql databases you could use following kubectl port forwardings: +```shell +kubectl port-forward plato-postgresql-0 -n business-tests 5555:5432 +kubectl port-forward sokrates-postgresql-0 -n business-tests 6666:5432 +``` +Please use the same ports later for your environment variables. + +### 3. Install Plato as provider EDC +```shell +helm install plato charts/tractusx-connector -n business-tests --create-namespace \ + --set fullnameOverride=plato \ + --set controlplane.service.type=NodePort \ + --set controlplane.endpoints.data.authKey=password \ + --set controlplane.image.pullPolicy=Never \ + --set controlplane.image.tag=latest \ + --set controlplane.image.repository=edc-controlplane-postgresql-hashicorp-vault \ + --set dataplane.image.tag=latest \ + --set dataplane.image.pullPolicy=Never \ + --set dataplane.image.repository=edc-dataplane-hashicorp-vault \ + --set controlplane.debug.enabled=true \ + --set controlplane.suspendOnStart=false \ + --set postgresql.enabled=true \ + --set postgresql.username=user \ + --set postgresql.password=password \ + --set postgresql.jdbcUrl=jdbc:postgresql://plato-postgresql:5432/edc \ + --set vault.hashicorp.enabled=true \ + --set vault.hashicorp.url=http://vault:8200 \ + --set vault.hashicorp.token=root \ + --set vault.secretNames.transferProxyTokenSignerPublicKey=plato/daps/my-plato-daps-crt \ + --set vault.secretNames.transferProxyTokenSignerPrivateKey=plato/daps/my-plato-daps-key \ + --set vault.secretNames.transferProxyTokenEncryptionAesKey=plato/data-encryption-aes-keys \ + --set vault.secretNames.dapsPrivateKey=plato/daps/my-plato-daps-key \ + --set vault.secretNames.dapsPublicKey=plato/daps/my-plato-daps-crt \ + --set daps.url=http://ids-daps:4567 \ + --set daps.clientId=99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:23:keyid:99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:23 \ + --set dataplane.aws.endpointOverride=http://minio:9000 \ + --set dataplane.aws.secretAccessKey=platoqwerty123 \ + --set dataplane.aws.accessKeyId=platoqwerty123 \ + --set backendService.httpProxyTokenReceiverUrl=http://backend:8080 \ + --wait-for-jobs --timeout=120s +``` + +### 4. Install Socrates as consumer EDC +```shell +helm install sokrates charts/tractusx-connector -n business-tests --create-namespace \ + --set fullnameOverride=sokrates \ + --set controlplane.service.type=NodePort \ + --set controlplane.endpoints.data.authKey=password \ + --set controlplane.image.pullPolicy=Never \ + --set controlplane.image.tag=latest \ + --set controlplane.image.repository=edc-controlplane-postgresql-hashicorp-vault \ + --set dataplane.image.tag=latest \ + --set dataplane.image.pullPolicy=Never \ + --set dataplane.image.repository=edc-dataplane-hashicorp-vault \ + --set controlplane.debug.enabled=true \ + --set controlplane.suspendOnStart=false \ + --set postgresql.enabled=true \ + --set postgresql.username=user \ + --set postgresql.password=password \ + --set postgresql.jdbcUrl=jdbc:postgresql://sokrates-postgresql:5432/edc \ + --set vault.hashicorp.enabled=true \ + --set vault.hashicorp.url=http://vault:8200 \ + --set vault.hashicorp.token=root \ + --set vault.secretNames.transferProxyTokenSignerPublicKey=sokrates/daps/my-sokrates-daps-crt \ + --set vault.secretNames.transferProxyTokenSignerPrivateKey=sokrates/daps/my-sokrates-daps-key \ + --set vault.secretNames.transferProxyTokenEncryptionAesKey=sokrates/data-encryption-aes-keys \ + --set vault.secretNames.dapsPrivateKey=sokrates/daps/my-sokrates-daps-key \ + --set vault.secretNames.dapsPublicKey=sokrates/daps/my-sokrates-daps-crt \ + --set daps.url=http://ids-daps:4567 \ + --set daps.clientId=E7:07:2D:74:56:66:31:F0:7B:10:EA:B6:03:06:4C:23:7F:ED:A6:65:keyid:E7:07:2D:74:56:66:31:F0:7B:10:EA:B6:03:06:4C:23:7F:ED:A6:65 \ + --set dataplane.aws.endpointOverride=http://minio:9000 \ + --set dataplane.aws.secretAccessKey=sokratesqwerty123 \ + --set dataplane.aws.accessKeyId=sokratesqwerty123 \ + --set backendService.httpProxyTokenReceiverUrl=http://backend:8080 \ + --wait-for-jobs --timeout=120s +``` + +### 5. Set environment variables and run configuration in IDE +You can create a run configuration in IntelliJ like bellow screenshot and copy/paste the whole set of environments variables if you use ";" after each line. +![](run-config.png) + +```shell +PLATO_BACKEND_SERVICE_BACKEND_API_URL=http://localhost:; +PLATO_DATA_MANAGEMENT_API_AUTH_KEY=password; +PLATO_DATA_MANAGEMENT_URL=http://localhost:/data; +PLATO_DATA_PLANE_URL=foo; +PLATO_DATABASE_PASSWORD=password; +PLATO_DATABASE_URL=jdbc:postgresql://localhost:5555/edc; +PLATO_DATABASE_USER=user; +PLATO_IDS_URL=http://plato-controlplane:8084/api/v1/ids; +PLATO_AWS_SECRET_ACCESS_KEY=platoqwerty123; +PLATO_AWS_ACCESS_KEY_ID=platoqwerty123; +SOKRATES_BACKEND_SERVICE_BACKEND_API_URL=http://localhost:; +SOKRATES_BACKEND_URL=http://localhost:; +SOKRATES_DATA_MANAGEMENT_API_AUTH_KEY=password; +SOKRATES_DATA_MANAGEMENT_URL=http://localhost:/data; +SOKRATES_DATA_PLANE_URL=foo; +SOKRATES_DATABASE_PASSWORD=password; +SOKRATES_DATABASE_URL=jdbc:postgresql://localhost:6666/edc; +SOKRATES_DATABASE_USER=user; +SOKRATES_IDS_URL=http://sokrates-controlplane:8084/api/v1/ids; +SOKRATES_AWS_SECRET_ACCESS_KEY=sokratesqwerty123; +SOKRATES_AWS_ACCESS_KEY_ID=sokratesqwerty123; +EDC_AWS_ENDPOINT_OVERRIDE=http://localhost:32000 +``` + +The services are using NodePort to expose the endpoints therefore the ports are not fix and needs to be determined after each deployment. +To determine the current ports you can use the following kubectl command: +```shell +kubectl get svc -n business-tests -o go-template='{{range .items}}{{ $save := . }}{{range.spec.ports}}{{if .nodePort}}{{$save.metadata.namespace}}{{"/"}}{{$save.metadata.name}}{{" - "}}{{.name}}{{": "}}{{.nodePort}}{{"("}}{{.port}}{{")"}}{{"\n"}}{{end}}{{end}}{{end}}' +``` +This will return all NodePorts which are available in business-tests namespace where you can pick the ports to use in your environment variables. +Now you are able to run it in IDE either as normal "Run" mode or in "Debug" mode where you can debug the business-tests by setting debugging points. + +### 6. Update your components +Once everything is installed you just need to update your services when you have a new image. +```shell +helm upgrade plato charts/tractusx-connector --recreate-pods +helm upgrade sokrates charts/tractusx-connector --recreate-pods +``` + +### 7. Tips +If you use the kubernetes within Docker Desktop you have direct access to the images which you have created with Docker Desktop they are using the same docker daemon. So you don't need to transfer it in your k8s cluster. diff --git a/docs/development/decision-records/2023-02-27_testing/README.md b/docs/development/decision-records/2023-02-27_testing/README.md new file mode 100644 index 000000000..fa4b803e1 --- /dev/null +++ b/docs/development/decision-records/2023-02-27_testing/README.md @@ -0,0 +1,86 @@ +# Testing concept for product-edc + +## Decision + +Henceforth, testing shall be done in accordance with the herein outlined rules and definitions. As the guiding principles we shall establish: + +- separation-of-concerns +- fast test execution speed +- debuggability +- low resource footprint +- leverage features provided by, and adopt standards set by the [Eclipse Dataspace Project](https://github.com/eclipse-edc/Connector) +- easy setup on developer systems + +## Rationale + +Past experiences with product-edc's testing setup has shown that it is time- and resource-consuming, which also makes it unreliable at times. +Furthermore, a finer-grained test classification such as the one outlined in this document is currently neither present nor documented. + +### Definitions and distinction + +This section is largely taken from the [EDC's testing documentation](https://github.com/eclipse-edc/Connector/blob/bab97cccf4d61a3a380a1d70925b34f4cec1b401/docs/developer/testing.md) with a few amendments. + +- **unit tests**: test one single class by mocking/stubbing all collaborating objects. + +- **integration tests**: test one particular aspect of a software, that may involve external systems. Example: testing a particular object store based on PostgreSQL. External systems are to be provided out-of-band, e.g. through a CI pipeline or a script that runs on a local machine. Starting external systems from code violates the separation of concerns and it may also cause problems on some systems, e.g. when docker is not on the `PATH`, or not available at all. Integration tests typically only involve parts of a connector. A _component test_ is a special form of an integration test, where real collaborators, but no external systems are used. + +- **system tests**: rely on the _entire system_ being present. This is specific for each variant, for example testing a request against a system's API and verifying that a particular entry was created in the database. System tests involve _one connector_ and the external service. + +- **end-to-end-tests**: similar to system tests, but they involve several connectors plus external services such as databases, identity providers, objects stores, etc. This type of test is used to verify that certain business requirements are fulfilled by simulating real user scenarios from start to finish, hence they are sometimes dubbed "business tests". For example, one would send a data request to a connector's public API and expect the connector to behave in a certain way and expect a certain response back. To keep things simple, end-to-end tests can be conjoined with system tests. + +- **deployment tests**: tests deployment artifacts such a Docker images or a Helm charts. The purpose of such a test is to verify the correct configuration and composition of an artifact, its purpose is _not_ to test application logic. However, we can use normal requests to _verify_ the correct installation. Sometimes this is referred to as "Smoke test". + +- **performance tests**: measure whether a certain iteration of the software fulfills pre-established performance goals. These tests are highly specific and may have dependencies onto specific hardware and network parameters. + +It is a [well-established](https://martinfowler.com/articles/practical-test-pyramid.html) fact that unit tests should make up for the majority of tests, because they are easy and quick to write and quick to execute, whereas integration and end-to-end tests are usually more complex and time-consuming to write and run. + +## Approach + +Generally we should aim at writing unit tests rather than integration tests, because they are simpler, more stable and typically run faster. Sometimes that's not (easily) possible, especially when an implementation relies on an external system that is not easily mocked or stubbed such as cloud-based databases. + +Therefore, in many cases writing unit tests is more involved that writing an integration test, for example say we wanted to test our implementation of a PostgreSQL-backed queue. We would have to mock the behaviour of the PostgreSQL API, which - while certainly possible - can get complicated pretty quickly. Now we still might do that for simpler scenarios, but +eventually we might want to write an integration test that uses a (containerized) PostgreSQL test instance. + +### Adopt a "local-first" mindset + +EDC provides a way to launch (multiple) embedded connector runtimes from within the JVM using the JUnit runner, see [this module](https://github.com/eclipse-edc/Connector/tree/main/system-tests/e2e-transfer-test/runner/src/test/java/org/eclipse/edc/test/e2e) and the [test runtime extension](https://github.com/eclipse-edc/Connector/blob/main/core/common/junit/src/main/java/org/eclipse/edc/junit/extensions/EdcRuntimeExtension.java) for reference. All tests except deployment tests should be implemented using this feature to offer an easily debuggable and maintainable test suite. We call this a "local first" mindset, because we primarily aim at running a test locally (possibly using manual setup of external services). Once we have that, we can execute the test in the same way on CI runners. It should not matter whether we run tests on developer machines or on CI runners. + +> As a general rule of thumb, we should aim at running as much code from the JVM as opposed to: in external runtimes such as Docker or Kubernetes. + +### Running tests in CI + +External systems such as databases or identity providers should be setup "out-of-band" of the test, using a script or the CI pipeline's declarative syntax (e.g. GitHub Actions' `services` feature). If possible, we should employ external systems in a self-contained way, e.g. using docker containers, because that increases portability and decreases the potential for conflict, e.g. in always-on databases. + +### DO: + +- use integration tests sparingly and only when unit tests are not practical +- deploy the external system as service directly in the workflow or +- use a dedicated always-on test instance if provisioning is complicated and time-consuming (e.g. CosmosDB) +- adopt a local-first mindset, i.e. aim at running test code inside the JVM. +- take into account that external systems might experience transient failures or have degraded performance, so test + methods should have a timeout so as not to block the runner indefinitely. +- use randomized strings for things like database/table/bucket/container names, etc., especially when the external + system does not get destroyed after the test. +- use the class annotations provided by EDC to categorize and configure test execution + +### DO NOT: + +- try to cover everything with integration tests. It's typically a code smell if there are no corresponding unit tests + for an integration test. +- slip into a habit of testing the external system rather than your usage of it +- store secrets directly in the code. Github will warn about that. +- perform complex external system setup in @BeforeEach or @BeforeAll +- write tests that are opaque, or can only run in certain enviroments +- use Test Containers, as it violates the separation of concerns. If external systems are needed, it should be an integration test. + +## Test execution strategies + +This section explains _at which point in time_ we should execute which test. This is intended to minimize the impact on overall test execution time on CI, while still maintaining sufficient coverage. + +| Test type | When to run | Remarks | +| ---------------------- | ----------------------------------------------------------------------------------- | ------- | +| Unit test | when running tests locally, without any parameters, on every commit on every branch | | +| Integration test | on every commit on every branch | | +| System/End-To-End test | on pull request branches except when marked as `draft` | | +| Deployment test | before merging pull requests and on every commit on `develop` | | +| Performance test | Only on a specific schedule, e.g. once per day or week | | diff --git a/docs/development/decision-records/2023-03-02_gradle_build/README.md b/docs/development/decision-records/2023-03-02_gradle_build/README.md new file mode 100644 index 000000000..0f8e7b327 --- /dev/null +++ b/docs/development/decision-records/2023-03-02_gradle_build/README.md @@ -0,0 +1,48 @@ +# Migration to Gradle + +## Decision + +Product-EDC will move to Gradle as its build system. This decision +record outlines the reasoning behind the decision as well as the migration path. + +## Rationale + +The primary motivator for migrating to Gradle is the overarching goal, set by the board of Catena-X, of pursuing an +open-source methodology in general, and to track the Eclipse Datasource Components project in particular. While in +theory that could be achieved with any build tool, much of what is useful or even necessary to achieve that goal, such +as publishing to OSSRH/Sonatype and - in further consequence - to MavenCentral, has already been implemented in the EDC +project. This reduces the implementation and maintenance surface of product-edc with regard to the build, documentation +and testing, and hence increases the development velocity considerably. + +It is therefore a foregone conclusion to rely on technology that has already proven itself in the opensource community, +instead of re-implementing (and maintaining) the same functionality all over again. + +In detail, the aforementioned features are: + +- automatic and structured documentation using the `autodoc` plugin +- generating unified OpenAPI documentation +- default module dependencies +- default configuration (POM, Swagger, artifact signing, code style,...) +- default plugins for project submodules +- publishing to artifact repositories (OSSRH/Sonatype and Maven) +- unified and core-maintained version catalogs and version resolution strategies to avoid version clashes and runtime + errors + +This also contributes to much smaller, easier readable and more succinct build files. Since the build itself is +executable code, a high degree of customization, optimization and modularization is possible. + +Furthermore, developers can expect a much improved experience due to Gradle features like caching, task avoidance and +parallelization resulting in faster and more responsive builds. + +## Approach + +- convert Maven POMs to `build.gradle.kts` files, including BOMs +- generate docker images using [this plugin](https://github.com/bmuschko/gradle-docker-plugin) +- convert maven profiles -> JUnit tags (cf. EDC): run tests using JUnit `@Tag`s and the `includeBuild` feature +- adapt documentation (i.e. exchange the commands) + +## Further consideration + +Planned improvements regarding the testing procedure (PR https://github.com/catenax-ng/product-edc/pull/781) will also greatly benefit from the EDC build tools such +as JUnit tags and conditional evaluation of the tagged tests. Much of EDC's testing framework is based on Gradle and can +be seamlessly integrated in product-edc. diff --git a/docs/development/postman/README.md b/docs/development/postman/README.md new file mode 100644 index 000000000..a6f5005b9 --- /dev/null +++ b/docs/development/postman/README.md @@ -0,0 +1,27 @@ +# Postman Collection + +## Prerequisites + +[![Postman][postman-shield]][postman-url] + +## Postman + +The Postman app can be used to send and receive EDC messages. + +### Install/Download Postman +please visit https://www.postman.com/downloads/ + +### Import Postman collection? +please visit https://learning.postman.com/docs/getting-started/importing-and-exporting-data/ + +## Collection + +The postman collection contains the most common API calls. Please note hat the + +- Policy & Negotiation calls come in pairs for the different kinds of policies +- The 'Data' call only works when using the All-In-One Deployment of this repository + +![screenshot](./images/screenshot.png) + +[postman-shield]: https://img.shields.io/badge/Postman-URL-orange +[postman-url]: https://www.postman.com \ No newline at end of file diff --git a/docs/development/postman/collection.json b/docs/development/postman/collection.json new file mode 100644 index 000000000..5f44e6ee5 --- /dev/null +++ b/docs/development/postman/collection.json @@ -0,0 +1,852 @@ +{ + "info": { + "_postman_id": "b61c0075-e360-45df-9756-c9bc432fe76a", + "name": "EDC", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "6134257" + }, + "item": [ + { + "name": "Asset", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/assets/{{ASSET_ID}}", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "assets", + "{{ASSET_ID}}" + ] + } + }, + "response": [] + }, + { + "name": "Assets", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/assets", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "assets" + ] + } + }, + "response": [] + }, + { + "name": "Asset", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 201\", function () {", + " pm.response.to.have.status(201);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"asset\": {\n \"properties\": {\n \"asset:prop:id\": \"{{ASSET_ID}}\",\n \"asset:prop:description\": \"Product EDC Demo Asset\"\n }\n },\n \"dataAddress\": {\n \"properties\": {\n \"type\": \"HttpData\",\n \"baseUrl\": \"https://jsonplaceholder.typicode.com/todos/1\"\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/assets", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "assets" + ] + } + }, + "response": [] + }, + { + "name": "Asset", + "request": { + "method": "DELETE", + "header": [], + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/assets/{{ASSET_ID}}", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "assets", + "{{ASSET_ID}}" + ] + } + }, + "response": [] + }, + { + "name": "Policy", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": []\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/policydefinitions/{{POLICY_ID}}", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "policydefinitions", + "{{POLICY_ID}}" + ] + } + }, + "response": [] + }, + { + "name": "Policies", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": []\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/policydefinitions", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "policydefinitions" + ] + } + }, + "response": [] + }, + { + "name": "Policy (Public)", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": []\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/policydefinitions", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "policydefinitions" + ] + } + }, + "response": [] + }, + { + "name": "Policy (Properties)", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": []\n }\n ],\n \"extensibleProperties\": {\n \"foo\": \"bar\"\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/policydefinitions", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "policydefinitions" + ] + } + }, + "response": [] + }, + { + "name": "Policy (BPN)", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": [\n {\n \"edctype\": \"AtomicConstraint\",\n \"leftExpression\": {\n \"edctype\": \"dataspaceconnector:literalexpression\",\n \"value\": \"BusinessPartnerNumber\"\n },\n \"rightExpression\": {\n \"edctype\": \"dataspaceconnector:literalexpression\",\n \"value\": \"{{POLICY_BPN}}\"\n },\n \"operator\": \"EQ\"\n }\n ]\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/policydefinitions", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "policydefinitions" + ] + } + }, + "response": [] + }, + { + "name": "Policy", + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": []\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/policydefinitions/{{POLICY_ID}}", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "policydefinitions", + "{{POLICY_ID}}" + ] + } + }, + "response": [] + }, + { + "name": "Contract Definition", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": []\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/contractdefinitions/{{POLICY_ID}}", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "contractdefinitions", + "{{POLICY_ID}}" + ] + } + }, + "response": [] + }, + { + "name": "Contract Definitiions", + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": []\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/contractdefinitions", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "contractdefinitions" + ] + } + }, + "response": [] + }, + { + "name": "Contract Definitiion", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{CONTRACT_DEFINITION_ID}}\",\n \"criteria\": [\n {\n \"operandLeft\": \"asset:prop:id\",\n \"operator\": \"=\",\n \"operandRight\": \"{{ASSET_ID}}\"\n }\n ],\n \"accessPolicyId\": \"{{ACCESS_POLICY_ID}}\",\n \"contractPolicyId\": \"{{CONTRACT_POLICY_ID}}\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/contractdefinitions", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "contractdefinitions" + ] + } + }, + "response": [] + }, + { + "name": "Contract Definition", + "request": { + "method": "DELETE", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"{{POLICY_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"constraints\": []\n }\n ]\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{PROVIDER_DATAMGMT_URL}}/data/contractdefinitions/{{POLICY_ID}}", + "host": [ + "{{PROVIDER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "contractdefinitions", + "{{POLICY_ID}}" + ] + } + }, + "response": [] + }, + { + "name": "Catalog", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/catalog?providerUrl={{PROVIDER_IDS_URL}}/api/v1/ids/data&size=50", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "catalog" + ], + "query": [ + { + "key": "providerUrl", + "value": "{{PROVIDER_IDS_URL}}/api/v1/ids/data" + }, + { + "key": "size", + "value": "50" + } + ] + } + }, + "response": [] + }, + { + "name": "Query Catalog", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"providerUrl\": \"{{PROVIDER_IDS_URL}}/api/v1/ids/data\",\r\n \"querySpec\": {\r\n \"offset\": 0,\r\n \"limit\": 100,\r\n \"filter\": \"\",\r\n \"range\": {\r\n \"from\": 0,\r\n \"to\": 100\r\n },\r\n \"sortOrder\": \"ASC\",\r\n \"sortField\": \"\"\r\n }\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/catalog/request", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "catalog", + "request" + ] + } + }, + "response": [] + }, + { + "name": "Negotation", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/contractnegotiations/{{NEGOTIATION_ID}}", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "contractnegotiations", + "{{NEGOTIATION_ID}}" + ] + } + }, + "response": [] + }, + { + "name": "Negotation (Public)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Body matches string\", function () {", + " var jsonData = pm.response.json();", + " pm.collectionVariables.set(\"NEGOTIATION_ID\", jsonData.id);", + "", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"connectorId\": \"foo\",\n \"connectorAddress\": \"{{PROVIDER_IDS_URL}}/api/v1/ids/data\",\n \"offer\": {\n \"offerId\": \"{{CONTRACT_DEFINITION_ID}}:foo\",\n \"assetId\": \"{{ASSET_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"target\": \"{{ASSET_ID}}\",\n \"constraints\": []\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/contractnegotiations", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "contractnegotiations" + ] + } + }, + "response": [] + }, + { + "name": "Negotation (Properties)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Body matches string\", function () {", + " var jsonData = pm.response.json();", + " pm.collectionVariables.set(\"NEGOTIATION_ID\", jsonData.id);", + "", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"connectorId\": \"foo\",\n \"connectorAddress\": \"{{PROVIDER_IDS_URL}}/api/v1/ids/data\",\n \"offer\": {\n \"offerId\": \"{{POLICY_ID}}:foo\",\n \"assetId\": \"{{ASSET_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"target\": \"{{ASSET_ID}}\",\n \"constraints\": []\n }\n ],\n \"extensibleProperties\": {\n \"foo\": \"bar\"\n }\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/contractnegotiations", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "contractnegotiations" + ] + } + }, + "response": [] + }, + { + "name": "Negotation (BPN)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Body matches string\", function () {", + " var jsonData = pm.response.json();", + " pm.collectionVariables.set(\"NEGOTIATION_ID\", jsonData.id);", + "", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"connectorId\": \"foo\",\n \"connectorAddress\": \"{{PROVIDER_IDS_URL}}/api/v1/ids/data\",\n \"offer\": {\n \"offerId\": \"{{POLICY_ID}}:foo\",\n \"assetId\": \"{{ASSET_ID}}\",\n \"policy\": {\n \"prohibitions\": [],\n \"obligations\": [],\n \"permissions\": [\n {\n \"edctype\": \"dataspaceconnector:permission\",\n \"action\": {\n \"type\": \"USE\"\n },\n \"target\": \"{{ASSET_ID}}\",\n \"constraints\": [\n {\n \"edctype\": \"AtomicConstraint\",\n \"leftExpression\": {\n \"edctype\": \"dataspaceconnector:literalexpression\",\n \"value\": \"BusinessPartnerNumber\"\n },\n \"rightExpression\": {\n \"edctype\": \"dataspaceconnector:literalexpression\",\n \"value\": \"{{POLICY_BPN}}\"\n },\n \"operator\": \"EQ\"\n }\n ]\n }\n ]\n }\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/contractnegotiations", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "contractnegotiations" + ] + } + }, + "response": [] + }, + { + "name": "Transfer", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "pm.collectionVariables.set(\"TRANSFER_ID\", Math.random());" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Body matches string\", function () {", + " var jsonData = pm.response.json();", + " pm.collectionVariables.set(\"TRANSFER_PROCESS_ID\", jsonData.id);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{ \"id\": \"{{TRANSFER_ID}}\",\n \"connectorId\": \"foo\", \n \"connectorAddress\": \"{{PROVIDER_IDS_URL}}/api/v1/ids/data\", \n \"contractId\": \"{{AGREEMENT_ID}}\", \n \"assetId\": \"{{ASSET_ID}}\",\n \"managedResources\": \"false\", \n \"dataDestination\": { \"type\": \"HttpProxy\" }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/transferprocess", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "transferprocess" + ] + } + }, + "response": [] + }, + { + "name": "Transfer dynamic http receiver", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "pm.collectionVariables.set(\"TRANSFER_ID\", Math.random());" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Body matches string\", function () {", + " var jsonData = pm.response.json();", + " pm.collectionVariables.set(\"TRANSFER_PROCESS_ID\", jsonData.id);", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{ \"id\": \"{{TRANSFER_ID}}\",\n \"connectorId\": \"foo\", \n \"connectorAddress\": \"{{PROVIDER_IDS_URL}}/api/v1/ids/data\", \n \"contractId\": \"{{AGREEMENT_ID}}\", \n \"assetId\": \"{{ASSET_ID}}\",\n \"managedResources\": \"false\", \n \"dataDestination\": { \"type\": \"HttpProxy\" },\n \"properties\": {\n \"receiver.http.endpoint\": \"{{BACKEND_SERVICE}}\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/transferprocess", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "transferprocess" + ] + } + }, + "response": [] + }, + { + "name": "Transfer", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{CONSUMER_DATAMGMT_URL}}/data/transferprocess/{{TRANSFER_PROCESS_ID}}", + "host": [ + "{{CONSUMER_DATAMGMT_URL}}" + ], + "path": [ + "data", + "transferprocess", + "{{TRANSFER_PROCESS_ID}}" + ] + } + }, + "response": [] + } + ], + "auth": { + "type": "apikey", + "apikey": [ + { + "key": "value", + "value": "", + "type": "string" + }, + { + "key": "key", + "value": "X-Api-Key", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "CONSUMER_DATAMGMT_URL", + "value": "https://sokrates-txdc.int.demo.catena-x.net" + }, + { + "key": "PROVIDER_IDS_URL", + "value": "https://plato-txdc.int.demo.catena-x.net" + }, + { + "key": "PROVIDER_DATAMGMT_URL", + "value": "https://plato-txdc.int.demo.catena-x.net" + }, + { + "key": "ASSET_ID", + "value": "1", + "type": "default" + }, + { + "key": "POLICY_ID", + "value": "1", + "type": "default" + }, + { + "key": "CONTRACT_POLICY_ID", + "value": "1", + "type": "default" + }, + { + "key": "ACCESS_POLICY_ID", + "value": "1", + "type": "default" + }, + { + "key": "CONTRACT_DEFINITION_ID", + "value": "1", + "type": "default" + }, + { + "key": "POLICY_BPN", + "value": "BPNSOKRATES", + "type": "default" + }, + { + "key": "NEGOTIATION_ID", + "value": "" + }, + { + "key": "AGREEMENT_ID", + "value": "" + }, + { + "key": "TRANSFER_ID", + "value": "" + }, + { + "key": "TRANSFER_PROCESS_ID", + "value": "" + }, + { + "key": "BACKEND_SERVICE", + "value": "http://backend:8080", + "type": "string" + } + ] +} \ No newline at end of file diff --git a/docs/development/postman/images/screenshot.png b/docs/development/postman/images/screenshot.png new file mode 100644 index 000000000..8a9d231c6 Binary files /dev/null and b/docs/development/postman/images/screenshot.png differ diff --git a/docs/development/run-config.png b/docs/development/run-config.png new file mode 100644 index 000000000..4be2d85ad Binary files /dev/null and b/docs/development/run-config.png differ diff --git a/docs/development/scripts/daps_token/README.md b/docs/development/scripts/daps_token/README.md new file mode 100644 index 000000000..aaeb49253 --- /dev/null +++ b/docs/development/scripts/daps_token/README.md @@ -0,0 +1,22 @@ +# DAPS Token Script + +Script to request an IDS token from the DAPS. + +## Usage + +1. Copy your DAPS private key into `key.pem` +2. Edit in the script the following variables + - `token_url` + - `client_id` + - `resource` +3. Run script + +```bash +./daps_auth_sh +``` + +4. Take the `access_token` from the output in use it in IDS messages +Script output: +```json +{"access_token":"eyJ0eXAiOiJhdCtqd3QiLCJraWQiOiI3MDM2MzAwNzVkYTM2N2IxYmZiYjRjY2Q0N2M1Y2ViMGQ5ZjM1MmRmYWU2MzJkMzYxMGMxNzNmMTM1NDI0NmM5IiwiYWxnIjoiUlMyNTYifQ.eyJzY29wZSI6Imlkc2M6SURTX0NPTk5FQ1RPUl9BVFRSSUJVVEVTX0FMTCIsImF1ZCI6WyJodHRwczovL3Blbi10ZXN0LXBsYXRvLXR4ZGMuaW50LmRlbW8uY2F0ZW5hLXgubmV0L2FwaS92MS9pZHMvZGF0YSJdLCJpc3MiOiJodHRwOi8vaWRzLWRhcHM6NDU2Ny8iLCJzdWIiOiI5OTo4MzpBNzoxNzo4NjpGRjo5ODo5MzpDRTpBMDpERDpBMTpGMTozNjpGQTpGNjowRjo3NTowQToyMzprZXlpZDo5OTo4MzpBNzoxNzo4NjpGRjo5ODo5MzpDRTpBMDpERDpBMTpGMTozNjpGQTpGNjowRjo3NTowQToyMyIsIm5iZiI6MTY3ODMxMDE0OSwiaWF0IjoxNjc4MzEwMTQ5LCJqdGkiOiJkZmY5Y2FmOS05NDZiLTQ1YmMtOWY4My0yYmJkMDI4NTlmYWMiLCJleHAiOjE2NzgzMTM3NDksImNsaWVudF9pZCI6Ijk5OjgzOkE3OjE3Ojg2OkZGOjk4OjkzOkNFOkEwOkREOkExOkYxOjM2OkZBOkY2OjBGOjc1OjBBOjIzOmtleWlkOjk5OjgzOkE3OjE3Ojg2OkZGOjk4OjkzOkNFOkEwOkREOkExOkYxOjM2OkZBOkY2OjBGOjc1OjBBOjIzIiwicmVmZXJyaW5nQ29ubmVjdG9yIjoiaHR0cDovL3BsYXRvLWNvbnRyb2xwbGFuZS9CUE5QTEFUTyJ9.JQqt9gCpaG7rLztO5-pJa7HIybVjKog9v0CFXHoVJZgdxMc5nTKZnuwBVHC1PXuWrBiyPxPoNg0TsfRg9DqF8rFD5noarxOJ1S84BF7AUUi3phQzBF26lsmNmOW_gdNBC-8xw1WMo5hRHH56cB64_x4V8T4VwFlSYYrmA5ge_EiPCW_KWF9sNguXBKs8uTbLB3lvTELGTjmZI93tVR-vYuYzW2jxH1PJNW29KJRQcM0D1AiveMs3_ThRjheEvugyh9QIY1RwPXMgYQpSTvoumNuFFTnpR21ueWfSUtU-4Qu9suNTkcaFihvEObXVrhyMja-HjhQaC8i0XsAgY0tT1A","expires_in":3600,"token_type":"bearer","scope":"idsc:IDS_CONNECTOR_ATTRIBUTES_ALL"}% +``` diff --git a/docs/development/scripts/daps_token/daps_auth.sh b/docs/development/scripts/daps_token/daps_auth.sh new file mode 100755 index 000000000..2835a2e61 --- /dev/null +++ b/docs/development/scripts/daps_token/daps_auth.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +#################################################### +# Update these variables before running the script # +#################################################### +token_url="https://mydaps/token" +client_id="99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FF:F6:0F:75:0A:23:keyid:99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:24" +# resource is later used as token audience, so it must be the IDS url of the token receiving connector +resource="https://receiving-connector/api/v1/ids/data" + + +base64_encode() +{ + declare input=${1:-$(", + "prohibitions": [], + "obligations": [], + "permissions": [ + { + "edctype": "dataspaceconnector:permission", + "action": { + "type": "USE" + }, + "constraints": [ + { + "edctype": "AtomicConstraint", + "leftExpression": { + "edctype": "dataspaceconnector:literalexpression", + "value": "BusinessPartnerNumber" + }, + "rightExpression": { + "edctype": "dataspaceconnector:literalexpression", + "value": [ + "", + "" + ] + }, + "operator": "IN" + } + ] + } + ] +} +``` + +The BPN extension will now always decline BPN policies with 'IN' operators, when asked by the EDC to enforce it. + +## 2.2 HashiCorp Vault Extension + +It is now possible to arrange HashiCorp Vault secrets in sub-directories. + +For example by storing the DAPS secrets in their own `/daps` directory: + +``` +EDC_OAUTH_PRIVATE_KEY_ALIAS: daps/my-plato-daps-key +EDC_OAUTH_PUBLIC_KEY_ALIAS: daps/my-plato-daps-crt +``` + +## 2.3 OAuth2 Extension + +The EDC Oauth2 Extension has now the possibility to add the audience to the claim. As the official OAuth2 Extension was +added to the control plane again most of the functionality of the CX Oauth2 Extension was removed. + +> **Breaking Change** The official OAuth2 Extension uses different settings then the EDC OAuth Extension. Please +> consolidate the [Migration Documentation](../migration/Version_0.1.2_0.1.3.md). + +# 3. Bug Fixes + +## 3.1 S3 Data Transfer + +Version 0.1.2 had some issues with the S3 data transfer. This version fixes them. \ No newline at end of file diff --git a/docs/release-notes/Version 0.1.5.md b/docs/release-notes/Version 0.1.5.md index 5b7fbff54..37bac446f 100644 --- a/docs/release-notes/Version 0.1.5.md +++ b/docs/release-notes/Version 0.1.5.md @@ -5,10 +5,10 @@ ## 0. Summary 1. [Version updates](#1-version-updates) - - Use patched EDC version: 0.0.1-20220922.2-SNAPSHOT + - Use patched EDC version: 0.0.1-20220922.2-SNAPSHOT 2. [Extensions](#2-extensions) - - [2.1 Data Encryption Extension](#22-data-encryption-extension) - - Fixed usage of a blocking algorithm + - [2.1 Data Encryption Extension](#22-data-encryption-extension) + - Fixed usage of a blocking algorithm ## 1. Version Updates @@ -22,4 +22,4 @@ catalog pagination. [GitHub issue](https://github.com/eclipse-edc/Connector/issu ### 2.2 Data Encryption Extension The encryption of the `EndpointDataReference` took up to 3 minutes unter certain circumstances. -This was fixed by using a not blocking algorithm and setting the Java CMD flag `java.security.egd` correctly. +This was fixed by using a not blocking algorithm and setting the Java CMD flag `java.security.egd` correctly. \ No newline at end of file diff --git a/docs/samples/Local TXDC Setup.md b/docs/samples/Local TXDC Setup.md new file mode 100644 index 000000000..8117dc05d --- /dev/null +++ b/docs/samples/Local TXDC Setup.md @@ -0,0 +1,124 @@ +# Local TXDC Setup + +This document describes how to set up two TXDConnector instances locally. The Supporting Infrastructure Deployment, used +by this example, must never be used productively. The deployment of the two TXDConnector instances, done by this example, +is not suitable for productive deployment scenarios. + +## Prerequisites + +[![Helm][helm-shield]][helm-url] + +[![Kubernetes][kubernets-shield]][kubernets-url] + +## Local Deployment + +The Local TXDC Setup consists of three separate deployments. The Supporting Infrastructure, that is required to +run connectors, and two different TXDC Connector instances, that can communicate with each other. + +- [TXDC Supporting Infrastructure](../../edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/README.md) +- [TXDC Connector](../../charts/tractusx-connector/README.md) Plato +- [TXDC Connector](../../charts/tractusx-connector/README.md) Sokrates + +[helm-shield]: https://img.shields.io/badge/Helm-URL-lightgrey + +[helm-url]: https://helm.sh + +[kubernets-shield]: https://img.shields.io/badge/Kubernetes-URL-lightgrey + +[kubernets-url]: https://kubernetes.io/ + +### Supporting Infrastructure + +Before the connectors can be setup, the Supporting Infrastructure must be in place. It comes with pre-configured everything +to run two connectors independently. + +For this local test scenario, +the [Supporting Infrastructure](../../edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/README.md) +of the TXDC Business Tests can be used. + +Install the TXDC Supporting Infrastructure by running the following command from the project root directory. The Minio +set can be skipped, as it's only used by AWS S3 Transfer Business Tests. Also, the PostgreSQL Database is not really +mandatory to try out the EDC. So it can be disabled as well. + +```sh +helm dependency update edc-tests/src/main/resources/deployment/helm/supporting-infrastructure +``` + +```sh +helm install infrastructure edc-tests/src/main/resources/deployment/helm/supporting-infrastructure \ + --namespace cx \ + --create-namespace \ + --set install.minio=false \ + --set install.postgresql=false +``` + +### Plato Connector + +After the supporting infrastructure is deployed the Plato Connector can be added. The Supporting Infrastructure +Deployment has a DAPS Client and Vault Secrets configured accordingly. So that the TXDConnector can use them directly. + +Install Plato by running the following command from the project root directory. + +```sh +helm install plato charts/tractusx-connector \ + --namespace cx \ + --create-namespace \ + --set fullnameOverride=plato \ + --set controlplane.image.tag=0.2.0 \ + --set controlplane.service.type=NodePort \ + --set controlplane.endpoints.data.authKey=password \ + --set vault.hashicorp.enabled=true \ + --set vault.hashicorp.url=http://vault:8200 \ + --set vault.hashicorp.token=root \ + --set vault.secretNames.transferProxyTokenSignerPublicKey=plato/daps/my-plato-daps-crt \ + --set vault.secretNames.transferProxyTokenSignerPrivateKey=plato/daps/my-plato-daps-key \ + --set vault.secretNames.transferProxyTokenEncryptionAesKey=plato/data-encryption-aes-keys \ + --set vault.secretNames.dapsPrivateKey=plato/daps/my-plato-daps-key \ + --set vault.secretNames.dapsPublicKey=plato/daps/my-plato-daps-crt \ + --set daps.url=http://ids-daps:4567 \ + --set daps.clientId=99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:23:keyid:99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:23 \ + --set backendService.httpProxyTokenReceiverUrl=http://backend:8080 +``` + +The different settings are explained in the [TXDC Connector](../../charts/tractusx-connector/README.md) documentation. +Basically this deployment overrides the full name, to avoid naming conflicts, and sets a NodePort, to access the +containers from outside the local Kubernetes cluster. Then it configures a DAPS instance and the corresponding vault, +where the DAPS secrets are persisted, so that the connector has its own identity. + +### Sokrates Connector + +After Plato is set up the same can be done for Sokrates. The main difference will be, that Sokrates uses another DAPS +Client ID with different public-/private keys. + +Install Sokrates by running the following command from the project root directory. + +```shell +helm install sokrates charts/tractusx-connector \ + --namespace cx \ + --create-namespace \ + --set fullnameOverride=sokrates \ + --set controlplane.image.tag=0.2.0 \ + --set controlplane.service.type=NodePort \ + --set controlplane.endpoints.data.authKey=password \ + --set vault.hashicorp.enabled=true \ + --set vault.hashicorp.url=http://vault:8200 \ + --set vault.hashicorp.token=root \ + --set vault.secretNames.transferProxyTokenSignerPublicKey=sokrates/daps/my-sokrates-daps-crt \ + --set vault.secretNames.transferProxyTokenSignerPrivateKey=sokrates/daps/my-sokrates-daps-key \ + --set vault.secretNames.transferProxyTokenEncryptionAesKey=sokrates/data-encryption-aes-keys \ + --set vault.secretNames.dapsPrivateKey=sokrates/daps/my-sokrates-daps-key \ + --set vault.secretNames.dapsPublicKey=sokrates/daps/my-sokrates-daps-crt \ + --set daps.url=http://ids-daps:4567 \ + --set daps.clientId=E7:07:2D:74:56:66:31:F0:7B:10:EA:B6:03:06:4C:23:7F:ED:A6:65:keyid:E7:07:2D:74:56:66:31:F0:7B:10:EA:B6:03:06:4C:23:7F:ED:A6:65 \ + --set backendService.httpProxyTokenReceiverUrl=http://backend:8080 +``` + +## Uninstall + +```shell +helm uninstall --namespace cx infrastructure +helm uninstall --namespace cx plato +helm uninstall --namespace cx sokrates +``` + +> To try out the local setup, have a look at the [Transfer Example Documentation](Transfer%20Data.md) \ No newline at end of file diff --git a/docs/samples/README.md b/docs/samples/README.md new file mode 100644 index 000000000..fcd5fe8bd --- /dev/null +++ b/docs/samples/README.md @@ -0,0 +1,7 @@ +# Samples + +In this folder are listed some documents that will help you setting up a connector execute some use cases. + +- [Local setup](./Local%20TXDC%20Setup.md) +- [Transfer data](./Transfer%20Data.md) +- [Data Plane HTTP OAuth2](./data-plane-http-oauth2.md) diff --git a/docs/samples/Transfer Data.md b/docs/samples/Transfer Data.md new file mode 100644 index 000000000..f07f685f9 --- /dev/null +++ b/docs/samples/Transfer Data.md @@ -0,0 +1,366 @@ +# Transfer Data + +This document will showcase a data transfer between two connectors. + +For this transfer connector **Bob** will act as data provider, and connector **Alice** will act as data +consumer. But the roles could be inverse as well. + +> Please note: Before running the examples the corresponding environment variables must be set. +> How such an environment can be setup locally is documented in [chapter 0](#0--optional--local-setup). + +**Contents** + +0. [(optional) Local Setup](#0--optional--local-setup) +1. [Setup Data Offer](#1-setup-data-offer) +2. [Request Contract Offers](#2-request-contract-offer-catalog) +3. [Negotiate Contract](#3-negotiate-contract) +4. [Transfer Data](#4-transfer-data) +5. [Verify Data Transfer](#5-verify-data-transfer) + +## 0. (optional) Local Setup + +To create a local setup with two connectors have a look at +the [Local TXDC Setup Documentation](Local%20TXDC%20Setup.md). +It creates two connectors (Plato & Sokrates) with exposed Node Ports. + +### See Node Ports using Minikube + +Run the following command. + +```shell +minkube service list +``` + +Minikube will then print out something like this: + +```shell +|-------------|-----------------------|-----------------|---------------------------| +| NAMESPACE | NAME | TARGET PORT | URL | +|-------------|-----------------------|-----------------|---------------------------| +| cx | backend | frontend/8080 | http://192.168.49.2:31918 | +| | | backend/8081 | http://192.168.49.2:30193 | < Transfer Backend API +| cx | ids-daps | No node port | +| cx | plato-controlplane | default/8080 | http://192.168.49.2:31016 | +| | | control/8083 | http://192.168.49.2:32510 | +| | | data/8081 | http://192.168.49.2:30423 | < Plato Data Management API +| | | validation/8082 | http://192.168.49.2:30997 | +| | | ids/8084 | http://192.168.49.2:32709 | < Plato IDS API +| | | metrics/8085 | http://192.168.49.2:31124 | +| cx | plato-dataplane | No node port | +| cx | sokrates-controlplane | default/8080 | http://192.168.49.2:32297 | +| | | control/8083 | http://192.168.49.2:32671 | +| | | data/8081 | http://192.168.49.2:31772 | < Sokrates Data Management API +| | | validation/8082 | http://192.168.49.2:30540 | +| | | ids/8084 | http://192.168.49.2:32543 | < Sokrates IDS API +| | | metrics/8085 | http://192.168.49.2:30247 | +| cx | sokrates-dataplane | No node port | +| cx | vault | No node port | +| cx | vault-internal | No node port | +| cx | vault-ui | No node port | +| default | kubernetes | No node port | +| kube-system | kube-dns | No node port | +|-------------|-----------------------|-----------------|---------------------------| +``` + +The most important APIs, used by this example, are highlighted. How they are used is described in subchapter ['Set +Environment Variables](#set-environment-variables-used-by-this-example), used by this example below. + +### See Node Ports using Kubernetes + +Using Kubernetes only the Node Ports of each Service must be checked separately. + +Run + +```shell +kubectl describe service -n cx plato-controlplane +``` + +or + +```shell +kubectl describe service -n cx sokrates-controlplane +``` + +Kubernetes will then print out something like this. + +```shell +Name: plato-controlplane +Namespace: cx +Labels: app.kubernetes.io/component=edc-controlplane + app.kubernetes.io/instance=plato-controlplane + app.kubernetes.io/managed-by=Helm + app.kubernetes.io/name=tractusx-connector-controlplane + app.kubernetes.io/part-of=edc + app.kubernetes.io/version=0.2.0 + helm.sh/chart=tractusx-connector-0.2.0 +Annotations: meta.helm.sh/release-name: plato + meta.helm.sh/release-namespace: cx +Selector: app.kubernetes.io/instance=plato-controlplane,app.kubernetes.io/name=tractusx-connector-controlplane +Type: NodePort +IP Family Policy: SingleStack +IP Families: IPv4 +IP: 10.110.180.57 +IPs: 10.110.180.57 +Port: default 8080/TCP +TargetPort: default/TCP +NodePort: default 31016/TCP +Endpoints: 172.17.0.6:8080 +Port: control 8083/TCP +TargetPort: control/TCP +NodePort: control 32510/TCP +Endpoints: 172.17.0.6:8083 +Port: data 8081/TCP +TargetPort: data/TCP +NodePort: data 30423/TCP < Plato Data Manamgent API +Endpoints: 172.17.0.6:8081 +Port: validation 8082/TCP +TargetPort: validation/TCP +NodePort: validation 30997/TCP +Endpoints: 172.17.0.6:8082 +Port: ids 8084/TCP +TargetPort: ids/TCP +NodePort: ids 32709/TCP < Plato IDS API +Endpoints: 172.17.0.6:8084 +Port: metrics 8085/TCP +TargetPort: metrics/TCP +NodePort: metrics 31124/TCP +Endpoints: 172.17.0.6:8085 +Session Affinity: None +External Traffic Policy: Cluster +Events: +``` + +The most important APIs, used by this example, are highlighted. How they are used is described in subchapter ['Set +Environment Variables](#set-environment-variables-used-by-this-example), used by this example below. +In comparison to the Minikube example this call shows only the ports. To call the ports the Kubernetes Node IP / URL is +required. Where to get the IP may vary depending on how Kubernetes is deployed. + +### Set Environment Variables, used by this example + +Environment Variables, containing a URL, used by this example are +- BOB_DATAMGMT_URL +- ALICE_DATAMGMT_URL +- BOB_IDS_URL +- ALICE_BACKEND_URL + +Let's assume we will use Sokrates as Bob, and Plato as Alice. + +**BOB_DATAMGMT_URL** must be the Node URL. In this local setup it would be `http://192.168.49.2:31772` + +**ALICE_DATAMGMT_URL** must be the Node URL. In this local setup it would be `http://192.168.49.2:30423` + +**BOB_IDS_URL** must be internal Kubernetes URL. In this local setup `http://sokrates-controlplane:8084` + +**ALICE_BACKEND_URL** must the Node URL. In this local setup it would be `http://192.168.49.2:30193` + +## 1. Setup Data Offer + +Set up a data offer in **Bob**, so that **Alice** has something to consume. + +In case you are unfamiliar with the EDC terms `Asset`, `Policy` or `ContractDefinition` please have a look at the +official open source documentation ([link](https://github.com/eclipse-edc/Connector/blob/main/docs/developer/architecture/domain-model.md)). + +![Sequence 1](diagrams/transfer_sequence_1.png) + +**Run** + +The following commands will create an Asset, a Policy and a Contract Definition. +For simplicity `https://jsonplaceholder.typicode.com/todos/1` is used as data source of the asset, but could be any +other API, that is reachable from the Provider Data Plane. + +```bash +curl -X POST "${BOB_DATAMGMT_URL}/data/assets" \ + --header 'X-Api-Key: password' \ + --header 'Content-Type: application/json' \ + --data '{ + "asset": { + "properties": { + "asset:prop:id": "1", + "asset:prop:description": "Product EDC Demo Asset" + } + }, + "dataAddress": { + "properties": { + "type": "HttpData", + "baseUrl": "https://jsonplaceholder.typicode.com/todos/1" + } + } + }' \ + -s -o /dev/null -w 'Response Code: %{http_code}\n' +``` + +```bash +curl -X POST "${BOB_DATAMGMT_URL}/data/policydefinitions" \ + --header 'X-Api-Key: password' \ + --header 'Content-Type: application/json' \ + --data '{ + "id": "1", + "policy": { + "prohibitions": [], + "obligations": [], + "permissions": [ + { + "edctype": "dataspaceconnector:permission", + "action": { "type": "USE" }, + "constraints": [] + } + ] + } + }' \ + -s -o /dev/null -w 'Response Code: %{http_code}\n' +``` + +```bash +curl -X POST "${BOB_DATAMGMT_URL}/data/contractdefinitions" \ + --header 'X-Api-Key: password' \ + --header 'Content-Type: application/json' \ + --data '{ + "id": "1", + "criteria": [ + { + "operandLeft": "asset:prop:id", + "operator": "=", + "operandRight": "1" + } + ], + "accessPolicyId": "1", + "contractPolicyId": "1" + }' \ + -s -o /dev/null -w 'Response Code: %{http_code}\n' +``` + +## 2. Request Contract Offer Catalog + +In this step Alice gets told to request contract offers from another connector (in this case Bob). Alice will +then request the catalog over IDS messaging. + +For IDS messaging connectors will identify each other using the configured IDS DAPS. Therefore, it is important that +connectors, that intent to send messages to each other, have the same DAPS instance configured. + +![Sequence 1](diagrams/transfer_sequence_2.png) + +**Run** + +```bash +curl -G -X GET "${ALICE_DATAMGMT_URL}/data/catalog" \ + --data-urlencode "providerUrl=${BOB_IDS_URL}/api/v1/ids/data" \ + --header 'X-Api-Key: password' \ + --header 'Content-Type: application/json' \ + -s | jq +``` + +## 3. Negotiate Contract + +Initiate a contract negotiation for the asset (from step 1). Part of the negotiation payload is the contract +offer (received in step 2). + +In the diagram the IDS contract negotiation is marked as simplified, because the EDC is exchanging multiple messages +during contract negotiation. But the inter-controlplane communication is not in the scope of this document. + +After the negotiation is initiated ensure that is has concluded. This is done by requesting the negotiation from the API +and checking whether the `contractAgreementId` is set. This might take a few seconds. + +![Sequence 1](diagrams/transfer_sequence_3.png) + +**Run** + +```bash +export NEGOTIATION_ID=$( \ + curl -X POST "${ALICE_DATAMGMT_URL}/data/contractnegotiations" \ + --header "X-Api-Key: password" \ + --header "Content-Type: application/json" \ + --data "{ + \"connectorId\": \"foo\", + \"connectorAddress\": \"${BOB_IDS_URL}/api/v1/ids/data\", + \"offer\": { + \"offerId\": \"1:foo\", + \"assetId\": \"1\", + \"policy\": { + \"uid\": \"1\", + \"prohibitions\": [], + \"obligations\": [], + \"permissions\": [ + { + \"edctype\": \"dataspaceconnector:permission\", + \"action\": { \"type\": \"USE\" }, + \"target\": \"1\", + \"constraints\": [] + } + ] + } + } + }" \ + -s | jq -r '.id') +``` + +```bash +curl -X GET "${ALICE_DATAMGMT_URL}/data/contractnegotiations/${NEGOTIATION_ID}" \ + --header 'X-Api-Key: password' \ + --header 'Content-Type: application/json' \ + -s | jq +``` + +## 4. Transfer Data + +Initiate a data transfer using the contract agreement from the negotiation (from step 3). Then wait until the state of +the transfer process is `COMPLETED`. + +![Sequence 1](diagrams/transfer_sequence_4.png) + +**Run** + +```bash +export CONTRACT_AGREEMENT_ID=$( \ + curl -X GET "$ALICE_DATAMGMT_URL/data/contractnegotiations/$NEGOTIATION_ID" \ + --header 'X-Api-Key: password' \ + --header 'Content-Type: application/json' \ + -s | jq -r '.contractAgreementId') +``` + +```bash +export TRANSFER_PROCESS_ID=$(tr -dc '[:alnum:]' < /dev/urandom | head -c20) +export TRANSFER_ID=$( \ + curl -X POST "${ALICE_DATAMGMT_URL}/data/transferprocess" \ + --header "X-Api-Key: password" \ + --header "Content-Type: application/json" \ + --data "{ + \"id\": \"${TRANSFER_PROCESS_ID}\", + \"connectorId\": \"foo\", + \"connectorAddress\": \"${BOB_IDS_URL}/api/v1/ids/data\", + \"contractId\": \"${CONTRACT_AGREEMENT_ID}\", + \"assetId\": \"1\", + \"managedResources\": \"false\", + \"dataDestination\": { \"type\": \"HttpProxy\" } + }" \ + -s | jq -r '.id') +``` + +```bash +curl -X GET "${ALICE_DATAMGMT_URL}/data/transferprocess/${TRANSFER_ID}" \ + --header 'X-Api-Key: password' \ + --header 'Content-Type: application/json' \ + -s | jq +``` + +## 5. Verify Data Transfer + +After the transfer is complete the Backend Application has downloaded the data. The Backend Application stores the data +locally. In this demo the transfer can be verified by executing a simple `cat` call in the Pod. + +![Sequence 1](diagrams/transfer_sequence_5.png) + +```bash +curl -X GET "${ALICE_BACKEND_URL}/${TRANSFER_PROCESS_ID}" \ + --header 'Accept: application/octet-stream' \ + -s | jq +``` + +# Delete All Data + +```bash +minikube kubectl -- delete pvc -n edc-all-in-one --all +``` + +```bash +minikube kubectl -- delete pv -n edc-all-in-one --all +``` diff --git a/docs/samples/data-plane-http-oauth2.md b/docs/samples/data-plane-http-oauth2.md new file mode 100644 index 000000000..f757b703a --- /dev/null +++ b/docs/samples/data-plane-http-oauth2.md @@ -0,0 +1,7 @@ +# Data Plane HTTP OAuth2 + +The Data Plane HTTP OAuth2 extension permits the data-plane to fetch the data requested from a consumer from an HTTP server +with an OAuth2 authentication layer. + +For further documentation, please refer to the extension README: +https://github.com/eclipse-edc/Connector/tree/main/extensions/data-plane/data-plane-http-oauth2-core diff --git a/docs/samples/diagrams/transfer_sequence_1.png b/docs/samples/diagrams/transfer_sequence_1.png new file mode 100644 index 000000000..22500abc3 Binary files /dev/null and b/docs/samples/diagrams/transfer_sequence_1.png differ diff --git a/docs/samples/diagrams/transfer_sequence_1.puml b/docs/samples/diagrams/transfer_sequence_1.puml new file mode 100644 index 000000000..b49733a01 --- /dev/null +++ b/docs/samples/diagrams/transfer_sequence_1.puml @@ -0,0 +1,34 @@ +@startuml + +!define aliceColor 66CCFF +!define bobColor CCFF99 +!define dapsColor FFFF99 +!define noteColor 9999FF + +actor User as "User" + +box Alice + participant AliceControlPlane as "Control Plane" #aliceColor + participant AliceBackendService as "Backend Application" #aliceColor + participant AliceDataPlane as "Data Plane" #aliceColor +end box + +box Bob + participant BobControlPlane as "Control Plane" #bobColor + participant BobDataPlane as "Data Plane" #bobColor +end box + +participant JsonPlaceHolder as "JsonPlaceHolder" + + +User -> BobControlPlane ++ : Create Asset +return 204 + +User -> BobControlPlane ++ : Create Policy +return 204 + +User -> BobControlPlane ++ : Create Contract Definition +return 204 + + +@enduml diff --git a/docs/samples/diagrams/transfer_sequence_2.png b/docs/samples/diagrams/transfer_sequence_2.png new file mode 100644 index 000000000..95b6eeced Binary files /dev/null and b/docs/samples/diagrams/transfer_sequence_2.png differ diff --git a/docs/samples/diagrams/transfer_sequence_2.puml b/docs/samples/diagrams/transfer_sequence_2.puml new file mode 100644 index 000000000..2d078607d --- /dev/null +++ b/docs/samples/diagrams/transfer_sequence_2.puml @@ -0,0 +1,28 @@ +@startuml + +!define aliceColor 66CCFF +!define bobColor CCFF99 +!define dapsColor FFFF99 +!define noteColor 9999FF + +actor User as "User" + +box Alice + participant AliceControlPlane as "Control Plane" #aliceColor + participant AliceBackendService as "Backend Application" #aliceColor + participant AliceDataPlane as "Data Plane" #aliceColor +end box + +box Bob + participant BobControlPlane as "Control Plane" #bobColor + participant BobDataPlane as "Data Plane" #bobColor +end box + +participant JsonPlaceHolder as "JsonPlaceHolder" + +User -> AliceControlPlane ++ : Request Contract Offers from Bob + AliceControlPlane -> BobControlPlane ++ : IDS Description Request Message + return Description +return Contract Offers + +@enduml diff --git a/docs/samples/diagrams/transfer_sequence_3.png b/docs/samples/diagrams/transfer_sequence_3.png new file mode 100644 index 000000000..14a30c9a9 Binary files /dev/null and b/docs/samples/diagrams/transfer_sequence_3.png differ diff --git a/docs/samples/diagrams/transfer_sequence_3.puml b/docs/samples/diagrams/transfer_sequence_3.puml new file mode 100644 index 000000000..7bec9eadb --- /dev/null +++ b/docs/samples/diagrams/transfer_sequence_3.puml @@ -0,0 +1,33 @@ +@startuml + +!define aliceColor 66CCFF +!define bobColor CCFF99 +!define dapsColor FFFF99 +!define noteColor 9999FF + +actor User as "User" + +box Alice + participant AliceControlPlane as "Control Plane" #aliceColor + participant AliceBackendService as "Backend Application" #aliceColor + participant AliceDataPlane as "Data Plane" #aliceColor +end box + +box Bob + participant BobControlPlane as "Control Plane" #bobColor + participant BobDataPlane as "Data Plane" #bobColor +end box + +participant JsonPlaceHolder as "JsonPlaceHolder" + + +User -> AliceControlPlane ++ : Negotiate Contract for Offer X +AliceControlPlane --> User: Negotiation ID + AliceControlPlane -> BobControlPlane ++ : IDS Contract Negotiation (simplified) + return Contract Agreement +deactivate AliceControlPlane + +User -> AliceControlPlane ++ : Request Negotiation by ID +return Contract Negotiation + +@enduml diff --git a/docs/samples/diagrams/transfer_sequence_4.png b/docs/samples/diagrams/transfer_sequence_4.png new file mode 100644 index 000000000..e3630e70a Binary files /dev/null and b/docs/samples/diagrams/transfer_sequence_4.png differ diff --git a/docs/samples/diagrams/transfer_sequence_4.puml b/docs/samples/diagrams/transfer_sequence_4.puml new file mode 100644 index 000000000..6d4e936ed --- /dev/null +++ b/docs/samples/diagrams/transfer_sequence_4.puml @@ -0,0 +1,44 @@ +@startuml + +!define aliceColor 66CCFF +!define bobColor CCFF99 +!define dapsColor FFFF99 +!define noteColor 9999FF + +actor User as "User" + +box Alice + participant AliceControlPlane as "Control Plane" #aliceColor + participant AliceBackendService as "Backend Application" #aliceColor + participant AliceDataPlane as "Data Plane" #aliceColor +end box + +box Bob + participant BobControlPlane as "Control Plane" #bobColor + participant BobDataPlane as "Data Plane" #bobColor +end box + +participant JsonPlaceHolder as "JsonPlaceHolder" + +User -> AliceControlPlane ++ : Request Negotiation by ID +return Contract Negotiation\n(containing Contract Agreement ID) + +User -> AliceControlPlane ++ : Initiate Transfer with Agreement ID +AliceControlPlane --> User : Transfer Process ID + AliceControlPlane -> BobControlPlane ++ : IDS Data Transfer (simplified) +return +AliceControlPlane -> AliceBackendService ++ : Data Plane Endpoint + Token + AliceBackendService -> AliceDataPlane ++ : Request Data with Token + AliceDataPlane -> BobDataPlane ++ : Request Data + BobDataPlane -> JsonPlaceHolder ++ : Request Data + return data + return data + return data + AliceBackendService -> AliceBackendService : Write Data to File +return ok +deactivate AliceControlPlane + +User -> AliceControlPlane ++ : Request Transfer Process by ID +return Transfer Process + +@enduml diff --git a/docs/samples/diagrams/transfer_sequence_5.png b/docs/samples/diagrams/transfer_sequence_5.png new file mode 100644 index 000000000..1a18b5be2 Binary files /dev/null and b/docs/samples/diagrams/transfer_sequence_5.png differ diff --git a/docs/samples/diagrams/transfer_sequence_5.puml b/docs/samples/diagrams/transfer_sequence_5.puml new file mode 100644 index 000000000..598b747b6 --- /dev/null +++ b/docs/samples/diagrams/transfer_sequence_5.puml @@ -0,0 +1,27 @@ +@startuml + +!define aliceColor 66CCFF +!define bobColor CCFF99 +!define dapsColor FFFF99 +!define noteColor 9999FF + +actor User as "User" + +box Alice + participant AliceControlPlane as "Control Plane" #aliceColor + participant AliceBackendService as "Backend Application" #aliceColor + participant AliceDataPlane as "Data Plane" #aliceColor +end box + +box Bob + participant BobControlPlane as "Control Plane" #bobColor + participant BobDataPlane as "Data Plane" #bobColor +end box + +participant JsonPlaceHolder as "JsonPlaceHolder" + +User -> AliceBackendService ++ : Get File Content +return data + + +@enduml diff --git a/edc b/edc deleted file mode 160000 index 740c100ac..000000000 --- a/edc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 740c100ac162bc41b1968c232ad81f7d739aefa9 diff --git a/edc-controlplane/README.md b/edc-controlplane/README.md index 033852b1c..01017989c 100644 --- a/edc-controlplane/README.md +++ b/edc-controlplane/README.md @@ -32,7 +32,7 @@ As it is possible to configure EDC settings via environment variables, one way t Please have a look at the open issues in the open source repository. The list below might not be maintained well and only contains the most important issues. -EDC Github Repository https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues +EDC Github Repository https://github.com/eclipse-edc/Connector/issues --- @@ -42,30 +42,8 @@ EDC commit the Product-EDC uses. --- **Persistence** -- ContractDefinition-AssetSelector of InMemory Connector selects 50 Asset max.([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1779)) - -**Negotiation** - -- Connector blocks negotiation when `rightExpression` of a `Constraint` contains multiple elements/an array ([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/2026)) - -- Provider must pass its own `ContractPolicy` for the negotiation to succeed ([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1975)) - -**Transfer** -- Transfer Process remains 'InProgress' on provider side ([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1287)) - -**Data Management API** - -- Pagination is not correctly applied during catalog request ([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/2008)) - -**Configuration** -- Contract negotiation not working when `web.http.ids.path` is configured/changed ([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1249)) - - **Workaround:** Don't configure `web.http.ids.path`, so that the default path is used. - -- HttpProxy Transfer: Provider Control Plane spams Consumer Control Plane + HttpProxy Backend Application with requests([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1840)) - - **Possible Workaround:** Reconfigure data plane URL from `http://dataplane:8185/api/public` to `http://dataplane:8185/api/public/` - -- Non-telling logs when `edc.transfer.proxy.token.verifier.publickey.alias` setting is missing([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1889)) +- ContractDefinition-AssetSelector of InMemory Connector selects 50 Asset max.([issue](https://github.com/eclipse-edc/Connector/issues/1779)) **Other** -- Non-IDS-Transformable-ContractDefinition causes connector to be unable to send out self-descriptions/catalogs([issue](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues/1265)) +- Non-IDS-Transformable-ContractDefinition causes connector to be unable to send out self-descriptions/catalogs([issue](https://github.com/eclipse-edc/Connector/issues/1265)) - **Workaround:** Delete non-transformable ContractDefinition or Policy. diff --git a/edc-controlplane/build.gradle.kts b/edc-controlplane/build.gradle.kts new file mode 100644 index 000000000..d27dbdf36 --- /dev/null +++ b/edc-controlplane/build.gradle.kts @@ -0,0 +1,12 @@ + +plugins { + `java-library` +} + +dependencies { + implementation(project(":edc-controlplane:edc-controlplane-base")) + implementation(project(":edc-controlplane:edc-controlplane-memory")) + implementation(project(":edc-controlplane:edc-controlplane-memory-hashicorp-vault")) + implementation(project(":edc-controlplane:edc-controlplane-postgresql")) + implementation(project(":edc-controlplane:edc-controlplane-postgresql-hashicorp-vault")) +} diff --git a/edc-controlplane/edc-controlplane-base/README.md b/edc-controlplane/edc-controlplane-base/README.md index 98888200a..9fe217c80 100644 --- a/edc-controlplane/edc-controlplane-base/README.md +++ b/edc-controlplane/edc-controlplane-base/README.md @@ -3,5 +3,5 @@ ### Building ```shell -./mvnw -pl .,edc-controlplane/edc-controlplane-base -am package +./gradlew edc-controlplane:edc-controlplane-base:build ``` diff --git a/edc-controlplane/edc-controlplane-base/build.gradle.kts b/edc-controlplane/edc-controlplane-base/build.gradle.kts new file mode 100644 index 000000000..2fc866bb6 --- /dev/null +++ b/edc-controlplane/edc-controlplane-base/build.gradle.kts @@ -0,0 +1,28 @@ + +plugins { + `java-library` +} + +dependencies { + implementation(project(":edc-extensions:business-partner-validation")) + implementation(project(":edc-extensions:dataplane-selector-configuration")) + implementation(project(":edc-extensions:data-encryption")) + implementation(project(":edc-extensions:cx-oauth2")) + implementation(project(":edc-extensions:control-plane-adapter")) + implementation(project(":edc-extensions:provision-additional-headers")) + + implementation(edc.core.controlplane) + implementation(edc.config.filesystem) + implementation(edc.auth.tokenbased) + implementation(edc.auth.oauth2.core) + implementation(edc.auth.oauth2.daps) + implementation(edc.api.management) + implementation(edc.api.observability) + implementation(edc.ids) + implementation(edc.spi.jwt) + implementation(edc.bundles.dpf) + + implementation(edc.ext.http) + implementation(edc.bundles.monitoring) + implementation(edc.transfer.dynamicreceiver) +} diff --git a/edc-controlplane/edc-controlplane-base/pom.xml b/edc-controlplane/edc-controlplane-base/pom.xml deleted file mode 100644 index 06f2da6da..000000000 --- a/edc-controlplane/edc-controlplane-base/pom.xml +++ /dev/null @@ -1,197 +0,0 @@ - - - - - edc-controlplane - net.catenax.edc - 0.1.6 - - 4.0.0 - - edc-controlplane-base - jar - - - ${project.groupId}_${project.artifactId} - - - - ${project.artifactId} - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - - - net.catenax.edc.extensions - business-partner-validation - - - net.catenax.edc.extensions - dataplane-selector-configuration - - - net.catenax.edc.extensions - data-encryption - - - net.catenax.edc.extensions - cx-oauth2 - - - - - org.eclipse.dataspaceconnector - filesystem-configuration - - - - - org.eclipse.dataspaceconnector - auth-tokenbased - - - - - org.eclipse.dataspaceconnector - data-management-api - - - org.eclipse.dataspaceconnector - observability-api - - - - - org.eclipse.dataspaceconnector - ids-api-configuration - - - org.eclipse.dataspaceconnector - ids-api-multipart-dispatcher-v1 - - - org.eclipse.dataspaceconnector - ids-api-multipart-endpoint-v1 - - - org.eclipse.dataspaceconnector - ids-api-transform-v1 - - - org.eclipse.dataspaceconnector - ids-core - - - org.eclipse.dataspaceconnector - ids-spi - - - - - org.eclipse.dataspaceconnector - core-base - - - org.eclipse.dataspaceconnector - core-boot - - - org.eclipse.dataspaceconnector - transfer - - - org.eclipse.dataspaceconnector - contract - - - org.eclipse.dataspaceconnector - jwt-spi - - - - - - org.eclipse.dataspaceconnector - data-plane-transfer-sync - - - org.eclipse.dataspaceconnector - data-plane-selector-core - - - org.eclipse.dataspaceconnector - data-plane-selector-client - - - org.eclipse.dataspaceconnector - data-plane-selector-spi - - - - - org.eclipse.dataspaceconnector - core-micrometer - - - org.eclipse.dataspaceconnector - jersey-micrometer - - - org.eclipse.dataspaceconnector - jetty-micrometer - - - - - org.eclipse.dataspaceconnector - jdk-logger-monitor - - - - - - org.eclipse.dataspaceconnector - http - - - - org.eclipse.dataspaceconnector - http-receiver - - - \ No newline at end of file diff --git a/edc-controlplane/edc-controlplane-memory-hashicorp-vault/build.gradle.kts b/edc-controlplane/edc-controlplane-memory-hashicorp-vault/build.gradle.kts new file mode 100644 index 000000000..3cc9eb084 --- /dev/null +++ b/edc-controlplane/edc-controlplane-memory-hashicorp-vault/build.gradle.kts @@ -0,0 +1,27 @@ +import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage + +plugins { + `java-library` + id("application") + id("com.github.johnrengelman.shadow") version "8.0.0" +} + +dependencies { + implementation(project(":edc-controlplane:edc-controlplane-base")) + implementation(project(":edc-extensions:hashicorp-vault")) + implementation(edc.core.controlplane) + implementation(edc.dpf.transfer) + +} + + +tasks.withType { + exclude("**/pom.properties", "**/pom.xm") + mergeServiceFiles() + archiveFileName.set("${project.name}.jar") +} + +application { + mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") +} + diff --git a/edc-controlplane/edc-controlplane-memory-hashicorp-vault/src/main/docker/Dockerfile b/edc-controlplane/edc-controlplane-memory-hashicorp-vault/src/main/docker/Dockerfile new file mode 100644 index 000000000..470e4356a --- /dev/null +++ b/edc-controlplane/edc-controlplane-memory-hashicorp-vault/src/main/docker/Dockerfile @@ -0,0 +1,70 @@ +# +# Copyright (c) 2023 ZF Friedrichshafen AG +# Copyright (c) 2022,2023 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# +FROM alpine:3.17.1 as otel + +ENV OTEL_AGENT_LOCATION "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.12.1/opentelemetry-javaagent.jar" + +HEALTHCHECK NONE + +RUN wget ${OTEL_AGENT_LOCATION} -O /tmp/opentelemetry-javaagent.jar + +FROM alpine:3.17.1 + +ARG JAR +ARG LIB + +ARG APP_USER=docker +ARG APP_UID=10100 + +RUN apk update && \ + apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ + rm -rf /var/cache/apk/* + +RUN addgroup --system "$APP_USER" + +RUN adduser \ + --shell /sbin/nologin \ + --disabled-password \ + --gecos "" \ + --ingroup "$APP_USER" \ + --no-create-home \ + --uid "$APP_UID" \ + "$APP_USER" + +USER "$APP_USER" +WORKDIR /app + +COPY --from=otel /tmp/opentelemetry-javaagent.jar . +COPY ${JAR} edc-controlplane.jar +COPY ${LIB} ./lib/ + +HEALTHCHECK NONE + +CMD ["java", \ + "-javaagent:/app/opentelemetry-javaagent.jar", \ + "-Dedc.fs.config=/app/configuration.properties", \ + "-Djava.util.logging.config.file=/app/logging.properties", \ + "-Dotel.javaagent.configuration-file=/app/opentelemetry.properties", \ + "-Dotel.metrics.exporter=prometheus", \ + "-Dotel.exporter.prometheus.port=9090", \ + "-Djava.security.egd=file:/dev/urandom", \ + "-jar", \ + "edc-controlplane.jar"] diff --git a/edc-controlplane/edc-controlplane-memory/README.md b/edc-controlplane/edc-controlplane-memory/README.md index b3115a5c3..2eb2ce2e4 100644 --- a/edc-controlplane/edc-controlplane-memory/README.md +++ b/edc-controlplane/edc-controlplane-memory/README.md @@ -3,13 +3,13 @@ ### Building ```shell -./mvnw -pl .,edc-controlplane/edc-controlplane-memory -am package -Pwith-docker-image +./gradlew :edc-controlplane:edc-controlplane-memory:dockerize ``` ### Configuration (configuration.properties) Listed below are configuration keys needed to get the `edc-controlplane-memory` up and running. -Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/docs). +Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-edc/Connector/tree/main/docs). | Key | Required | Example | Description | |--- |--- |--- |--- | @@ -106,7 +106,7 @@ EOF export LOGGING_PROPERTIES_FILE=$(mktemp /tmp/logging.properties.XXXXXX) cat << 'EOF' > ${LOGGING_PROPERTIES_FILE} .level=INFO -org.eclipse.dataspaceconnector.level=ALL +org.eclipse.edc.level=ALL handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.level=ALL diff --git a/edc-controlplane/edc-controlplane-memory/build.gradle.kts b/edc-controlplane/edc-controlplane-memory/build.gradle.kts new file mode 100644 index 000000000..7de03126f --- /dev/null +++ b/edc-controlplane/edc-controlplane-memory/build.gradle.kts @@ -0,0 +1,25 @@ +import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage + +plugins { + `java-library` + id("application") + id("com.github.johnrengelman.shadow") version "8.0.0" +} + +dependencies { + implementation(project(":edc-controlplane:edc-controlplane-base")) + implementation(edc.core.controlplane) + implementation(edc.azure.vault) + implementation(edc.azure.identity) + +} + +tasks.withType { + exclude("**/pom.properties", "**/pom.xm") + mergeServiceFiles() + archiveFileName.set("${project.name}.jar") +} + +application { + mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") +} diff --git a/edc-controlplane/edc-controlplane-memory/pom.xml b/edc-controlplane/edc-controlplane-memory/pom.xml deleted file mode 100644 index e68c04a2a..000000000 --- a/edc-controlplane/edc-controlplane-memory/pom.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - - - net.catenax.edc - edc-controlplane - 0.1.6 - - 4.0.0 - - edc-controlplane-memory - jar - - - ${project.groupId}_${project.artifactId} - - - - ${project.artifactId} - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - lib/ - - org.eclipse.dataspaceconnector.boot.system.runtime.BaseRuntime - - false - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - package - - copy-dependencies - - - ${project.build.directory}/lib - - - - - - - - - - - net.catenax.edc - edc-controlplane-base - - - org.eclipse.dataspaceconnector - control-plane-core - - - - - org.eclipse.dataspaceconnector - azure-vault - - - com.azure - azure-security-keyvault-secrets - - - com.azure - azure-identity - - - - - - - com.azure - azure-identity - - - com.azure - azure-security-keyvault-secrets - - - - - - - with-docker-image - - - - org.codehaus.mojo - exec-maven-plugin - - - - docker-build-${project.artifactId}:${project.version} - package - - exec - - - docker - ${project.basedir} - - build - -f - src/main/docker/Dockerfile - --build-arg - JAR=target/${project.artifactId}.jar - --build-arg - LIB=target/lib - -t - ${project.artifactId}:${project.version} - . - - - - - docker-tag-${project.artifactId}:latest - package - - exec - - - docker - ${project.basedir} - - tag - ${project.artifactId}:${project.version} - ${project.artifactId}:latest - - - - - - - - - - \ No newline at end of file diff --git a/edc-controlplane/edc-controlplane-memory/src/main/docker/Dockerfile b/edc-controlplane/edc-controlplane-memory/src/main/docker/Dockerfile index 2063e626b..f6e00c14a 100644 --- a/edc-controlplane/edc-controlplane-memory/src/main/docker/Dockerfile +++ b/edc-controlplane/edc-controlplane-memory/src/main/docker/Dockerfile @@ -1,6 +1,7 @@ # -# Copyright (c) 2022 - 2023 Mercedes-Benz Tech Innovation GmbH -# Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation +# Copyright (c) 2023 ZF Friedrichshafen AG +# Copyright (c) 2022,2023 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2023 Contributors to the Eclipse Foundation # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -17,14 +18,15 @@ # # SPDX-License-Identifier: Apache-2.0 # - -FROM alpine:3.17.1 as otel +FROM alpine:3.17.2 as otel ENV OTEL_AGENT_LOCATION "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.12.1/opentelemetry-javaagent.jar" +HEALTHCHECK NONE + RUN wget ${OTEL_AGENT_LOCATION} -O /tmp/opentelemetry-javaagent.jar -FROM alpine:3.17.1 +FROM alpine:3.17.2 ARG JAR ARG LIB @@ -33,8 +35,8 @@ ARG APP_USER=docker ARG APP_UID=10100 RUN apk update && \ - apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ - rm -rf /var/cache/apk/* + apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ + rm -rf /var/cache/apk/* RUN addgroup --system "$APP_USER" @@ -54,6 +56,8 @@ COPY --from=otel /tmp/opentelemetry-javaagent.jar . COPY ${JAR} edc-controlplane.jar COPY ${LIB} ./lib/ +HEALTHCHECK NONE + CMD ["java", \ "-javaagent:/app/opentelemetry-javaagent.jar", \ "-Dedc.fs.config=/app/configuration.properties", \ diff --git a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/README.md b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/README.md index 08a1ecf3c..0efd61884 100644 --- a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/README.md +++ b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/README.md @@ -3,13 +3,13 @@ ### Building ```shell -./mvnw -pl .,edc-controlplane/edc-controlplane-postgresql-hashicorp-vault -am package -Pwith-docker-image +./gardlew :edc-controlplane:edc-controlplane-postgresql-hashicorp-vault:dockerize ``` ### Configuration Listed below are configuration keys needed to get the `edc-controlplane-postgresql-hashicorp-vault` up and running. -Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/docs). +Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-edc/Connector/tree/main/docs). | Key | Required | Example | Description | |--- |--- |--- |--- | @@ -146,7 +146,7 @@ EOF export LOGGING_PROPERTIES_FILE=$(mktemp /tmp/logging.properties.XXXXXX) cat << 'EOF' > ${LOGGING_PROPERTIES_FILE} .level=INFO -org.eclipse.dataspaceconnector.level=ALL +org.eclipse.edc.level=ALL handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.level=ALL diff --git a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/build.gradle.kts b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/build.gradle.kts new file mode 100644 index 000000000..894585c55 --- /dev/null +++ b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/build.gradle.kts @@ -0,0 +1,32 @@ +import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + `java-library` + id("application") + id("com.github.johnrengelman.shadow") version "8.0.0" +} + +dependencies { + implementation(project(":edc-controlplane:edc-controlplane-base")) + implementation(project(":edc-extensions:postgresql-migration")) + implementation(project(":edc-extensions:hashicorp-vault")) + implementation(edc.bundles.sqlstores) + implementation(edc.transaction.local) + implementation(edc.sql.pool) + implementation(edc.core.controlplane) + implementation(edc.dpf.transfer) + +} + + +tasks.withType { + exclude("**/pom.properties", "**/pom.xm") + mergeServiceFiles() + archiveFileName.set("${project.name}.jar") +} + + +application { + mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") +} diff --git a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/pom.xml b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/pom.xml deleted file mode 100644 index e71e1dd76..000000000 --- a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/pom.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - - - net.catenax.edc - edc-controlplane - 0.1.6 - - 4.0.0 - - edc-controlplane-postgresql-hashicorp-vault - jar - - - ${project.groupId}_${project.artifactId} - - - - ${project.artifactId} - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - lib/ - org.eclipse.dataspaceconnector.boot.system.runtime.BaseRuntime - false - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - package - - copy-dependencies - - - ${project.build.directory}/lib - - - - - - - - - - - - net.catenax.edc - edc-controlplane-postgresql - - - org.eclipse.dataspaceconnector - azure-vault - - - - - - - net.catenax.edc.extensions - hashicorp-vault - - - - - - - - with-docker-image - - - - org.codehaus.mojo - exec-maven-plugin - - - - docker-build-${project.artifactId}:${project.version} - package - - exec - - - docker - ${project.basedir} - - build - -f - src/main/docker/Dockerfile - --build-arg - JAR=target/${project.artifactId}.jar - --build-arg - LIB=target/lib - -t - ${project.artifactId}:${project.version} - . - - - - - docker-tag-${project.artifactId}:latest - package - - exec - - - docker - ${project.basedir} - - tag - ${project.artifactId}:${project.version} - ${project.artifactId}:latest - - - - - - - - - - diff --git a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/src/main/docker/Dockerfile b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/src/main/docker/Dockerfile index 2063e626b..f6e00c14a 100644 --- a/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/src/main/docker/Dockerfile +++ b/edc-controlplane/edc-controlplane-postgresql-hashicorp-vault/src/main/docker/Dockerfile @@ -1,6 +1,7 @@ # -# Copyright (c) 2022 - 2023 Mercedes-Benz Tech Innovation GmbH -# Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation +# Copyright (c) 2023 ZF Friedrichshafen AG +# Copyright (c) 2022,2023 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2023 Contributors to the Eclipse Foundation # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -17,14 +18,15 @@ # # SPDX-License-Identifier: Apache-2.0 # - -FROM alpine:3.17.1 as otel +FROM alpine:3.17.2 as otel ENV OTEL_AGENT_LOCATION "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.12.1/opentelemetry-javaagent.jar" +HEALTHCHECK NONE + RUN wget ${OTEL_AGENT_LOCATION} -O /tmp/opentelemetry-javaagent.jar -FROM alpine:3.17.1 +FROM alpine:3.17.2 ARG JAR ARG LIB @@ -33,8 +35,8 @@ ARG APP_USER=docker ARG APP_UID=10100 RUN apk update && \ - apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ - rm -rf /var/cache/apk/* + apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ + rm -rf /var/cache/apk/* RUN addgroup --system "$APP_USER" @@ -54,6 +56,8 @@ COPY --from=otel /tmp/opentelemetry-javaagent.jar . COPY ${JAR} edc-controlplane.jar COPY ${LIB} ./lib/ +HEALTHCHECK NONE + CMD ["java", \ "-javaagent:/app/opentelemetry-javaagent.jar", \ "-Dedc.fs.config=/app/configuration.properties", \ diff --git a/edc-controlplane/edc-controlplane-postgresql/README.md b/edc-controlplane/edc-controlplane-postgresql/README.md index b6f18f171..bb8730712 100644 --- a/edc-controlplane/edc-controlplane-postgresql/README.md +++ b/edc-controlplane/edc-controlplane-postgresql/README.md @@ -3,13 +3,13 @@ ### Building ```shell -./mvnw -pl .,edc-controlplane/edc-controlplane-postgresql -am package -Pwith-docker-image +./gardlew :edc-controlplane:edc-controlplane-postgresql:dockerize ``` ### Configuration Listed below are configuration keys needed to get the `edc-controlplane-postgresql` up and running. -Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/docs). +Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-edc/Connector/tree/main/docs). | Key | Required | Example | Description | |--- |--- |--- |--- | @@ -149,7 +149,7 @@ EOF export LOGGING_PROPERTIES_FILE=$(mktemp /tmp/logging.properties.XXXXXX) cat << 'EOF' > ${LOGGING_PROPERTIES_FILE} .level=INFO -org.eclipse.dataspaceconnector.level=ALL +org.eclipse.edc.level=ALL handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.level=ALL diff --git a/edc-controlplane/edc-controlplane-postgresql/build.gradle.kts b/edc-controlplane/edc-controlplane-postgresql/build.gradle.kts new file mode 100644 index 000000000..5bbe614e5 --- /dev/null +++ b/edc-controlplane/edc-controlplane-postgresql/build.gradle.kts @@ -0,0 +1,30 @@ +import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + `java-library` + id("application") + id("com.github.johnrengelman.shadow") version "8.0.0" +} + +dependencies { + implementation(project(":edc-controlplane:edc-controlplane-base")) + implementation(project(":edc-extensions:postgresql-migration")) + implementation(edc.azure.vault) + implementation(edc.bundles.sqlstores) + implementation(edc.core.controlplane) + implementation(edc.dpf.transfer) + +} + + +tasks.withType { + exclude("**/pom.properties", "**/pom.xm") + mergeServiceFiles() + archiveFileName.set("${project.name}.jar") +} + + +application { + mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") +} diff --git a/edc-controlplane/edc-controlplane-postgresql/pom.xml b/edc-controlplane/edc-controlplane-postgresql/pom.xml deleted file mode 100644 index 0412ddada..000000000 --- a/edc-controlplane/edc-controlplane-postgresql/pom.xml +++ /dev/null @@ -1,222 +0,0 @@ - - - - - net.catenax.edc - edc-controlplane - 0.1.6 - - 4.0.0 - - edc-controlplane-postgresql - jar - - - ${project.groupId}_${project.artifactId} - - - - ${project.artifactId} - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - lib/ - - org.eclipse.dataspaceconnector.boot.system.runtime.BaseRuntime - - false - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - package - - copy-dependencies - - - ${project.build.directory}/lib - - - - - - - - - - - net.catenax.edc - edc-controlplane-base - - - - - net.catenax.edc.extensions - postgresql-migration - - - - - org.eclipse.dataspaceconnector - azure-vault - - - com.azure - azure-security-keyvault-secrets - - - com.azure - azure-identity - - - - - - - org.eclipse.dataspaceconnector - asset-index-sql - - - org.eclipse.dataspaceconnector - contractdefinition-store-sql - - - org.eclipse.dataspaceconnector - contractnegotiation-store-sql - - - org.eclipse.dataspaceconnector - transfer-process-store-sql - - - org.eclipse.dataspaceconnector - policy-store-sql - - - - - org.eclipse.dataspaceconnector - apache-commons-pool-sql - - - org.eclipse.dataspaceconnector - transaction-local - - - - - com.azure - azure-identity - - - com.azure - azure-security-keyvault-secrets - - - org.postgresql - postgresql - - - - - - - with-docker-image - - - - org.codehaus.mojo - exec-maven-plugin - - - - docker-build-${project.artifactId}:${project.version} - package - - exec - - - docker - ${project.basedir} - - build - -f - src/main/docker/Dockerfile - --build-arg - JAR=target/${project.artifactId}.jar - --build-arg - LIB=target/lib - -t - ${project.artifactId}:${project.version} - . - - - - - docker-tag-${project.artifactId}:latest - package - - exec - - - docker - ${project.basedir} - - tag - ${project.artifactId}:${project.version} - ${project.artifactId}:latest - - - - - - - - - - \ No newline at end of file diff --git a/edc-controlplane/edc-controlplane-postgresql/src/main/docker/Dockerfile b/edc-controlplane/edc-controlplane-postgresql/src/main/docker/Dockerfile index 2063e626b..f6e00c14a 100644 --- a/edc-controlplane/edc-controlplane-postgresql/src/main/docker/Dockerfile +++ b/edc-controlplane/edc-controlplane-postgresql/src/main/docker/Dockerfile @@ -1,6 +1,7 @@ # -# Copyright (c) 2022 - 2023 Mercedes-Benz Tech Innovation GmbH -# Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation +# Copyright (c) 2023 ZF Friedrichshafen AG +# Copyright (c) 2022,2023 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2023 Contributors to the Eclipse Foundation # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -17,14 +18,15 @@ # # SPDX-License-Identifier: Apache-2.0 # - -FROM alpine:3.17.1 as otel +FROM alpine:3.17.2 as otel ENV OTEL_AGENT_LOCATION "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.12.1/opentelemetry-javaagent.jar" +HEALTHCHECK NONE + RUN wget ${OTEL_AGENT_LOCATION} -O /tmp/opentelemetry-javaagent.jar -FROM alpine:3.17.1 +FROM alpine:3.17.2 ARG JAR ARG LIB @@ -33,8 +35,8 @@ ARG APP_USER=docker ARG APP_UID=10100 RUN apk update && \ - apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ - rm -rf /var/cache/apk/* + apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ + rm -rf /var/cache/apk/* RUN addgroup --system "$APP_USER" @@ -54,6 +56,8 @@ COPY --from=otel /tmp/opentelemetry-javaagent.jar . COPY ${JAR} edc-controlplane.jar COPY ${LIB} ./lib/ +HEALTHCHECK NONE + CMD ["java", \ "-javaagent:/app/opentelemetry-javaagent.jar", \ "-Dedc.fs.config=/app/configuration.properties", \ diff --git a/edc-controlplane/pom.xml b/edc-controlplane/pom.xml deleted file mode 100644 index 88440ab29..000000000 --- a/edc-controlplane/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - net.catenax.edc - product-edc-parent - 0.1.6 - - 4.0.0 - - edc-controlplane - pom - - - ${project.groupId}_${project.artifactId} - - - - edc-controlplane-base - edc-controlplane-memory - edc-controlplane-postgresql - edc-controlplane-postgresql-hashicorp-vault - - diff --git a/edc-dataplane/README.md b/edc-dataplane/README.md index 6efe7366f..2deeec0d6 100644 --- a/edc-dataplane/README.md +++ b/edc-dataplane/README.md @@ -12,4 +12,4 @@ Please be aware that there are several confidential settings, that should not be As it is possible to configure EDC settings via environment variables, one way to do it would be via Kubernetes Secrets. For other deployment scenarios than Kubernetes equivalent measures should be taken. # Known Data Plane Issues -Please have a look at the open issues in the open source repository: [EDC Github Repository](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/issues) +Please have a look at the open issues in the open source repository: [EDC Github Repository](https://github.com/eclipse-edc/Connector/issues) diff --git a/edc-dataplane/build.gradle.kts b/edc-dataplane/build.gradle.kts new file mode 100644 index 000000000..063edd76c --- /dev/null +++ b/edc-dataplane/build.gradle.kts @@ -0,0 +1,10 @@ + +plugins { + `java-library` +} + +dependencies { + implementation(project(":edc-dataplane:edc-dataplane-base")) + implementation(project(":edc-dataplane:edc-dataplane-azure-vault")) + implementation(project(":edc-dataplane:edc-dataplane-hashicorp-vault")) +} diff --git a/edc-dataplane/edc-dataplane-azure-vault/README.md b/edc-dataplane/edc-dataplane-azure-vault/README.md index 490bd0002..b133fee26 100644 --- a/edc-dataplane/edc-dataplane-azure-vault/README.md +++ b/edc-dataplane/edc-dataplane-azure-vault/README.md @@ -3,13 +3,13 @@ ### Building ```shell -./mvnw -pl .,edc-dataplane/edc-dataplane-azure-vault -am package -Pwith-docker-image +./gardlew :edc-dataplane:edc-dataplane-azure-vault:dockerize ``` ### Configuration Listed below are configuration keys needed to get the `edc-dataplane-azure-vault` up and running. -Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/docs). +Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-edc/Connector/tree/main/docs). | Key | Required | Example | Description | |--- |--- |--- |--- | @@ -64,7 +64,7 @@ EOF export LOGGING_PROPERTIES_FILE=$(mktemp /tmp/logging.properties.XXXXXX) cat << 'EOF' > ${LOGGING_PROPERTIES_FILE} .level=INFO -org.eclipse.dataspaceconnector.level=ALL +org.eclipse.edc.level=ALL handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.level=ALL diff --git a/edc-dataplane/edc-dataplane-azure-vault/build.gradle.kts b/edc-dataplane/edc-dataplane-azure-vault/build.gradle.kts new file mode 100644 index 000000000..bde51831c --- /dev/null +++ b/edc-dataplane/edc-dataplane-azure-vault/build.gradle.kts @@ -0,0 +1,23 @@ + +plugins { + `java-library` + id("application") + id("com.github.johnrengelman.shadow") version "8.0.0" +} + +dependencies { + implementation(project(":edc-dataplane:edc-dataplane-base")) + implementation(edc.azure.vault) + implementation(edc.azure.identity) + implementation("com.azure:azure-security-keyvault-secrets:4.5.4") +} + +tasks.withType { + exclude("**/pom.properties", "**/pom.xm") + mergeServiceFiles() + archiveFileName.set("${project.name}.jar") +} + +application { + mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") +} diff --git a/edc-dataplane/edc-dataplane-azure-vault/pom.xml b/edc-dataplane/edc-dataplane-azure-vault/pom.xml deleted file mode 100644 index 0ee3e3843..000000000 --- a/edc-dataplane/edc-dataplane-azure-vault/pom.xml +++ /dev/null @@ -1,178 +0,0 @@ - - - - - net.catenax.edc - edc-dataplane - 0.1.6 - - 4.0.0 - - edc-dataplane-azure-vault - jar - - - ${project.groupId}_${project.artifactId} - - - - ${project.artifactId} - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - lib/ - org.eclipse.dataspaceconnector.boot.system.runtime.BaseRuntime - false - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - package - - copy-dependencies - - - ${project.build.directory}/lib - - - - - - - - - - - net.catenax.edc - edc-dataplane-base - - - - - org.eclipse.dataspaceconnector - azure-vault - - - com.azure - azure-security-keyvault-secrets - - - com.azure - azure-identity - - - - - - - com.azure - azure-identity - - - com.azure - azure-security-keyvault-secrets - - - - - - - with-docker-image - - - - org.codehaus.mojo - exec-maven-plugin - - - - docker-build-${project.artifactId}:${project.version} - package - - exec - - - docker - ${project.basedir} - - build - -f - src/main/docker/Dockerfile - --build-arg - JAR=target/${project.artifactId}.jar - --build-arg - LIB=target/lib - -t - ${project.artifactId}:${project.version} - . - - - - - docker-tag-${project.artifactId}:latest - package - - exec - - - docker - ${project.basedir} - - tag - ${project.artifactId}:${project.version} - ${project.artifactId}:latest - - - - - - - - - - diff --git a/edc-dataplane/edc-dataplane-azure-vault/src/main/docker/Dockerfile b/edc-dataplane/edc-dataplane-azure-vault/src/main/docker/Dockerfile index 05e336cd3..3edccafbc 100644 --- a/edc-dataplane/edc-dataplane-azure-vault/src/main/docker/Dockerfile +++ b/edc-dataplane/edc-dataplane-azure-vault/src/main/docker/Dockerfile @@ -1,6 +1,7 @@ # -# Copyright (c) 2022 - 2023 Mercedes-Benz Tech Innovation GmbH -# Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation +# Copyright (c) 2023 ZF Friedrichshafen AG +# Copyright (c) 2022,2023 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2023 Contributors to the Eclipse Foundation # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -17,14 +18,15 @@ # # SPDX-License-Identifier: Apache-2.0 # - -FROM alpine:3.17.1 as otel +FROM alpine:3.17.2 as otel ENV OTEL_AGENT_LOCATION "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.12.1/opentelemetry-javaagent.jar" +HEALTHCHECK NONE + RUN wget ${OTEL_AGENT_LOCATION} -O /tmp/opentelemetry-javaagent.jar -FROM alpine:3.17.1 +FROM alpine:3.17.2 ARG JAR ARG LIB @@ -33,8 +35,8 @@ ARG APP_USER=docker ARG APP_UID=10100 RUN apk update && \ - apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ - rm -rf /var/cache/apk/* + apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ + rm -rf /var/cache/apk/* RUN addgroup --system "$APP_USER" @@ -54,6 +56,8 @@ COPY --from=otel /tmp/opentelemetry-javaagent.jar . COPY ${JAR} edc-dataplane.jar COPY ${LIB} ./lib/ +HEALTHCHECK NONE + CMD ["java", \ "-javaagent:/app/opentelemetry-javaagent.jar", \ "-Dedc.fs.config=/app/configuration.properties", \ diff --git a/edc-dataplane/edc-dataplane-base/README.md b/edc-dataplane/edc-dataplane-base/README.md index 448937507..ee8ac9961 100644 --- a/edc-dataplane/edc-dataplane-base/README.md +++ b/edc-dataplane/edc-dataplane-base/README.md @@ -3,5 +3,5 @@ ### Building ```shell -./mvnw -pl .,edc-dataplane/edc-dataplane-base -am package +./gardlew :edc-dataplane:edc-dataplane-base:build ``` diff --git a/edc-dataplane/edc-dataplane-base/build.gradle.kts b/edc-dataplane/edc-dataplane-base/build.gradle.kts new file mode 100644 index 000000000..686e5fd06 --- /dev/null +++ b/edc-dataplane/edc-dataplane-base/build.gradle.kts @@ -0,0 +1,21 @@ + +plugins { + `java-library` +} + +dependencies { + implementation(edc.config.filesystem) + implementation(edc.dpf.awss3) + implementation(edc.dpf.oauth2) + implementation(edc.dpf.http) + + implementation(edc.dpf.framework) + implementation(edc.dpf.api) + implementation(edc.api.observability) + implementation(edc.core.connector) + implementation(edc.boot) + + + implementation(edc.bundles.monitoring) + implementation(edc.ext.http) +} \ No newline at end of file diff --git a/edc-dataplane/edc-dataplane-base/pom.xml b/edc-dataplane/edc-dataplane-base/pom.xml deleted file mode 100644 index e66a94cc0..000000000 --- a/edc-dataplane/edc-dataplane-base/pom.xml +++ /dev/null @@ -1,124 +0,0 @@ - - - - - edc-dataplane - net.catenax.edc - 0.1.6 - - 4.0.0 - - edc-dataplane-base - jar - - - ${project.groupId}_${project.artifactId} - - - - ${project.artifactId} - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - - - org.eclipse.dataspaceconnector - filesystem-configuration - - - - - org.eclipse.dataspaceconnector - data-plane-s3 - - - org.eclipse.dataspaceconnector - data-plane-http - - - - - org.eclipse.dataspaceconnector - data-plane-framework - - - org.eclipse.dataspaceconnector - data-plane-api - - - org.eclipse.dataspaceconnector - observability-api - - - - - org.eclipse.dataspaceconnector - core-base - - - org.eclipse.dataspaceconnector - core-boot - - - org.eclipse.dataspaceconnector - s3-core - - - - - org.eclipse.dataspaceconnector - core-micrometer - - - org.eclipse.dataspaceconnector - jersey-micrometer - - - org.eclipse.dataspaceconnector - jetty-micrometer - - - - - org.eclipse.dataspaceconnector - jdk-logger-monitor - - - - - - org.eclipse.dataspaceconnector - http - - - diff --git a/edc-dataplane/edc-dataplane-hashicorp-vault/README.md b/edc-dataplane/edc-dataplane-hashicorp-vault/README.md index 45b196572..f43382ee1 100644 --- a/edc-dataplane/edc-dataplane-hashicorp-vault/README.md +++ b/edc-dataplane/edc-dataplane-hashicorp-vault/README.md @@ -3,13 +3,13 @@ ### Building ```shell -./mvnw -pl .,edc-dataplane/edc-dataplane-hashicorp-vault -am package -Pwith-docker-image +./gardlew :edc-dataplane:edc-dataplane-hashicorp-vault:dockerize ``` ### Configuration Listed below are configuration keys needed to get the `edc-dataplane-hashicorp-vault` up and running. -Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/docs). +Details regarding each configuration property can be found at the [documentary section of the EDC](https://github.com/eclipse-edc/Connector/tree/main/docs). | Key | Required | Example | Description | |--- |--- |--- |--- | @@ -62,7 +62,7 @@ EOF export LOGGING_PROPERTIES_FILE=$(mktemp /tmp/logging.properties.XXXXXX) cat << 'EOF' > ${LOGGING_PROPERTIES_FILE} .level=INFO -org.eclipse.dataspaceconnector.level=ALL +org.eclipse.edc.level=ALL handlers=java.util.logging.ConsoleHandler java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.ConsoleHandler.level=ALL diff --git a/edc-dataplane/edc-dataplane-hashicorp-vault/build.gradle.kts b/edc-dataplane/edc-dataplane-hashicorp-vault/build.gradle.kts new file mode 100644 index 000000000..7f53f8c5c --- /dev/null +++ b/edc-dataplane/edc-dataplane-hashicorp-vault/build.gradle.kts @@ -0,0 +1,21 @@ + +plugins { + `java-library` + id("application") + id("com.github.johnrengelman.shadow") version "8.0.0" +} + +dependencies { + implementation(project(":edc-dataplane:edc-dataplane-base")) + implementation(project(":edc-extensions:hashicorp-vault")) +} + +tasks.withType { + exclude("**/pom.properties", "**/pom.xm") + mergeServiceFiles() + archiveFileName.set("${project.name}.jar") +} + +application { + mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") +} diff --git a/edc-dataplane/edc-dataplane-hashicorp-vault/pom.xml b/edc-dataplane/edc-dataplane-hashicorp-vault/pom.xml deleted file mode 100644 index abbde799b..000000000 --- a/edc-dataplane/edc-dataplane-hashicorp-vault/pom.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - - - net.catenax.edc - edc-dataplane - 0.1.6 - - 4.0.0 - - edc-dataplane-hashicorp-vault - jar - - - ${project.groupId}_${project.artifactId} - - - - ${project.artifactId} - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - lib/ - org.eclipse.dataspaceconnector.boot.system.runtime.BaseRuntime - false - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - package - - copy-dependencies - - - ${project.build.directory}/lib - - - - - - - - - - - net.catenax.edc - edc-dataplane-base - - - - - net.catenax.edc.extensions - hashicorp-vault - - - - - - - with-docker-image - - - - org.codehaus.mojo - exec-maven-plugin - - - - docker-build-${project.artifactId}:${project.version} - package - - exec - - - docker - ${project.basedir} - - build - -f - src/main/docker/Dockerfile - --build-arg - JAR=target/${project.artifactId}.jar - --build-arg - LIB=target/lib - -t - ${project.artifactId}:${project.version} - . - - - - - docker-tag-${project.artifactId}:latest - package - - exec - - - docker - ${project.basedir} - - tag - ${project.artifactId}:${project.version} - ${project.artifactId}:latest - - - - - - - - - - diff --git a/edc-dataplane/edc-dataplane-hashicorp-vault/src/main/docker/Dockerfile b/edc-dataplane/edc-dataplane-hashicorp-vault/src/main/docker/Dockerfile index 05e336cd3..3edccafbc 100644 --- a/edc-dataplane/edc-dataplane-hashicorp-vault/src/main/docker/Dockerfile +++ b/edc-dataplane/edc-dataplane-hashicorp-vault/src/main/docker/Dockerfile @@ -1,6 +1,7 @@ # -# Copyright (c) 2022 - 2023 Mercedes-Benz Tech Innovation GmbH -# Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation +# Copyright (c) 2023 ZF Friedrichshafen AG +# Copyright (c) 2022,2023 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2023 Contributors to the Eclipse Foundation # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -17,14 +18,15 @@ # # SPDX-License-Identifier: Apache-2.0 # - -FROM alpine:3.17.1 as otel +FROM alpine:3.17.2 as otel ENV OTEL_AGENT_LOCATION "https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.12.1/opentelemetry-javaagent.jar" +HEALTHCHECK NONE + RUN wget ${OTEL_AGENT_LOCATION} -O /tmp/opentelemetry-javaagent.jar -FROM alpine:3.17.1 +FROM alpine:3.17.2 ARG JAR ARG LIB @@ -33,8 +35,8 @@ ARG APP_USER=docker ARG APP_UID=10100 RUN apk update && \ - apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ - rm -rf /var/cache/apk/* + apk add openjdk11-jre-headless=11.0.18_p10-r0 --no-cache && \ + rm -rf /var/cache/apk/* RUN addgroup --system "$APP_USER" @@ -54,6 +56,8 @@ COPY --from=otel /tmp/opentelemetry-javaagent.jar . COPY ${JAR} edc-dataplane.jar COPY ${LIB} ./lib/ +HEALTHCHECK NONE + CMD ["java", \ "-javaagent:/app/opentelemetry-javaagent.jar", \ "-Dedc.fs.config=/app/configuration.properties", \ diff --git a/edc-dataplane/pom.xml b/edc-dataplane/pom.xml deleted file mode 100644 index 691495162..000000000 --- a/edc-dataplane/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - 4.0.0 - - - net.catenax.edc - product-edc-parent - 0.1.6 - - - edc-dataplane - pom - - - ${project.groupId}_${project.artifactId} - - - - edc-dataplane-base - - edc-dataplane-azure-vault - edc-dataplane-hashicorp-vault - - diff --git a/edc-extensions/README.md b/edc-extensions/README.md deleted file mode 100644 index cbbaa5684..000000000 --- a/edc-extensions/README.md +++ /dev/null @@ -1 +0,0 @@ -# edc-extensions \ No newline at end of file diff --git a/edc-extensions/build.gradle.kts b/edc-extensions/build.gradle.kts new file mode 100644 index 000000000..f7740ef67 --- /dev/null +++ b/edc-extensions/build.gradle.kts @@ -0,0 +1,18 @@ + +plugins { + `java-library` +} + +dependencies { + implementation(project(":edc-extensions:business-partner-validation")) + implementation(project(":edc-extensions:control-plane-adapter")) + implementation(project(":edc-extensions:cx-oauth2")) + implementation(project(":edc-extensions:data-encryption")) + implementation(project(":edc-extensions:dataplane-selector-configuration")) + implementation(project(":edc-extensions:hashicorp-vault")) + implementation(project(":edc-extensions:postgresql-migration")) + implementation(project(":edc-extensions:provision-additional-headers")) + implementation(project(":edc-extensions:transferprocess-sftp-client")) + implementation(project(":edc-extensions:transferprocess-sftp-common")) + implementation(project(":edc-extensions:transferprocess-sftp-provisioner")) +} diff --git a/edc-extensions/business-partner-validation/README.md b/edc-extensions/business-partner-validation/README.md index daf374e96..d37041560 100644 --- a/edc-extensions/business-partner-validation/README.md +++ b/edc-extensions/business-partner-validation/README.md @@ -1,25 +1,12 @@ -# Important for Milestone 3! - -Please note, that with the start of the **Milestone 3** release (v0.0.1) there exists an issue, where the BPN number cannot be retrieved from the DAPS token. The missing token BPN makes offers, protected by a BPN constraint, unavailable to all connectors. - # Business Partner Validation Extension Using the Business Partner Validation Extension it's possible to add configurable validation against -Catena-X `Participants` in the `ContractDefinition.AccessPolicy`. - -**Why only AccessPolicy?** Because when a custom validation is used in the `ContractPolicy`, it is necessary -to send it to the other connector. But nether is it possible to send a generic constraint using the IDS Protocol, -nor is it possible for another connector to enforce a generic constraint reliable. Hence, the limit -to `AccessPolicy`. This limitation is not technically enforceable, therefore adding Business Partner constraints to the -contract policy simply won't work. +Catena-X `Participants` in the `ContractDefinition.AccessPolicy`. Using a BPN in `ContractDefinition.ContractPolicy` is possible, too, but once the contract is complete there is no policy enforcement in place from the EDC. -This extension is already included in all the Catena-X control-planes and can be used accordingly. It is recommended to have a basic understanding of the EDC contract/policy domain before using this extension. The -corresponding documentation can -be found in the [EDC GitHub Repository](https://github.com/eclipse-dataspaceconnector/DataSpaceConnector). For a -simplified overview of the EDC domain please have a look at the Catena-X Control Plane documentation. +corresponding documentation can be found in the [EDC GitHub Repository](https://github.com/eclipse-edc/Connector). -The business partner number of another connector is part of the DAPS token. Once a BPN constraint is used in an access +The business partner number of another connector is part of its DAPS token. Once a BPN constraint is used in an access policy the connector checks the token before sending out contract offers. Example of business partner constraint: @@ -40,16 +27,14 @@ The `leftExpression` must always contain 'BusinessPartner', so that the policy f Additionally, the only `operator` that is supported by these policy functions is 'EQ'. Finally, the `rightExpression` must contain the Business Partner Number. +## Single BusinessPartnerNumber example + The most simple BPN policy would allow the usage of certain data to a single Business Partner. An example `Policy` is -shown below. In this example the `edctype` properties are added, so that this policy may even be sent to the Data -Management API. +shown below. +In this example the `edctype` properties are added, so that this policy may even be sent to the Management API. -**Example 1 for single BPN:** ```json { - "uid": "", - "prohibitions": [], - "obligations": [], "permissions": [ { "edctype": "dataspaceconnector:permission", @@ -75,32 +60,54 @@ Management API. } ``` -**Example 2 for multiple BPN:** +## Multiple BusinessPartnerNumber example + +To define multiple BPN and allow multiple participants to use the data the `orconstraint` should be used. +It will permit the constraints contained to be evaluated using the `OR` operator. ```json { - "uid": "", - "prohibitions": [], - "obligations": [], "permissions": [ { "edctype": "dataspaceconnector:permission", "action": { - "type": "USE" + "type": "USE", }, "constraints": [ { - "edctype": "AtomicConstraint", - "leftExpression": { - "edctype": "dataspaceconnector:literalexpression", - "value": "BusinessPartnerNumber" - }, - "rightExpression": { - "edctype": "dataspaceconnector:literalexpression", - "value": [ "", "" ] - }, - "operator": "IN" + "edctype": "dataspaceconnector:orconstraint", + "constraints": [ + { + "edctype": "AtomicConstraint", + "leftExpression": { + "edctype": "dataspaceconnector:literalexpression", + "value": "BusinessPartnerNumber" + }, + "rightExpression": { + "edctype": "dataspaceconnector:literalexpression", + "value": "" + }, + "operator": "EQ" + }, + { + "edctype": "AtomicConstraint", + "leftExpression": { + "edctype": "dataspaceconnector:literalexpression", + "value": "BusinessPartnerNumber" + }, + "rightExpression": { + "edctype": "dataspaceconnector:literalexpression", + "value": "" + }, + "operator": "EQ" + }, + + ... + + // other constraints can be added + ] } - ] + ], + "duties": [] } ] } @@ -112,7 +119,7 @@ Please be aware that the EDC ignores all Rules and Constraint it does not unders --- -**Example 3 for accidentially public:** +**Example 1 for accidentially public:** ```json { "uid": "1", @@ -147,7 +154,7 @@ This policy is public available, even though the constraint is described correct --- -**Example 4 for accidentially public:** +**Example 2 for accidentally public:** ```json { @@ -179,4 +186,4 @@ This policy is public available, even though the constraint is described correct } ``` -This policy is public available, too. The cause is a typo in the left-expression of the constraint. This extension only registeres the Constraint.LeftExpression `BusinessPartnerNumber` within the EDC. Any other term will have the EDC ignore the corresponding constraint, hence interpret the polics as public policy. +This policy is public available, too. The cause is a typo in the left-expression of the constraint. This extension only registers the `Constraint.LeftExpression` `BusinessPartnerNumber` within the EDC. Any other term will have the EDC ignore the corresponding constraint, hence interpret the policies as public policy. diff --git a/edc-extensions/business-partner-validation/build.gradle.kts b/edc-extensions/business-partner-validation/build.gradle.kts new file mode 100644 index 000000000..53cb11e31 --- /dev/null +++ b/edc-extensions/business-partner-validation/build.gradle.kts @@ -0,0 +1,11 @@ + +plugins { + `java-library` + `maven-publish` +} + +dependencies { + api(edc.spi.core) + implementation(edc.spi.policy) + implementation(edc.spi.policyengine) +} diff --git a/edc-extensions/business-partner-validation/pom.xml b/edc-extensions/business-partner-validation/pom.xml deleted file mode 100644 index a9e761cc9..000000000 --- a/edc-extensions/business-partner-validation/pom.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - net.catenax.edc.extensions - edc-extensions - 0.1.6 - - 4.0.0 - - business-partner-validation - jar - - - ${project.groupId}_${project.artifactId} - - - - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - - - org.eclipse.dataspaceconnector - core-spi - - - org.eclipse.dataspaceconnector - policy-spi - - - org.eclipse.dataspaceconnector - policy-engine-spi - - - - - org.junit.jupiter - junit-jupiter - test - - - org.mockito - mockito-core - test - - - diff --git a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/BusinessPartnerValidationExtension.java b/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/BusinessPartnerValidationExtension.java deleted file mode 100644 index b183a0fcc..000000000 --- a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/BusinessPartnerValidationExtension.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.validation.businesspartner; - -import static org.eclipse.dataspaceconnector.spi.policy.engine.PolicyEngine.ALL_SCOPES; - -import net.catenax.edc.validation.businesspartner.functions.BusinessPartnerDutyFunction; -import net.catenax.edc.validation.businesspartner.functions.BusinessPartnerPermissionFunction; -import net.catenax.edc.validation.businesspartner.functions.BusinessPartnerProhibitionFunction; -import org.eclipse.dataspaceconnector.policy.model.Duty; -import org.eclipse.dataspaceconnector.policy.model.Permission; -import org.eclipse.dataspaceconnector.policy.model.Prohibition; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.policy.engine.PolicyEngine; -import org.eclipse.dataspaceconnector.spi.policy.engine.RuleBindingRegistry; -import org.eclipse.dataspaceconnector.spi.system.Requires; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtension; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; - -@Requires({RuleBindingRegistry.class, PolicyEngine.class}) -public class BusinessPartnerValidationExtension implements ServiceExtension { - - /** - * The key for business partner numbers constraints. Must be used as left operand when declaring - * constraints. - * - *

Example: - * - *

-   * {
-   *     "constraint": {
-   *         "leftOperand": "BusinessPartnerNumber",
-   *         "operator": "EQ",
-   *         "rightOperand": "BPNLCDQ90000X42KU"
-   *     }
-   * }
-   * 
- */ - public static final String BUSINESS_PARTNER_CONSTRAINT_KEY = "BusinessPartnerNumber"; - - @Override - public String name() { - return "Business Partner Validation Extension"; - } - - @Override - public void initialize(ServiceExtensionContext context) { - - final Monitor monitor = context.getMonitor(); - final PolicyEngine policyEngine = context.getService(PolicyEngine.class); - final RuleBindingRegistry ruleBindingRegistry = context.getService(RuleBindingRegistry.class); - - final BusinessPartnerDutyFunction dutyFunction = new BusinessPartnerDutyFunction(monitor); - final BusinessPartnerPermissionFunction permissionFunction = - new BusinessPartnerPermissionFunction(monitor); - final BusinessPartnerProhibitionFunction prohibitionFunction = - new BusinessPartnerProhibitionFunction(monitor); - - ruleBindingRegistry.bind("USE", ALL_SCOPES); - ruleBindingRegistry.bind(BUSINESS_PARTNER_CONSTRAINT_KEY, ALL_SCOPES); - - policyEngine.registerFunction( - ALL_SCOPES, Duty.class, BUSINESS_PARTNER_CONSTRAINT_KEY, dutyFunction); - policyEngine.registerFunction( - ALL_SCOPES, Permission.class, BUSINESS_PARTNER_CONSTRAINT_KEY, permissionFunction); - policyEngine.registerFunction( - ALL_SCOPES, Prohibition.class, BUSINESS_PARTNER_CONSTRAINT_KEY, prohibitionFunction); - } -} diff --git a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerDutyFunction.java b/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerDutyFunction.java deleted file mode 100644 index db7a7282b..000000000 --- a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerDutyFunction.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.validation.businesspartner.functions; - -import org.eclipse.dataspaceconnector.policy.model.Duty; -import org.eclipse.dataspaceconnector.policy.model.Operator; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.policy.engine.AtomicConstraintFunction; -import org.eclipse.dataspaceconnector.spi.policy.engine.PolicyContext; - -/** AtomicConstraintFunction to validate business partner numbers for edc duties. */ -public class BusinessPartnerDutyFunction extends AbstractBusinessPartnerValidation - implements AtomicConstraintFunction { - - public BusinessPartnerDutyFunction(Monitor monitor) { - super(monitor); - } - - @Override - public boolean evaluate(Operator operator, Object rightValue, Duty rule, PolicyContext context) { - return evaluate(operator, rightValue, context); - } -} diff --git a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerPermissionFunction.java b/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerPermissionFunction.java deleted file mode 100644 index 101f37054..000000000 --- a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerPermissionFunction.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.validation.businesspartner.functions; - -import org.eclipse.dataspaceconnector.policy.model.Operator; -import org.eclipse.dataspaceconnector.policy.model.Permission; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.policy.engine.AtomicConstraintFunction; -import org.eclipse.dataspaceconnector.spi.policy.engine.PolicyContext; - -/** AtomicConstraintFunction to validate business partner numbers for edc permissions. */ -public class BusinessPartnerPermissionFunction extends AbstractBusinessPartnerValidation - implements AtomicConstraintFunction { - - public BusinessPartnerPermissionFunction(Monitor monitor) { - super(monitor); - } - - @Override - public boolean evaluate( - Operator operator, Object rightValue, Permission rule, PolicyContext context) { - return evaluate(operator, rightValue, context); - } -} diff --git a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerProhibitionFunction.java b/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerProhibitionFunction.java deleted file mode 100644 index 4db6d9629..000000000 --- a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/BusinessPartnerProhibitionFunction.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.validation.businesspartner.functions; - -import org.eclipse.dataspaceconnector.policy.model.Operator; -import org.eclipse.dataspaceconnector.policy.model.Prohibition; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.policy.engine.AtomicConstraintFunction; -import org.eclipse.dataspaceconnector.spi.policy.engine.PolicyContext; - -/** AtomicConstraintFunction to validate business partner numbers for edc prohibitions. */ -public class BusinessPartnerProhibitionFunction extends AbstractBusinessPartnerValidation - implements AtomicConstraintFunction { - - public BusinessPartnerProhibitionFunction(Monitor monitor) { - super(monitor); - } - - @Override - public boolean evaluate( - Operator operator, Object rightValue, Prohibition rule, PolicyContext context) { - return evaluate(operator, rightValue, context); - } -} diff --git a/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/BusinessPartnerValidationExtension.java b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/BusinessPartnerValidationExtension.java new file mode 100644 index 000000000..f0edd6be2 --- /dev/null +++ b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/BusinessPartnerValidationExtension.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.validation.businesspartner; + +import static org.eclipse.edc.policy.engine.spi.PolicyEngine.ALL_SCOPES; + +import org.eclipse.edc.policy.engine.spi.PolicyEngine; +import org.eclipse.edc.policy.engine.spi.RuleBindingRegistry; +import org.eclipse.edc.policy.model.Duty; +import org.eclipse.edc.policy.model.Permission; +import org.eclipse.edc.policy.model.Prohibition; +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.validation.businesspartner.functions.BusinessPartnerDutyFunction; +import org.eclipse.tractusx.edc.validation.businesspartner.functions.BusinessPartnerPermissionFunction; +import org.eclipse.tractusx.edc.validation.businesspartner.functions.BusinessPartnerProhibitionFunction; + +public class BusinessPartnerValidationExtension implements ServiceExtension { + + /** + * The key for business partner numbers constraints. Must be used as left operand when declaring + * constraints. + * + *

Example: + * + *

+   * {
+   *     "constraint": {
+   *         "leftOperand": "BusinessPartnerNumber",
+   *         "operator": "EQ",
+   *         "rightOperand": "BPNLCDQ90000X42KU"
+   *     }
+   * }
+   * 
+ */ + public static final String BUSINESS_PARTNER_CONSTRAINT_KEY = "BusinessPartnerNumber"; + + public BusinessPartnerValidationExtension() {} + + public BusinessPartnerValidationExtension( + final RuleBindingRegistry ruleBindingRegistry, final PolicyEngine policyEngine) { + this.ruleBindingRegistry = ruleBindingRegistry; + this.policyEngine = policyEngine; + } + + @Inject private RuleBindingRegistry ruleBindingRegistry; + + @Inject private PolicyEngine policyEngine; + + @Override + public String name() { + return "Business Partner Validation Extension"; + } + + @Override + public void initialize(ServiceExtensionContext context) { + + final Monitor monitor = context.getMonitor(); + + final BusinessPartnerDutyFunction dutyFunction = new BusinessPartnerDutyFunction(monitor); + final BusinessPartnerPermissionFunction permissionFunction = + new BusinessPartnerPermissionFunction(monitor); + final BusinessPartnerProhibitionFunction prohibitionFunction = + new BusinessPartnerProhibitionFunction(monitor); + + ruleBindingRegistry.bind("USE", ALL_SCOPES); + ruleBindingRegistry.bind(BUSINESS_PARTNER_CONSTRAINT_KEY, ALL_SCOPES); + + policyEngine.registerFunction( + ALL_SCOPES, Duty.class, BUSINESS_PARTNER_CONSTRAINT_KEY, dutyFunction); + policyEngine.registerFunction( + ALL_SCOPES, Permission.class, BUSINESS_PARTNER_CONSTRAINT_KEY, permissionFunction); + policyEngine.registerFunction( + ALL_SCOPES, Prohibition.class, BUSINESS_PARTNER_CONSTRAINT_KEY, prohibitionFunction); + } +} diff --git a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidation.java b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidation.java similarity index 60% rename from edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidation.java rename to edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidation.java index e5f4eabe0..55cb0d52b 100644 --- a/edc-extensions/business-partner-validation/src/main/java/net/catenax/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidation.java +++ b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidation.java @@ -1,26 +1,31 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * Mercedes-Benz Tech Innovation GmbH - Right value of constraint can now contain iterable of BPNs + * 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 net.catenax.edc.validation.businesspartner.functions; +package org.eclipse.tractusx.edc.validation.businesspartner.functions; import java.util.Map; import java.util.Objects; -import org.eclipse.dataspaceconnector.policy.model.Operator; -import org.eclipse.dataspaceconnector.spi.agent.ParticipantAgent; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.policy.engine.PolicyContext; +import org.eclipse.edc.policy.engine.spi.PolicyContext; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.spi.agent.ParticipantAgent; +import org.eclipse.edc.spi.monitor.Monitor; /** * Abstract class for BusinessPartnerNumber validation. This class may be inherited from the EDC @@ -32,14 +37,10 @@ public abstract class AbstractBusinessPartnerValidation { // Problems reported to the policy context are not logged. Therefore, everything // that is reported to the policy context should be logged, too. - private static final String SKIP_EVALUATION_BECAUSE_ITERABLE_VALUE_NOT_STRING = - "Skipping evaluation of iterable value in BusinessPartnerNumber constraint. Right values used in an iterable must be of type 'String'. Unsupported type: '%s'"; private static final String FAIL_EVALUATION_BECAUSE_RIGHT_VALUE_NOT_STRING = "Failing evaluation because of invalid BusinessPartnerNumber constraint. For operator 'EQ' right value must be of type 'String'. Unsupported type: '%s'"; - private static final String FAIL_EVALUATION_BECAUSE_RIGHT_VALUE_NOT_ITERABLE = - "Failing evaluation because of invalid BusinessPartnerNumber constraint. For operator 'IN' right value must be of type 'Iterable'. Unsupported type: '%s'"; private static final String FAIL_EVALUATION_BECAUSE_UNSUPPORTED_OPERATOR = - "Failing evaluation because of invalid BusinessPartnerNumber constraint. As operator only 'EQ' or 'IN' are supported. Unsupported operator: '%s'"; + "Failing evaluation because of invalid BusinessPartnerNumber constraint. As operator only 'EQ' is supported. Unsupported operator: '%s'"; private final Monitor monitor; @@ -98,8 +99,6 @@ protected boolean evaluate( if (operator == Operator.EQ) { return isBusinessPartnerNumber(referringConnectorClaim, rightValue, policyContext); - } else if (operator == Operator.IN) { - return containsBusinessPartnerNumber(referringConnectorClaim, rightValue, policyContext); } else { final String message = String.format(FAIL_EVALUATION_BECAUSE_UNSUPPORTED_OPERATOR, operator); monitor.warning(message); @@ -108,53 +107,6 @@ protected boolean evaluate( } } - /** - * @param referringConnectorClaim of the participant - * @param businessPartnerNumbers object - * @return true if object is an iterable and constains a string that is successfully evaluated - * against the claim - */ - private boolean containsBusinessPartnerNumber( - String referringConnectorClaim, Object businessPartnerNumbers, PolicyContext policyContext) { - if (businessPartnerNumbers == null) { - final String message = - String.format(FAIL_EVALUATION_BECAUSE_RIGHT_VALUE_NOT_ITERABLE, "null"); - monitor.warning(message); - policyContext.reportProblem(message); - return false; - } - if (!(businessPartnerNumbers instanceof Iterable)) { - final String message = - String.format( - FAIL_EVALUATION_BECAUSE_RIGHT_VALUE_NOT_ITERABLE, - businessPartnerNumbers.getClass().getName()); - monitor.warning(message); - policyContext.reportProblem(message); - return false; - } - - for (Object businessPartnerNumber : (Iterable) businessPartnerNumbers) { - if (businessPartnerNumber == null) { - final String message = - String.format(SKIP_EVALUATION_BECAUSE_ITERABLE_VALUE_NOT_STRING, "null"); - monitor.warning(message); - policyContext.reportProblem(message); - } else if (!(businessPartnerNumber instanceof String)) { - final String message = - String.format( - SKIP_EVALUATION_BECAUSE_ITERABLE_VALUE_NOT_STRING, - businessPartnerNumber.getClass().getName()); - monitor.warning(message); - policyContext.reportProblem(message); - } else if (isCorrectBusinessPartner( - referringConnectorClaim, (String) businessPartnerNumber)) { - return true; // iterable does contain at least one matching value - } - } - - return false; - } - /** * @param referringConnectorClaim of the participant * @param businessPartnerNumber object diff --git a/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerDutyFunction.java b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerDutyFunction.java new file mode 100644 index 000000000..f53ba3cbc --- /dev/null +++ b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerDutyFunction.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.validation.businesspartner.functions; + +import org.eclipse.edc.policy.engine.spi.AtomicConstraintFunction; +import org.eclipse.edc.policy.engine.spi.PolicyContext; +import org.eclipse.edc.policy.model.Duty; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.spi.monitor.Monitor; + +/** AtomicConstraintFunction to validate business partner numbers for edc duties. */ +public class BusinessPartnerDutyFunction extends AbstractBusinessPartnerValidation + implements AtomicConstraintFunction { + + public BusinessPartnerDutyFunction(Monitor monitor) { + super(monitor); + } + + @Override + public boolean evaluate(Operator operator, Object rightValue, Duty rule, PolicyContext context) { + return evaluate(operator, rightValue, context); + } +} diff --git a/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerPermissionFunction.java b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerPermissionFunction.java new file mode 100644 index 000000000..07bda765e --- /dev/null +++ b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerPermissionFunction.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.validation.businesspartner.functions; + +import org.eclipse.edc.policy.engine.spi.AtomicConstraintFunction; +import org.eclipse.edc.policy.engine.spi.PolicyContext; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.policy.model.Permission; +import org.eclipse.edc.spi.monitor.Monitor; + +/** AtomicConstraintFunction to validate business partner numbers for edc permissions. */ +public class BusinessPartnerPermissionFunction extends AbstractBusinessPartnerValidation + implements AtomicConstraintFunction { + + public BusinessPartnerPermissionFunction(Monitor monitor) { + super(monitor); + } + + @Override + public boolean evaluate( + Operator operator, Object rightValue, Permission rule, PolicyContext context) { + return evaluate(operator, rightValue, context); + } +} diff --git a/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerProhibitionFunction.java b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerProhibitionFunction.java new file mode 100644 index 000000000..f3cddf9fe --- /dev/null +++ b/edc-extensions/business-partner-validation/src/main/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/BusinessPartnerProhibitionFunction.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.validation.businesspartner.functions; + +import org.eclipse.edc.policy.engine.spi.AtomicConstraintFunction; +import org.eclipse.edc.policy.engine.spi.PolicyContext; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.policy.model.Prohibition; +import org.eclipse.edc.spi.monitor.Monitor; + +/** AtomicConstraintFunction to validate business partner numbers for edc prohibitions. */ +public class BusinessPartnerProhibitionFunction extends AbstractBusinessPartnerValidation + implements AtomicConstraintFunction { + + public BusinessPartnerProhibitionFunction(Monitor monitor) { + super(monitor); + } + + @Override + public boolean evaluate( + Operator operator, Object rightValue, Prohibition rule, PolicyContext context) { + return evaluate(operator, rightValue, context); + } +} diff --git a/edc-extensions/business-partner-validation/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/business-partner-validation/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..eaadbabd1 --- /dev/null +++ b/edc-extensions/business-partner-validation/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +# +# Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2022 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# +org.eclipse.tractusx.edc.validation.businesspartner.BusinessPartnerValidationExtension diff --git a/edc-extensions/business-partner-validation/src/test/java/net/catenax/edc/validation/businesspartner/BusinessPartnerValidationExtensionTest.java b/edc-extensions/business-partner-validation/src/test/java/org/eclipse/tractusx/edc/validation/businesspartner/BusinessPartnerValidationExtensionTest.java similarity index 56% rename from edc-extensions/business-partner-validation/src/test/java/net/catenax/edc/validation/businesspartner/BusinessPartnerValidationExtensionTest.java rename to edc-extensions/business-partner-validation/src/test/java/org/eclipse/tractusx/edc/validation/businesspartner/BusinessPartnerValidationExtensionTest.java index 4ae06eb83..732379fc2 100644 --- a/edc-extensions/business-partner-validation/src/test/java/net/catenax/edc/validation/businesspartner/BusinessPartnerValidationExtensionTest.java +++ b/edc-extensions/business-partner-validation/src/test/java/org/eclipse/tractusx/edc/validation/businesspartner/BusinessPartnerValidationExtensionTest.java @@ -1,26 +1,32 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.validation.businesspartner; +package org.eclipse.tractusx.edc.validation.businesspartner; -import org.eclipse.dataspaceconnector.policy.model.Duty; -import org.eclipse.dataspaceconnector.policy.model.Permission; -import org.eclipse.dataspaceconnector.policy.model.Prohibition; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.policy.engine.PolicyEngine; -import org.eclipse.dataspaceconnector.spi.policy.engine.RuleBindingRegistry; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; +import org.eclipse.edc.policy.engine.spi.PolicyEngine; +import org.eclipse.edc.policy.engine.spi.RuleBindingRegistry; +import org.eclipse.edc.policy.model.Duty; +import org.eclipse.edc.policy.model.Permission; +import org.eclipse.edc.policy.model.Prohibition; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -32,22 +38,20 @@ class BusinessPartnerValidationExtensionTest { // mocks private ServiceExtensionContext serviceExtensionContext; private PolicyEngine policyEngine; + private RuleBindingRegistry ruleBindingRegistry; @BeforeEach void setup() { policyEngine = Mockito.mock(PolicyEngine.class); - RuleBindingRegistry ruleBindingRegistry = Mockito.mock(RuleBindingRegistry.class); + ruleBindingRegistry = Mockito.mock(RuleBindingRegistry.class); final Monitor monitor = Mockito.mock(Monitor.class); serviceExtensionContext = Mockito.mock(ServiceExtensionContext.class); Mockito.when(serviceExtensionContext.getMonitor()).thenReturn(monitor); - Mockito.when(serviceExtensionContext.getService(PolicyEngine.class)).thenReturn(policyEngine); - Mockito.when(serviceExtensionContext.getService(RuleBindingRegistry.class)) - .thenReturn(ruleBindingRegistry); - extension = new BusinessPartnerValidationExtension(); + extension = new BusinessPartnerValidationExtension(ruleBindingRegistry, policyEngine); } @Test diff --git a/edc-extensions/business-partner-validation/src/test/java/net/catenax/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidationTest.java b/edc-extensions/business-partner-validation/src/test/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidationTest.java similarity index 72% rename from edc-extensions/business-partner-validation/src/test/java/net/catenax/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidationTest.java rename to edc-extensions/business-partner-validation/src/test/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidationTest.java index b00232d5e..e8909c04e 100644 --- a/edc-extensions/business-partner-validation/src/test/java/net/catenax/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidationTest.java +++ b/edc-extensions/business-partner-validation/src/test/java/org/eclipse/tractusx/edc/validation/businesspartner/functions/AbstractBusinessPartnerValidationTest.java @@ -1,25 +1,31 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.validation.businesspartner.functions; +package org.eclipse.tractusx.edc.validation.businesspartner.functions; import java.util.Collections; import java.util.List; -import org.eclipse.dataspaceconnector.policy.model.Operator; -import org.eclipse.dataspaceconnector.spi.agent.ParticipantAgent; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.policy.engine.PolicyContext; +import org.eclipse.edc.policy.engine.spi.PolicyContext; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.spi.agent.ParticipantAgent; +import org.eclipse.edc.spi.monitor.Monitor; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -51,7 +57,7 @@ void BeforeEach() { @EnumSource(Operator.class) void testFailsOnUnsupportedOperations(Operator operator) { - if (operator == Operator.EQ || operator == Operator.IN) { // only allowed operator + if (operator == Operator.EQ) { // only allowed operator return; } @@ -72,7 +78,6 @@ void testFailsOnUnsupportedRightValue() { // invoke & assert Assertions.assertFalse(validation.evaluate(Operator.EQ, 1, policyContext)); - Assertions.assertFalse(validation.evaluate(Operator.IN, "foo", policyContext)); } @Test @@ -135,6 +140,9 @@ void testValidationWhenSingleParticipantIsValid() { Assertions.assertTrue(isContainedTrue); } + // In the past it was possible to use the 'IN' constraint with multiple BPNs as + // a list. This is no longer supported. + // The EDC must now always decline this kind of BPN format. @Test void testValidationForMultipleParticipants() { @@ -143,8 +151,8 @@ void testValidationForMultipleParticipants() { prepareBusinessPartnerClaim("foo"); // invoke & verify - Assertions.assertTrue(validation.evaluate(Operator.IN, List.of("foo", "bar"), policyContext)); - Assertions.assertTrue(validation.evaluate(Operator.IN, List.of(1, "foo"), policyContext)); + Assertions.assertFalse(validation.evaluate(Operator.IN, List.of("foo", "bar"), policyContext)); + Assertions.assertFalse(validation.evaluate(Operator.IN, List.of(1, "foo"), policyContext)); Assertions.assertFalse(validation.evaluate(Operator.IN, List.of("bar", "bar"), policyContext)); } diff --git a/edc-extensions/control-plane-adapter/README.md b/edc-extensions/control-plane-adapter/README.md new file mode 100644 index 000000000..7b6dfa31b --- /dev/null +++ b/edc-extensions/control-plane-adapter/README.md @@ -0,0 +1,92 @@ +# Control Plane Adapter Extension + +The goal of this extension is to simplify the process of retrieving data out of EDC. It returns "EndpointDataReference" object, hiding all the communication details for contract offers, contract negotiation process and retrieving DataReference from EDC control-plane. + +Additional requirements, that affects the architecture of the extension: +- can return data both in SYNC and ASYNC mode (currently only SYNC endpoint available) +- can be persistent, so that process can be restored from the point where it was before application was stopped +- scaling horizontally (when persistence is added to configuration) +- can retry failed part of the process (no need to start the process from the beginning) + +## Configuration: + +| Key | Description | Mandatory | Default | +|:-------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------|---------| +| edc.cp.adapter.default.message.retry.number | Number of retries of a message, in case of an error, within the internal process of retrieving DataReference | no | 3 | +| edc.cp.adapter.default.sync.request.timeout | Timeout for synchronous request (in seconds), after witch 'timeout' error will be returned to the requesting client | no | 20 | +| edc.cp.adapter.messagebus.inmemory.thread.number | Number of threads running within the in-memory implementation of MessageBus _ _ | no | 10 | +| edc.cp.adapter.reuse.contract.agreement | Turn on/off reusing of existing contract agreements for the specific asset. Once the contract is agreed, the second request for the same asset will reuse the agreement (if exists) pulled from the EDC. | no | true | +| edc.cp.adapter.cache.catalog.expire.after | Number of seconds, after witch prevoiusly requested catalog will not be reused, and will be removed from catalog cache | no | 300 | +| edc.cp.adapter.catalog.request.limit | Maximum number of items taken from Catalog within single request. Requests are repeated until all offers of the query are retrieved | no | 100 | + +By default, the extension works in "IN MEMORY" mode. This setup has some limitations: ++ It can work only within single EDC instance. If CP-adapter requests are handled by more than one EDC, data flow may be broken. ++ If the EDC instance is restarted, all running processes are lost. + +To run CP-Adapter in "PERSISTENT" mode, You need to create a proper tables with [this](docs/schema.sql) script, and add the following configuration values to Your control-plane EDC properties file: + +| Key | Description | +|-----------------------------------|-------------| +| edc.datasource.cpadapter.name | data source name | +| edc.datasource.cpadapter.url | data source url | +| edc.datasource.cpadapter.user | data source user | +| edc.datasource.cpadapter.password | data source password | + + +## How to use it: +1. Client sends a GET request with two parameters: assetId and the url of the provider control-plane: + + ``` + /adapter/asset/sync/{assetId}?providerUrl={providerUrl} + ``` + + The example ULR could be: + + ``` + http://localhost:9193/api/v1/data/adapter/asset/sync/123?providerUrl=http://localhost:8182/api/v1/ids/data + ``` + + Optional request parameters, that overwrite the settings for a single request: + + | Name | Description | + |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--- | + | contractAgreementId | Defines the ID of existing contract agreement, that should be reused for retrieving the asset. If parameter is specified, but contract is not found, 404 error will be returned. | + | contractAgreementReuse | Similar to edc.cp.adapter.reuse.contract.agreement option allows to turn off reusing of existing contracts, but on a request level. Set the parameter value to 'false' and new contract agrement will be negotiated. | + | timeout | Similar to edc.cp.adapter.default.sync.request.timeout, defines the maximum time of the request. If data is not ready, time out error will be returned. | + + The controller is registered under the context alias of DataManagement API. The authentication depends on the DataManagement configuration. + To find out more please visit: + + [api-configuration](../../edc/extensions/control-plane/api/data-management/api-configuration/README.md) + + [data-management](../../edc/extensions/control-plane/api/data-management/README.md) + + +2. EndpointDataReference object is returned. Example of the EndpointDataReference response: + ```json + { + "id": "ee8b758a-4b02-4cca-bb37-d0256b4638e7", + "endpoint": "http://consumer-dataplane:9192/publicsubmodel?provider-connector-url=...", + "authKey": "Authorization", + "authCode": "eyJhbGciOiJSUzI1NiJ9.eyJkYWQiOi...", + "properties": { + "cid": "1:b2367617-5f51-48c5-9f25-e30a7299235c" + } + } + ``` + +3. Client, using the DataReference, retrieves the Asset through data-plane. + + Example of the data-plane GET request, to retrieve Asset, with DataReference information: + + ``` + url: http://consumer-dataplane:9192/publicsubmodel?provider-connector-url=... {endpoint} + header: Authorization:eyJhbGciOiJSUzI1NiJ9.eyJkYWQiOi... {authKey:authCode} + ``` + +### Internal design of the extension: + +![diagram](src/main/resources/control-plane-adapter.jpg) + + + diff --git a/edc-extensions/control-plane-adapter/build.gradle.kts b/edc-extensions/control-plane-adapter/build.gradle.kts new file mode 100644 index 000000000..715b5da74 --- /dev/null +++ b/edc-extensions/control-plane-adapter/build.gradle.kts @@ -0,0 +1,25 @@ + +plugins { + `java-library` + `maven-publish` +} + +dependencies { + implementation(edc.spi.core) + implementation(edc.spi.policy) + implementation(edc.api.management) + implementation(edc.spi.catalog) + implementation(edc.spi.transactionspi) + implementation(edc.spi.transaction.datasource) + implementation(edc.ids) + implementation(edc.sql.core) + implementation(edc.sql.lease) + implementation(edc.sql.pool) + + + implementation(libs.postgres) + implementation(libs.jakarta.rsApi) + + + implementation(edc.spi.aggregateservices) +} diff --git a/edc-extensions/control-plane-adapter/docs/schema.sql b/edc-extensions/control-plane-adapter/docs/schema.sql new file mode 100644 index 000000000..3e64d3c45 --- /dev/null +++ b/edc-extensions/control-plane-adapter/docs/schema.sql @@ -0,0 +1,54 @@ +-- +-- Copyright (c) 2022 ZF Friedrichshafen AG +-- +-- This program and the accompanying materials are made available under the +-- terms of the Apache License, Version 2.0 which is available at +-- https://www.apache.org/licenses/LICENSE-2.0 +-- +-- SPDX-License-Identifier: Apache-2.0 +-- +-- Contributors: +-- ZF Friedrichshafen AG - Initial SQL Query +-- + +-- Statements are designed for and tested with Postgres only! + + +CREATE TABLE IF NOT EXISTS edc_lease +( + leased_by VARCHAR NOT NULL, + leased_at BIGINT, + lease_duration INTEGER NOT NULL, + lease_id VARCHAR NOT NULL + CONSTRAINT lease_pk + PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS edc_cpadapter_queue +( + id VARCHAR NOT NULL, + created_at BIGINT NOT NULL, + channel VARCHAR, + message JSON, + invoke_after BIGINT NOT NULL, + lease_id VARCHAR + CONSTRAINT cpadapter_queue_lease_lease_id_fk + REFERENCES edc_lease + ON DELETE SET NULL, + PRIMARY KEY (id) +); + +CREATE UNIQUE INDEX IF NOT EXISTS edc_cpadapter_queue_id_uindex + ON edc_cpadapter_queue (id); + +CREATE TABLE IF NOT EXISTS edc_cpadapter_object_store +( + id VARCHAR NOT NULL, + created_at BIGINT NOT NULL, + type VARCHAR, + object JSON, + PRIMARY KEY (id) +); + + + diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/ApiAdapterConfig.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/ApiAdapterConfig.java new file mode 100644 index 000000000..cd243f9ba --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/ApiAdapterConfig.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter; + +import org.eclipse.edc.spi.system.ServiceExtensionContext; + +public class ApiAdapterConfig { + private static final String DEFAULT_MESSAGE_RETRY_NUMBER = + "edc.cp.adapter.default.message.retry.number"; + private static final String DEFAULT_SYNC_REQUEST_TIMEOUT = + "edc.cp.adapter.default.sync.request.timeout"; + private static final String CATALOG_EXPIRE_AFTER_TIME = + "edc.cp.adapter.cache.catalog.expire.after"; + private static final String REUSE_CONTRACT_AGREEMENT = "edc.cp.adapter.reuse.contract.agreement"; + private static final String CATALOG_REQUEST_LIMIT = "edc.cp.adapter.catalog.request.limit"; + + private static final String DATASOURCE_NAME = "edc.datasource.cpadapter.name"; + private static final String DATASOURCE_URL = "edc.datasource.cpadapter.url"; + private static final String DATASOURCE_USER = "edc.datasource.cpadapter.user"; + private static final String DATASOURCE_PASS = "edc.datasource.cpadapter.password"; + + private static final String IN_MEMORY_MESSAGE_BUS_THREAD_NUMBER = + "edc.cp.adapter.messagebus.inmemory.thread.number"; + private static final String SQL_MESSAGE_BUS_THREAD_NUMBER = + "edc.cp.adapter.messagebus.sql.thread.number"; + private static final String SQL_MESSAGE_BUS_MAX_DELIVERY = + "edc.cp.adapter.messagebus.sql.max.delivery"; + private static final String SQL_MESSAGE_BUS_DELIVERY_INTERVAL = + "edc.cp.adapter.messagebus.sql.max.delivery"; + + private final ServiceExtensionContext context; + + public ApiAdapterConfig(ServiceExtensionContext context) { + this.context = context; + } + + public int getDefaultMessageRetryNumber() { + return context.getSetting(DEFAULT_MESSAGE_RETRY_NUMBER, 3); + } + + public int getDefaultSyncRequestTimeout() { + return context.getSetting(DEFAULT_SYNC_REQUEST_TIMEOUT, 20); + } + + public int getInMemoryMessageBusThreadNumber() { + return context.getSetting(IN_MEMORY_MESSAGE_BUS_THREAD_NUMBER, 10); + } + + public boolean isContractAgreementReuseOn() { + return context.getSetting(REUSE_CONTRACT_AGREEMENT, true); + } + + public int getCatalogExpireAfterTime() { + return context.getSetting(CATALOG_EXPIRE_AFTER_TIME, 180); + } + + public int getCatalogRequestLimit() { + return context.getSetting(CATALOG_REQUEST_LIMIT, 100); + } + + public String getDataSourceName() { + return context.getSetting(DATASOURCE_NAME, "cpadapter"); + } + + public String getDataSourceUrl() { + return context.getSetting(DATASOURCE_URL, null); + } + + public String getDataSourceUser() { + return context.getSetting(DATASOURCE_USER, null); + } + + public String getDataSourcePass() { + return context.getSetting(DATASOURCE_PASS, null); + } + + public int getSqlMessageBusThreadNumber() { + return context.getSetting(SQL_MESSAGE_BUS_THREAD_NUMBER, 10); + } + + public int getSqlMessageBusMaxDelivery() { + return context.getSetting(SQL_MESSAGE_BUS_MAX_DELIVERY, 10); + } + + public int getSqlMessageBusDeliveryInterval() { + return context.getSetting(SQL_MESSAGE_BUS_DELIVERY_INTERVAL, 1); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/ApiAdapterExtension.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/ApiAdapterExtension.java new file mode 100644 index 000000000..16eb0a32a --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/ApiAdapterExtension.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter; + +import static java.util.Objects.nonNull; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.Clock; +import java.util.Objects; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.eclipse.edc.connector.api.management.configuration.ManagementApiConfiguration; +import org.eclipse.edc.connector.contract.spi.negotiation.observe.ContractNegotiationListener; +import org.eclipse.edc.connector.contract.spi.negotiation.observe.ContractNegotiationObservable; +import org.eclipse.edc.connector.spi.catalog.CatalogService; +import org.eclipse.edc.connector.spi.contractagreement.ContractAgreementService; +import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationService; +import org.eclipse.edc.connector.spi.transferprocess.TransferProcessService; +import org.eclipse.edc.connector.transfer.spi.edr.EndpointDataReferenceReceiver; +import org.eclipse.edc.connector.transfer.spi.edr.EndpointDataReferenceReceiverRegistry; +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.edc.transaction.datasource.spi.DataSourceRegistry; +import org.eclipse.edc.transaction.spi.TransactionContext; +import org.eclipse.edc.web.spi.WebService; +import org.eclipse.tractusx.edc.cp.adapter.messaging.*; +import org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation.CatalogCachedRetriever; +import org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation.CatalogRetriever; +import org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation.ContractAgreementRetriever; +import org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation.ContractNegotiationHandler; +import org.eclipse.tractusx.edc.cp.adapter.process.contractnotification.*; +import org.eclipse.tractusx.edc.cp.adapter.process.datareference.*; +import org.eclipse.tractusx.edc.cp.adapter.service.ErrorResultService; +import org.eclipse.tractusx.edc.cp.adapter.service.ResultService; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreService; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreServiceInMemory; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreServiceSql; +import org.eclipse.tractusx.edc.cp.adapter.store.SqlObjectStore; +import org.eclipse.tractusx.edc.cp.adapter.store.SqlQueueStore; +import org.eclipse.tractusx.edc.cp.adapter.store.schema.postgres.PostgresDialectObjectStoreStatements; +import org.eclipse.tractusx.edc.cp.adapter.store.schema.postgres.PostgresDialectQueueStatements; +import org.eclipse.tractusx.edc.cp.adapter.util.ExpiringMap; +import org.eclipse.tractusx.edc.cp.adapter.util.LockMap; + +public class ApiAdapterExtension implements ServiceExtension { + @Inject private Monitor monitor; + @Inject private ContractNegotiationObservable negotiationObservable; + @Inject private WebService webService; + @Inject private ContractNegotiationService contractNegotiationService; + @Inject private EndpointDataReferenceReceiverRegistry receiverRegistry; + @Inject private ManagementApiConfiguration apiConfig; + @Inject private TransferProcessService transferProcessService; + @Inject private TransactionContext transactionContext; + @Inject private CatalogService catalogService; + @Inject private ContractAgreementService agreementService; + @Inject private DataSourceRegistry dataSourceRegistry; + @Inject private Clock clock; + + @Override + public String name() { + return "Control Plane Adapter Extension"; + } + + @Override + public void initialize(ServiceExtensionContext context) { + ApiAdapterConfig config = new ApiAdapterConfig(context); + ListenerService listenerService = new ListenerService(); + + MessageBus messageBus = createMessageBus(listenerService, context, config); + ObjectStoreService storeService = getStoreService(context, config); + + ResultService resultService = new ResultService(config.getDefaultSyncRequestTimeout(), monitor); + ErrorResultService errorResultService = new ErrorResultService(monitor, messageBus); + + ContractNotificationSyncService contractSyncService = + new ContractSyncService(storeService, new LockMap()); + + DataTransferInitializer dataTransferInitializer = + new DataTransferInitializer(monitor, transferProcessService); + + ContractNotificationHandler contractNotificationHandler = + new ContractNotificationHandler( + monitor, + messageBus, + contractSyncService, + contractNegotiationService, + dataTransferInitializer); + + ContractNegotiationHandler contractNegotiationHandler = + getContractNegotiationHandler(monitor, contractNegotiationService, messageBus, config); + + DataRefNotificationSyncService dataRefSyncService = + new DataRefSyncService(storeService, new LockMap()); + DataReferenceHandler dataReferenceHandler = + new DataReferenceHandler(monitor, messageBus, dataRefSyncService); + + listenerService.addListener(Channel.INITIAL, contractNegotiationHandler); + listenerService.addListener(Channel.CONTRACT_CONFIRMATION, contractNotificationHandler); + listenerService.addListener(Channel.DATA_REFERENCE, dataReferenceHandler); + listenerService.addListener(Channel.RESULT, resultService); + listenerService.addListener(Channel.DLQ, errorResultService); + + initHttpController(messageBus, resultService, config); + initContractNegotiationListener( + negotiationObservable, messageBus, contractSyncService, dataTransferInitializer); + initDataReferenceReceiver(messageBus, dataRefSyncService); + initDataRefErrorHandler(messageBus, storeService, transferProcessService); + } + + private MessageBus createMessageBus( + ListenerService listenerService, ServiceExtensionContext context, ApiAdapterConfig config) { + if (!isPersistenceConfigured(config)) { + monitor.info( + "Persistent layer configuration is missing. Starting MessageBus in 'IN MEMORY' mode."); + return new InMemoryMessageBus( + monitor, listenerService, config.getInMemoryMessageBusThreadNumber()); + } + + SqlQueueStore sqlQueueStore = + new SqlQueueStore( + dataSourceRegistry, + config.getDataSourceName(), + transactionContext, + context.getTypeManager().getMapper(), + new PostgresDialectQueueStatements(), + context.getConnectorId(), + clock); + SqlMessageBus messageBus = + new SqlMessageBus( + monitor, + listenerService, + sqlQueueStore, + config.getSqlMessageBusThreadNumber(), + config.getSqlMessageBusMaxDelivery()); + initMessageBus(messageBus, config); + return messageBus; + } + + private ObjectStoreService getStoreService( + ServiceExtensionContext context, ApiAdapterConfig config) { + if (!isPersistenceConfigured(config)) { + monitor.info( + "Persistent layer configuration is missing. Starting Control Plane Adapter Extension in 'IN MEMORY' mode."); + return new ObjectStoreServiceInMemory(context.getTypeManager().getMapper()); + } + + ObjectMapper mapper = context.getTypeManager().getMapper(); + SqlObjectStore objectStore = + new SqlObjectStore( + dataSourceRegistry, + config.getDataSourceName(), + transactionContext, + mapper, + new PostgresDialectObjectStoreStatements()); + return new ObjectStoreServiceSql(mapper, objectStore); + } + + private void initMessageBus(SqlMessageBus messageBus, ApiAdapterConfig config) { + final int poolSize = 1; + final int initialDelay = 5; + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(poolSize); + scheduler.scheduleAtFixedRate( + () -> messageBus.deliverMessages(config.getSqlMessageBusMaxDelivery()), + initialDelay, + config.getSqlMessageBusDeliveryInterval(), + TimeUnit.SECONDS); + } + + private void initHttpController( + MessageBus messageBus, ResultService resultService, ApiAdapterConfig config) { + webService.registerResource( + apiConfig.getContextAlias(), + new HttpController(monitor, resultService, messageBus, config)); + } + + private ContractNegotiationHandler getContractNegotiationHandler( + Monitor monitor, + ContractNegotiationService contractNegotiationService, + MessageBus messageBus, + ApiAdapterConfig config) { + return new ContractNegotiationHandler( + monitor, + messageBus, + contractNegotiationService, + new CatalogCachedRetriever( + new CatalogRetriever(config.getCatalogRequestLimit(), catalogService), + new ExpiringMap<>()), + new ContractAgreementRetriever(monitor, agreementService)); + } + + private void initDataReferenceReceiver( + MessageBus messageBus, DataRefNotificationSyncService dataRefSyncService) { + EndpointDataReferenceReceiver dataReferenceReceiver = + new EndpointDataReferenceReceiverImpl(monitor, messageBus, dataRefSyncService); + receiverRegistry.registerReceiver(dataReferenceReceiver); + } + + private void initContractNegotiationListener( + ContractNegotiationObservable negotiationObservable, + MessageBus messageBus, + ContractNotificationSyncService contractSyncService, + DataTransferInitializer dataTransferInitializer) { + ContractNegotiationListener contractNegotiationListener = + new ContractNegotiationListenerImpl( + monitor, messageBus, contractSyncService, dataTransferInitializer); + if (nonNull(negotiationObservable)) { + negotiationObservable.registerListener(contractNegotiationListener); + } + } + + private void initDataRefErrorHandler( + MessageBus messageBus, + ObjectStoreService objectStore, + TransferProcessService transferProcessService) { + + final int poolSize = 1; + final int initialDelay = 5; + final int interval = 5; + ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(poolSize); + + DataReferenceErrorHandler errorHandler = + new DataReferenceErrorHandler(monitor, messageBus, objectStore, transferProcessService); + + scheduler.scheduleAtFixedRate( + errorHandler::validateActiveProcesses, initialDelay, interval, TimeUnit.SECONDS); + } + + private boolean isPersistenceConfigured(ApiAdapterConfig config) { + return Objects.nonNull(config.getDataSourceName()) + && Objects.nonNull(config.getDataSourceUrl()); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/HttpController.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/HttpController.java new file mode 100644 index 000000000..1d6bbc3fa --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/HttpController.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter; + +import static java.util.Objects.isNull; + +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.util.string.StringUtils; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.eclipse.tractusx.edc.cp.adapter.service.ResultService; + +@Consumes({MediaType.APPLICATION_JSON}) +@Produces({MediaType.APPLICATION_JSON}) +@Path("/adapter/asset") +@RequiredArgsConstructor +public class HttpController { + private final Monitor monitor; + private final ResultService resultService; + private final MessageBus messageBus; + private final ApiAdapterConfig config; + + @GET + @Path("sync/{assetId}") + public Response getAssetSynchronous( + @PathParam("assetId") String assetId, + @QueryParam("providerUrl") String providerUrl, + @QueryParam("contractAgreementId") String contractAgreementId, + @QueryParam("contractAgreementReuse") @DefaultValue("true") boolean contractAgreementReuse, + @QueryParam("timeout") String timeout) { + + if (invalidParams(assetId, providerUrl)) { + return badRequestResponse(); + } + + String traceId = + initiateProcess(assetId, providerUrl, contractAgreementId, contractAgreementReuse); + + try { + ProcessData processData = + StringUtils.isNullOrEmpty(timeout) || !isNumeric(timeout) + ? resultService.pull(traceId) + : resultService.pull(traceId, Long.parseLong(timeout), TimeUnit.SECONDS); + + if (Objects.isNull(processData)) { + return notFoundResponse(); + } + if (Objects.nonNull(processData.getErrorStatus())) { + return errorResponse(processData); + } + if (Objects.nonNull(processData.getEndpointDataReference())) { + return okResponse(processData); + } + return timeoutResponse(); + } catch (InterruptedException e) { + monitor.severe("InterruptedException", e); + return notFoundResponse(); + } + } + + private Response badRequestResponse() { + return Response.status(Response.Status.BAD_REQUEST) + .entity("AssetId or providerUrl is empty!") + .build(); + } + + private boolean invalidParams(String assetId, String providerUrl) { + return isNull(assetId) || assetId.isBlank() || isNull(providerUrl) || providerUrl.isBlank(); + } + + private String initiateProcess( + String assetId, + String providerUrl, + String contractAgreementId, + boolean contractAgreementReuse) { + ProcessData processData = + ProcessData.builder() + .assetId(assetId) + .provider(providerUrl) + .contractAgreementId(contractAgreementId) + .contractAgreementReuseOn(isContractAgreementReuseOn(contractAgreementReuse)) + .catalogExpiryTime(config.getCatalogExpireAfterTime()) + .build(); + + Message message = + new DataReferenceRetrievalDto(processData, config.getDefaultMessageRetryNumber()); + messageBus.send(Channel.INITIAL, message); + return message.getTraceId(); + } + + private boolean isContractAgreementReuseOn(boolean contractAgreementReuse) { + return contractAgreementReuse && config.isContractAgreementReuseOn(); + } + + private Response notFoundResponse() { + return Response.status(Response.Status.NOT_FOUND) + .entity(Response.Status.NOT_FOUND.getReasonPhrase()) + .build(); + } + + private Response errorResponse(ProcessData processData) { + return Response.status(processData.getErrorStatus()) + .entity(processData.getErrorMessage()) + .build(); + } + + private Response okResponse(ProcessData processData) { + return Response.status(Response.Status.OK) + .entity(processData.getEndpointDataReference()) + .build(); + } + + private Response timeoutResponse() { + return Response.status(Response.Status.REQUEST_TIMEOUT) + .entity(Response.Status.REQUEST_TIMEOUT.getReasonPhrase()) + .build(); + } + + private boolean isNumeric(String str) { + return str != null && str.matches("[0-9]+"); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/dto/DataReferenceRetrievalDto.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/dto/DataReferenceRetrievalDto.java new file mode 100644 index 000000000..675a991e4 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/dto/DataReferenceRetrievalDto.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.dto; + +import lombok.NoArgsConstructor; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; + +@NoArgsConstructor +public class DataReferenceRetrievalDto extends Message { + public DataReferenceRetrievalDto(ProcessData payload, int retryLimit) { + super(payload, retryLimit); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/dto/ProcessData.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/dto/ProcessData.java new file mode 100644 index 000000000..98792df2a --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/dto/ProcessData.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.dto; + +import static java.lang.System.currentTimeMillis; + +import jakarta.ws.rs.core.Response; +import lombok.*; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; + +@Getter +@ToString +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProcessData { + private final long timestamp = currentTimeMillis(); + + // request data + private String assetId; + private String provider; + private String contractOfferId; + private int catalogExpiryTime; + private boolean contractAgreementReuseOn; + + // contract data + @Setter private String contractNegotiationId; + @Setter private String contractAgreementId; + @Builder.Default @Setter private boolean isContractConfirmed = false; + @Setter private String transferProcessId; + + // result/response data + @Setter private EndpointDataReference endpointDataReference; + @Setter private String errorMessage; + @Setter private Response.Status errorStatus; +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ConfigurationException.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ConfigurationException.java new file mode 100644 index 000000000..bd8e2ad2a --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ConfigurationException.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.exception; + +public class ConfigurationException extends RuntimeException { + public ConfigurationException(String message) { + super(message); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ExternalRequestException.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ExternalRequestException.java new file mode 100644 index 000000000..f8bcb8939 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ExternalRequestException.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.exception; + +public class ExternalRequestException extends RuntimeException { + public ExternalRequestException(String message) { + super(message); + } + + public ExternalRequestException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ResourceNotFoundException.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ResourceNotFoundException.java new file mode 100644 index 000000000..bde662d42 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/exception/ResourceNotFoundException.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.exception; + +public class ResourceNotFoundException extends RuntimeException { + public ResourceNotFoundException(String message) { + super(message); + } + + public ResourceNotFoundException(String message, Exception e) { + super(message, e); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Channel.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Channel.java new file mode 100644 index 000000000..170c6fc3d --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Channel.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +public enum Channel { + INITIAL, + CONTRACT_CONFIRMATION, + DATA_REFERENCE, + RESULT, + DLQ +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/InMemoryMessageBus.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/InMemoryMessageBus.java new file mode 100644 index 000000000..6b4043e1f --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/InMemoryMessageBus.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +import static java.util.Objects.isNull; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.eclipse.edc.spi.monitor.Monitor; + +public class InMemoryMessageBus implements MessageBus { + private final Monitor monitor; + private final ListenerService listenerService; + private final ScheduledExecutorService executorService; + + public InMemoryMessageBus(Monitor monitor, ListenerService listenerService, int threadPoolSize) { + this.monitor = monitor; + this.listenerService = listenerService; + executorService = Executors.newScheduledThreadPool(threadPoolSize); + } + + @Override + public void send(Channel name, Message message) { + if (isNull(message)) { + monitor.warning(String.format("Message is empty, channel: %s", name)); + } else { + monitor.info(String.format("[%s] Message sent to channel: %s", message.getTraceId(), name)); + executorService.submit(() -> run(name, message)); + } + } + + /** Returns 'false' if message processing should be retried. * */ + protected boolean run(Channel name, Message message) { + try { + listenerService.getListener(name).process(message); + message.clearErrors(); + return true; + } catch (Exception e) { + monitor.warning(String.format("[%s] Message processing error.", message.getTraceId()), e); + if (!message.canRetry()) { + monitor.warning(String.format("[%s] Message reached retry limit!", message.getTraceId())); + sendMessageToDlq(message, e); + return true; + } + long delayTime = message.unsucceeded(); + executorService.schedule(() -> send(name, message), delayTime, TimeUnit.MILLISECONDS); + return false; + } + } + + private void sendMessageToDlq(Message message, Exception finalException) { + message.clearErrors(); + message.setFinalException(finalException); + run(Channel.DLQ, message); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Listener.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Listener.java new file mode 100644 index 000000000..911ba8902 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Listener.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +public interface Listener

> { + void process(P message); +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/ListenerService.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/ListenerService.java new file mode 100644 index 000000000..3e79e3e6f --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/ListenerService.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +import static java.util.Objects.isNull; + +import java.util.HashMap; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import org.eclipse.tractusx.edc.cp.adapter.exception.ConfigurationException; + +@RequiredArgsConstructor +public class ListenerService { + /** only single listener for a message at the moment * */ + private final Map listeners = new HashMap<>(); + + public void addListener(Channel name, Listener listener) { + listeners.put(name, listener); + } + + public void removeListener(Channel name) { + listeners.remove(name); + } + + Listener getListener(Channel name) { + Listener listener = listeners.get(name); + if (isNull(listener)) { + throw new ConfigurationException("No listener found for channel: " + name); + } + return listener; + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Message.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Message.java new file mode 100644 index 000000000..9bb67c414 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/Message.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +import java.util.UUID; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@NoArgsConstructor +@Getter +@Setter +public abstract class Message { + private String traceId; + private T payload; + private int errorNumber; + private int retryLimit; + private Exception exception; + private Exception finalException; + + public Message(String traceId, T payload, int retryLimit) { + this.traceId = traceId; + this.retryLimit = retryLimit; + this.payload = payload; + } + + public Message(T payload, int retryLimit) { + this.traceId = UUID.randomUUID().toString(); + this.retryLimit = retryLimit; + this.payload = payload; + } + + protected long unsucceeded() { + errorNumber++; + return getDelayTime(); + } + + protected void clearErrors() { + errorNumber = 0; + } + + protected boolean canRetry() { + return errorNumber < retryLimit; + } + + protected void setFinalException(Exception e) { + this.finalException = e; + } + + private int getDelayTime() { + return errorNumber < 5 ? errorNumber * 750 : (int) Math.pow(errorNumber, 2) * 150; + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/MessageBus.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/MessageBus.java new file mode 100644 index 000000000..b1021dd6d --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/MessageBus.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +public interface MessageBus { + void send(Channel name, Message message); +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/SqlMessageBus.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/SqlMessageBus.java new file mode 100644 index 000000000..d76079c53 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/messaging/SqlMessageBus.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +import static java.util.Objects.isNull; + +import java.time.Instant; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.store.SqlQueueStore; +import org.eclipse.tractusx.edc.cp.adapter.store.model.QueueMessage; + +public class SqlMessageBus implements MessageBus { + private final int maxDelivery; + private final Monitor monitor; + private final ListenerService listenerService; + private final ScheduledExecutorService executorService; + private final SqlQueueStore store; + + public SqlMessageBus( + Monitor monitor, + ListenerService listenerService, + SqlQueueStore sqlQueueStore, + int threadPoolSize, + int maxDelivery) { + this.monitor = monitor; + this.listenerService = listenerService; + this.store = sqlQueueStore; + this.maxDelivery = maxDelivery; + this.executorService = Executors.newScheduledThreadPool(threadPoolSize); + } + + @Override + public void send(Channel channel, Message message) { + if (isNull(message)) { + monitor.warning(String.format("Message is empty, channel: %s", channel)); + return; + } + monitor.info(String.format("[%s] Message sent to channel: %s", message.getTraceId(), channel)); + long now = Instant.now().toEpochMilli(); + store.saveMessage( + QueueMessage.builder().channel(channel.name()).message(message).invokeAfter(now).build()); + + deliverMessages(maxDelivery); + } + + public void deliverMessages(int maxElements) { + List queueMessages = store.findMessagesToSend(maxElements); + monitor.debug(String.format("Found [%d] messages to send.", queueMessages.size())); + queueMessages.forEach( + queueMessage -> executorService.submit(() -> deliverMessage(queueMessage))); + } + + private void deliverMessage(QueueMessage queueMessage) { + Channel channel = Channel.valueOf(queueMessage.getChannel()); + Message message = queueMessage.getMessage(); + + int currentErrorNumber = message.getErrorNumber(); + message.clearErrors(); + + try { + listenerService.getListener(channel).process(message); + store.deleteMessage(queueMessage.getId()); + monitor.debug(String.format("[%s] Message sent and removed.", queueMessage.getId())); + } catch (Exception e) { + monitor.warning(String.format("[%s] Message processing error.", message.getTraceId()), e); + message.setErrorNumber(currentErrorNumber); + if (!message.canRetry()) { + monitor.warning(String.format("[%s] Message reached retry limit!", message.getTraceId())); + sendMessageToDlq(message, e); + store.deleteMessage(queueMessage.getId()); + return; + } + long delayTime = message.unsucceeded(); + long now = Instant.now().toEpochMilli(); + queueMessage.setInvokeAfter(now + delayTime); + message.setException(e); + store.updateMessage(queueMessage); + } + } + + private void sendMessageToDlq(Message message, Exception finalException) { + message.clearErrors(); + message.setFinalException(finalException); + send(Channel.DLQ, message); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogCachedRetriever.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogCachedRetriever.java new file mode 100644 index 000000000..b57d6c9bc --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogCachedRetriever.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation; + +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.catalog.spi.Catalog; +import org.eclipse.edc.util.collection.CollectionUtil; +import org.eclipse.tractusx.edc.cp.adapter.util.ExpiringMap; + +@RequiredArgsConstructor +public class CatalogCachedRetriever { + private final CatalogRetriever catalogRetriever; + private final ExpiringMap catalogCache; + + public Catalog getEntireCatalog(String providerUrl, int catalogExpiryTime) { + return getEntireCatalog(providerUrl, null, catalogExpiryTime); + } + + public Catalog getEntireCatalog(String providerUrl, String assetId, int catalogExpiryTime) { + Catalog catalog = catalogCache.get(getKey(providerUrl, assetId), catalogExpiryTime); + if (Objects.nonNull(catalog)) { + return catalog; + } + + catalog = catalogRetriever.getEntireCatalog(providerUrl, assetId); + + if (Objects.nonNull(catalog) && CollectionUtil.isNotEmpty(catalog.getContractOffers())) { + catalogCache.put(getKey(providerUrl, assetId), catalog); + } + + return catalog; + } + + private String getKey(String providerUrl, String assetId) { + return providerUrl + "::" + assetId; + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogRetriever.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogRetriever.java new file mode 100644 index 000000000..51ccef238 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogRetriever.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.ExecutionException; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.catalog.spi.Catalog; +import org.eclipse.edc.connector.spi.catalog.CatalogService; +import org.eclipse.edc.spi.query.Criterion; +import org.eclipse.edc.spi.query.QuerySpec; +import org.eclipse.tractusx.edc.cp.adapter.exception.ExternalRequestException; + +@RequiredArgsConstructor +public class CatalogRetriever { + private final int limit; + private final CatalogService catalogService; + + public Catalog getEntireCatalog(String providerUrl) { + return getEntireCatalog(providerUrl, null); + } + + public Catalog getEntireCatalog(String providerUrl, String assetId) { + int offset = 0; + + Catalog catalogResult = getCatalog(providerUrl, getQuerySpec(limit, offset, assetId)); + boolean reachedLastPage = catalogResult.getContractOffers().size() < limit; + + while (!reachedLastPage) { + offset += limit; + Catalog catalog = getCatalog(providerUrl, getQuerySpec(limit, offset, assetId)); + catalogResult.getContractOffers().addAll(catalog.getContractOffers()); + reachedLastPage = catalog.getContractOffers().size() < limit; + } + + return catalogResult; + } + + public Catalog getCatalog(String providerUrl, QuerySpec querySpec) { + try { + return catalogService.getByProviderUrl(providerUrl, querySpec).get(); + } catch (InterruptedException | ExecutionException e) { + throw new ExternalRequestException("Could not retrieve contract offer.", e); + } + } + + private QuerySpec getQuerySpec(int limit, int offset, String assetId) { + List filters = + Objects.isNull(assetId) + ? Collections.emptyList() + : List.of(new Criterion("asset:prop:id", "=", assetId)); + return QuerySpec.Builder.newInstance().offset(offset).filter(filters).limit(limit).build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractAgreementRetriever.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractAgreementRetriever.java new file mode 100644 index 000000000..7d87948b0 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractAgreementRetriever.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation; + +import java.time.Instant; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; +import org.eclipse.edc.connector.spi.contractagreement.ContractAgreementService; +import org.eclipse.edc.service.spi.result.ServiceResult; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.query.Criterion; +import org.eclipse.edc.spi.query.QuerySpec; + +@RequiredArgsConstructor +public class ContractAgreementRetriever { + private final Monitor monitor; + private final ContractAgreementService agreementService; + + public ContractAgreement getExistingContractById(String contractAgreementId) { + return agreementService.findById(contractAgreementId); + } + + public ContractAgreement getExistingContractByAssetId(String assetId) { + Collection agreements = getContractAgreementsByAssetId(assetId); + + validateResults(agreements); + + long now = Instant.now().getEpochSecond(); + return agreements.stream() + .filter(agreement -> agreement.getContractStartDate() < now) + .filter(agreement -> agreement.getContractEndDate() > now) + .findFirst() + .orElse(null); + } + + private Collection getContractAgreementsByAssetId(String assetId) { + QuerySpec querySpec = + QuerySpec.Builder.newInstance() + .filter(List.of(new Criterion("policy.target", "=", assetId))) + .limit(500) + .build(); + ServiceResult> result = agreementService.query(querySpec); + return result.succeeded() + ? result.getContent().collect(Collectors.toList()) + : Collections.emptyList(); + } + + private void validateResults(Collection agreements) { + if (agreements.size() > 1) { + monitor.warning( + "More than one agreement found for a given assetId! First of the list will be used!"); + } + int numberOfProviders = + agreements.stream() + .collect(Collectors.groupingBy(ContractAgreement::getProviderAgentId)) + .size(); + if (numberOfProviders > 1) { + monitor.warning("Contract agreement: given assetId found for more than one provider!"); + } + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractNegotiationHandler.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractNegotiationHandler.java new file mode 100644 index 000000000..b0d7bf237 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractNegotiationHandler.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation; + +import jakarta.ws.rs.core.Response; +import java.time.Instant; +import java.util.*; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.catalog.spi.Catalog; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractOfferRequest; +import org.eclipse.edc.connector.contract.spi.types.offer.ContractOffer; +import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationService; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.exception.ResourceNotFoundException; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Listener; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; + +@RequiredArgsConstructor +public class ContractNegotiationHandler implements Listener { + private final Monitor monitor; + private final MessageBus messageBus; + private final ContractNegotiationService contractNegotiationService; + private final CatalogCachedRetriever catalogRetriever; + private final ContractAgreementRetriever agreementRetriever; + + @Override + public void process(DataReferenceRetrievalDto dto) { + monitor.info( + String.format( + "[%s] RequestHandler: input request: [%s]", dto.getTraceId(), dto.getPayload())); + ProcessData processData = dto.getPayload(); + + ContractAgreement contractAgreement = getContractAgreementById(dto); + if (Objects.nonNull(dto.getPayload().getContractAgreementId()) && contractAgreement == null) { + sendNotFoundErrorResult(dto, getAgreementNotFoundMessage(dto)); + return; + } + + if (Objects.isNull(contractAgreement)) { + contractAgreement = + agreementRetriever.getExistingContractByAssetId(dto.getPayload().getAssetId()); + } + + if (Objects.nonNull(contractAgreement) && isContractValid(contractAgreement)) { + monitor.info( + String.format("[%s] existing ContractAgreement taken from EDC.", dto.getTraceId())); + dto.getPayload().setContractAgreementId(contractAgreement.getId()); + dto.getPayload().setContractConfirmed(true); + messageBus.send(Channel.CONTRACT_CONFIRMATION, dto); + return; + } + + ContractOffer contractOffer = + findContractOffer( + processData.getAssetId(), + processData.getProvider(), + processData.getCatalogExpiryTime()); + + if (Objects.isNull(contractOffer)) { + sendNotFoundErrorResult(dto, getContractNotFoundMessage(dto)); + return; + } + + String contractNegotiationId = + initializeContractNegotiation( + contractOffer, dto.getPayload().getProvider(), dto.getTraceId()); + dto.getPayload().setContractNegotiationId(contractNegotiationId); + + messageBus.send(Channel.CONTRACT_CONFIRMATION, dto); + } + + private ContractAgreement getContractAgreementById(DataReferenceRetrievalDto dto) { + return Optional.ofNullable(dto.getPayload().getContractAgreementId()) + .map(agreementRetriever::getExistingContractById) + .orElse(null); + } + + private boolean isContractValid(ContractAgreement contractAgreement) { + long now = Instant.now().getEpochSecond(); + return Objects.nonNull(contractAgreement) + && contractAgreement.getContractStartDate() < now + && contractAgreement.getContractEndDate() > now; + } + + private ContractOffer findContractOffer( + String assetId, String providerUrl, int catalogExpiryTime) { + Catalog catalog = catalogRetriever.getEntireCatalog(providerUrl, assetId, catalogExpiryTime); + return Optional.ofNullable(catalog.getContractOffers()).orElse(Collections.emptyList()).stream() + .filter(it -> it.getAsset().getId().equals(assetId)) + .findFirst() + .orElse(null); + } + + private String initializeContractNegotiation( + ContractOffer contractOffer, String providerUrl, String traceId) { + monitor.info(String.format("[%s] RequestHandler: initiateNegotiation - start", traceId)); + ContractOfferRequest contractOfferRequest = + ContractOfferRequest.Builder.newInstance() + .connectorAddress(providerUrl) + .contractOffer(contractOffer) + .type(ContractOfferRequest.Type.INITIAL) + .connectorId("provider") + .protocol("ids-multipart") + .correlationId(traceId) + .build(); + + ContractNegotiation contractNegotiation = + contractNegotiationService.initiateNegotiation(contractOfferRequest); + monitor.info(String.format("[%s] RequestHandler: initiateNegotiation - end", traceId)); + return Optional.ofNullable(contractNegotiation.getId()) + .orElseThrow(() -> new ResourceNotFoundException("Could not find Contract NegotiationId")); + } + + private void sendNotFoundErrorResult(DataReferenceRetrievalDto dto, String message) { + dto.getPayload().setErrorMessage(message); + dto.getPayload().setErrorStatus(Response.Status.NOT_FOUND); + messageBus.send(Channel.RESULT, dto); + } + + private String getAgreementNotFoundMessage(DataReferenceRetrievalDto dto) { + return "Not found the contract agreement with ID: " + dto.getPayload().getContractAgreementId(); + } + + private String getContractNotFoundMessage(DataReferenceRetrievalDto dto) { + return "Could not find Contract Offer for given Asset Id"; + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractInfo.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractInfo.java new file mode 100644 index 000000000..e4437cbbb --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContractInfo { + @Getter private String contractAgreementId; + private ContractState contractState; + + public ContractInfo(String contractAgreementId, ContractState contractState) { + this.contractAgreementId = contractAgreementId; + this.contractState = contractState; + } + + public ContractInfo(ContractState contractState) { + this.contractState = contractState; + } + + public boolean isConfirmed() { + return ContractState.CONFIRMED.equals(contractState); + } + + public boolean isDeclined() { + return ContractState.DECLINED.equals(contractState); + } + + public boolean isError() { + return ContractState.ERROR.equals(contractState); + } + + protected enum ContractState { + CONFIRMED, + DECLINED, + ERROR; + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNegotiationListenerImpl.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNegotiationListenerImpl.java new file mode 100644 index 000000000..a441eddf6 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNegotiationListenerImpl.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import static java.util.Objects.isNull; + +import jakarta.ws.rs.core.Response; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.contract.spi.negotiation.observe.ContractNegotiationListener; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; + +@RequiredArgsConstructor +public class ContractNegotiationListenerImpl implements ContractNegotiationListener { + public static final String CONTRACT_DECLINED_MESSAGE = "Contract for asset is declined."; + public static final String CONTRACT_ERROR_MESSAGE = "Contract Error for asset."; + private final Monitor monitor; + private final MessageBus messageBus; + private final ContractNotificationSyncService syncService; + private final DataTransferInitializer dataTransfer; + + @Override + public void confirmed(ContractNegotiation negotiation) { + monitor.info("ContractConfirmationHandler: received ContractConfirmation event"); + String negotiationId = negotiation.getId(); + String agreementId = negotiation.getContractAgreement().getId(); + DataReferenceRetrievalDto dto = + syncService.exchangeConfirmedContract(negotiationId, agreementId); + if (isNull(dto)) { + return; + } + dto.getPayload().setContractAgreementId(agreementId); + initiateDataTransfer(dto); + syncService.removeDto(negotiationId); + } + + @Override + public void declined(ContractNegotiation negotiation) { + monitor.info("ContractConfirmationHandler: received ContractDeclined event"); + String contractNegotiationId = negotiation.getId(); + DataReferenceRetrievalDto dto = syncService.exchangeDeclinedContract(contractNegotiationId); + if (isNull(dto)) { + return; + } + sendErrorResult(dto, CONTRACT_DECLINED_MESSAGE); + syncService.removeDto(contractNegotiationId); + } + + @Override + public void failed(ContractNegotiation negotiation) { + monitor.info("ContractConfirmationHandler: received ContractError event"); + String contractNegotiationId = negotiation.getId(); + DataReferenceRetrievalDto dto = syncService.exchangeErrorContract(contractNegotiationId); + if (isNull(dto)) { + return; + } + sendErrorResult(dto, CONTRACT_ERROR_MESSAGE); + syncService.removeDto(contractNegotiationId); + } + + public void initiateDataTransfer(DataReferenceRetrievalDto dto) { + String transferProcessId = dataTransfer.initiate(dto); + dto.getPayload().setTransferProcessId(transferProcessId); + dto.getPayload().setContractConfirmed(true); + messageBus.send(Channel.DATA_REFERENCE, dto); + } + + private void sendErrorResult(DataReferenceRetrievalDto dto, String errorMessage) { + dto.getPayload().setErrorMessage(errorMessage); + dto.getPayload().setErrorStatus(Response.Status.BAD_GATEWAY); + messageBus.send(Channel.RESULT, dto); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationHandler.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationHandler.java new file mode 100644 index 000000000..5bd254194 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationHandler.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import static jakarta.ws.rs.core.Response.Status; +import static java.util.Objects.isNull; + +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiationStates; +import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationService; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Listener; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; + +@RequiredArgsConstructor +public class ContractNotificationHandler implements Listener { + public static final String CONTRACT_DECLINED_MESSAGE = "Contract for asset is declined."; + public static final String CONTRACT_ERROR_MESSAGE = "Contract Error for asset."; + private final Monitor monitor; + private final MessageBus messageBus; + private final ContractNotificationSyncService syncService; + private final ContractNegotiationService contractNegotiationService; + private final DataTransferInitializer dataTransfer; + + @Override + public void process(DataReferenceRetrievalDto dto) { + monitor.info( + String.format("[%s] ContractConfirmationHandler: received message.", dto.getTraceId())); + String contractNegotiationId = dto.getPayload().getContractNegotiationId(); + + if (dto.getPayload().isContractConfirmed()) { + initiateDataTransfer(dto); + return; + } + + ContractNegotiation contractNegotiation = + contractNegotiationService.findbyId(contractNegotiationId); + if (isContractConfirmed(contractNegotiation)) { + dto.getPayload().setContractAgreementId(contractNegotiation.getContractAgreement().getId()); + initiateDataTransfer(dto); + return; + } + + ContractInfo contractInfo = syncService.exchangeDto(dto); + if (isNull(contractInfo)) { + return; + } + + if (contractInfo.isConfirmed()) { + dto.getPayload().setContractAgreementId(contractInfo.getContractAgreementId()); + initiateDataTransfer(dto); + } else { + sendErrorResult( + dto, contractInfo.isDeclined() ? CONTRACT_DECLINED_MESSAGE : CONTRACT_ERROR_MESSAGE); + } + syncService.removeContractInfo(contractNegotiationId); + } + + public void initiateDataTransfer(DataReferenceRetrievalDto dto) { + String transferProcessId = dataTransfer.initiate(dto); + dto.getPayload().setTransferProcessId(transferProcessId); + dto.getPayload().setContractConfirmed(true); + messageBus.send(Channel.DATA_REFERENCE, dto); + } + + private void sendErrorResult(DataReferenceRetrievalDto dto, String errorMessage) { + dto.getPayload().setErrorMessage(errorMessage); + dto.getPayload().setErrorStatus(Status.BAD_GATEWAY); + messageBus.send(Channel.RESULT, dto); + } + + private boolean isContractConfirmed(ContractNegotiation contractNegotiation) { + return Objects.nonNull(contractNegotiation) + && contractNegotiation.getState() == ContractNegotiationStates.CONFIRMED.code(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationSyncService.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationSyncService.java new file mode 100644 index 000000000..e687822c2 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationSyncService.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; + +public interface ContractNotificationSyncService { + DataReferenceRetrievalDto exchangeConfirmedContract( + String contractNegotiationId, String contractAgreementId); + + DataReferenceRetrievalDto exchangeDeclinedContract(String contractNegotiationId); + + DataReferenceRetrievalDto exchangeErrorContract(String contractNegotiationId); + + ContractInfo exchangeDto(DataReferenceRetrievalDto dto); + + void removeContractInfo(String key); + + void removeDto(String key); +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractSyncService.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractSyncService.java new file mode 100644 index 000000000..44f3cbce6 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractSyncService.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import static java.util.Objects.isNull; + +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreService; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectType; +import org.eclipse.tractusx.edc.cp.adapter.util.LockMap; + +public class ContractSyncService implements ContractNotificationSyncService { + private final ObjectStoreService storeService; + private final LockMap locks; + + public ContractSyncService(ObjectStoreService storeService, LockMap locks) { + this.storeService = storeService; + this.locks = locks; + } + + @Override + public DataReferenceRetrievalDto exchangeConfirmedContract( + String negotiationId, String agreementId) { + locks.lock(negotiationId); + + DataReferenceRetrievalDto dto = + storeService.get(negotiationId, ObjectType.DTO, DataReferenceRetrievalDto.class); + + if (isNull(dto)) { + ContractInfo contractInfo = + new ContractInfo(agreementId, ContractInfo.ContractState.CONFIRMED); + storeService.put(negotiationId, ObjectType.CONTRACT_INFO, contractInfo); + } + locks.unlock(negotiationId); + return dto; + } + + @Override + public DataReferenceRetrievalDto exchangeDeclinedContract(String negotiationId) { + locks.lock(negotiationId); + + DataReferenceRetrievalDto dto = + storeService.get(negotiationId, ObjectType.DTO, DataReferenceRetrievalDto.class); + + if (isNull(dto)) { + ContractInfo contractInfo = new ContractInfo(ContractInfo.ContractState.DECLINED); + storeService.put(negotiationId, ObjectType.CONTRACT_INFO, contractInfo); + } + locks.unlock(negotiationId); + return dto; + } + + @Override + public DataReferenceRetrievalDto exchangeErrorContract(String negotiationId) { + locks.lock(negotiationId); + + DataReferenceRetrievalDto dto = + storeService.get(negotiationId, ObjectType.DTO, DataReferenceRetrievalDto.class); + + if (isNull(dto)) { + ContractInfo contractInfo = new ContractInfo(ContractInfo.ContractState.ERROR); + storeService.put(negotiationId, ObjectType.CONTRACT_INFO, contractInfo); + } + + locks.unlock(negotiationId); + return dto; + } + + @Override + public ContractInfo exchangeDto(DataReferenceRetrievalDto dto) { + String negotiationId = dto.getPayload().getContractNegotiationId(); + locks.lock(negotiationId); + + ContractInfo contractInfo = + storeService.get(negotiationId, ObjectType.CONTRACT_INFO, ContractInfo.class); + + if (isNull(contractInfo)) { + storeService.put(negotiationId, ObjectType.DTO, dto); + } + + locks.unlock(negotiationId); + return contractInfo; + } + + @Override + public void removeContractInfo(String negotiationId) { + storeService.remove(negotiationId, ObjectType.CONTRACT_INFO); + locks.removeLock(negotiationId); + } + + @Override + public void removeDto(String negotiationId) { + storeService.remove(negotiationId, ObjectType.DTO); + locks.removeLock(negotiationId); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/DataTransferInitializer.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/DataTransferInitializer.java new file mode 100644 index 000000000..34812567f --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/DataTransferInitializer.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.spi.transferprocess.TransferProcessService; +import org.eclipse.edc.connector.transfer.spi.types.DataRequest; +import org.eclipse.edc.connector.transfer.spi.types.TransferType; +import org.eclipse.edc.service.spi.result.ServiceResult; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.exception.ExternalRequestException; + +@RequiredArgsConstructor +public class DataTransferInitializer { + private final Monitor monitor; + private final TransferProcessService transferProcessService; + + public String initiate(DataReferenceRetrievalDto dto) { + monitor.info( + String.format( + "[%s] ContractConfirmationHandler: transfer init - start.", dto.getTraceId())); + DataAddress dataDestination = DataAddress.Builder.newInstance().type("HttpProxy").build(); + + TransferType transferType = + TransferType.Builder.transferType() + .contentType("application/octet-stream") + .isFinite(true) + .build(); + + DataRequest dataRequest = + DataRequest.Builder.newInstance() + .id(dto.getTraceId()) + .assetId(dto.getPayload().getAssetId()) + .contractId(dto.getPayload().getContractAgreementId()) + .connectorId("provider") + .connectorAddress(dto.getPayload().getProvider()) + .protocol("ids-multipart") + .dataDestination(dataDestination) + .managedResources(false) + .transferType(transferType) + .build(); + + ServiceResult result = transferProcessService.initiateTransfer(dataRequest); + monitor.info( + String.format("[%s] ContractConfirmationHandler: transfer init - end", dto.getTraceId())); + if (result.failed()) { + throwDataRefRequestException(dto); + } + + return result.getContent(); + } + + private void throwDataRefRequestException(DataReferenceRetrievalDto dto) { + throw new ExternalRequestException( + String.format( + "Data reference initial request failed! AssetId: %s", dto.getPayload().getAssetId())); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefNotificationSyncService.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefNotificationSyncService.java new file mode 100644 index 000000000..2bb24af30 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefNotificationSyncService.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; + +public interface DataRefNotificationSyncService { + EndpointDataReference exchangeDto(DataReferenceRetrievalDto dto, String contractAgreementId); + + DataReferenceRetrievalDto exchangeDataReference( + EndpointDataReference dataReference, String contractAgreementId); + + void removeDataReference(String contractAgreementId); + + void removeDto(String key); +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefSyncService.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefSyncService.java new file mode 100644 index 000000000..812ba70da --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefSyncService.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import static java.util.Objects.isNull; + +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreService; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectType; +import org.eclipse.tractusx.edc.cp.adapter.util.LockMap; + +@RequiredArgsConstructor +public class DataRefSyncService implements DataRefNotificationSyncService { + private final ObjectStoreService storeService; + private final LockMap locks; + + public EndpointDataReference exchangeDto(DataReferenceRetrievalDto dto, String agreementId) { + locks.lock(agreementId); + + EndpointDataReference dataReference = + storeService.get(agreementId, ObjectType.DATA_REFERENCE, EndpointDataReference.class); + + if (isNull(dataReference)) { + storeService.put(agreementId, ObjectType.DTO, dto); + } + locks.unlock(agreementId); + return dataReference; + } + + @Override + public DataReferenceRetrievalDto exchangeDataReference( + EndpointDataReference dataReference, String agreementId) { + locks.lock(agreementId); + + DataReferenceRetrievalDto dto = + storeService.get(agreementId, ObjectType.DTO, DataReferenceRetrievalDto.class); + + if (isNull(dto)) { + storeService.put(agreementId, ObjectType.DATA_REFERENCE, dataReference); + } + locks.unlock(agreementId); + return dto; + } + + @Override + public void removeDataReference(String agreementId) { + storeService.remove(agreementId, ObjectType.DATA_REFERENCE); + locks.removeLock(agreementId); + } + + @Override + public void removeDto(String agreementId) { + storeService.remove(agreementId, ObjectType.DTO); + locks.removeLock(agreementId); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceErrorHandler.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceErrorHandler.java new file mode 100644 index 000000000..39885837c --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceErrorHandler.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import jakarta.ws.rs.core.Response; +import java.util.List; +import lombok.AllArgsConstructor; +import org.eclipse.edc.connector.spi.transferprocess.TransferProcessService; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.util.string.StringUtils; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreService; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectType; + +@AllArgsConstructor +public class DataReferenceErrorHandler { + private static final String ERROR_MESSAGE = "Data reference process stage failed with status: "; + private final Monitor monitor; + private final MessageBus messageBus; + private final ObjectStoreService objectStore; + private final TransferProcessService transferProcessService; + + private final List errorStates = List.of("CANCELLED", "ERROR"); + + public void validateActiveProcesses() { + monitor.debug("Data reference error handling - START"); + objectStore.get(ObjectType.DTO, DataReferenceRetrievalDto.class).stream() + .filter(dto -> !StringUtils.isNullOrEmpty(dto.getPayload().getTransferProcessId())) + .forEach(this::validateProcess); + } + + private void validateProcess(DataReferenceRetrievalDto dto) { + String state = transferProcessService.getState(dto.getPayload().getTransferProcessId()); + if (errorStates.contains(state)) { + monitor.warning(String.format("[%s] ", dto.getTraceId()) + ERROR_MESSAGE + state); + String contractAgreementId = dto.getPayload().getContractAgreementId(); + objectStore.remove(contractAgreementId, ObjectType.DTO); + + dto.getPayload().setErrorStatus(Response.Status.BAD_GATEWAY); + dto.getPayload().setErrorMessage(ERROR_MESSAGE + state); + messageBus.send(Channel.RESULT, dto); + } + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceHandler.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceHandler.java new file mode 100644 index 000000000..2e5f901d3 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import static java.util.Objects.isNull; + +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Listener; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; + +@RequiredArgsConstructor +public class DataReferenceHandler implements Listener { + private final Monitor monitor; + private final MessageBus messageBus; + private final DataRefNotificationSyncService syncService; + + @Override + public void process(DataReferenceRetrievalDto dto) { + String contractAgreementId = dto.getPayload().getContractAgreementId(); + monitor.info(String.format("[%s] DataReference message received.", dto.getTraceId())); + + EndpointDataReference dataReference = syncService.exchangeDto(dto, contractAgreementId); + if (isNull(dataReference)) { + return; + } + + dto.getPayload().setEndpointDataReference(dataReference); + messageBus.send(Channel.RESULT, dto); + syncService.removeDataReference(contractAgreementId); + monitor.info(String.format("[%s] DataReference message processed.", dto.getTraceId())); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/EndpointDataReferenceReceiverImpl.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/EndpointDataReferenceReceiverImpl.java new file mode 100644 index 000000000..0f1173cf4 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/EndpointDataReferenceReceiverImpl.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import static java.util.Objects.isNull; + +import java.util.concurrent.CompletableFuture; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.transfer.spi.edr.EndpointDataReferenceReceiver; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.jetbrains.annotations.NotNull; + +@RequiredArgsConstructor +public class EndpointDataReferenceReceiverImpl implements EndpointDataReferenceReceiver { + private final Monitor monitor; + private final MessageBus messageBus; + private final DataRefNotificationSyncService syncService; + + @Override + public CompletableFuture> send(@NotNull EndpointDataReference dataReference) { + String contractAgreementId = dataReference.getProperties().get("cid"); + monitor.info(String.format("DataReference received, contractAgr.: %s", contractAgreementId)); + + DataReferenceRetrievalDto dto = + syncService.exchangeDataReference(dataReference, contractAgreementId); + if (isNull(dto)) { + return CompletableFuture.completedFuture(Result.success()); + } + dto.getPayload().setEndpointDataReference(dataReference); + messageBus.send(Channel.RESULT, dto); + syncService.removeDto(contractAgreementId); + + monitor.info(String.format("[%s] DataReference processed.", dto.getTraceId())); + return CompletableFuture.completedFuture(Result.success()); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/ErrorResultService.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/ErrorResultService.java new file mode 100644 index 000000000..5428317e3 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/ErrorResultService.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.service; + +import jakarta.ws.rs.core.Response; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.exception.ExternalRequestException; +import org.eclipse.tractusx.edc.cp.adapter.exception.ResourceNotFoundException; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Listener; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; + +@RequiredArgsConstructor +public class ErrorResultService implements Listener { + private static final Map, Response.Status> statusOfException = new HashMap<>(); + + static { + statusOfException.put(ExternalRequestException.class, Response.Status.BAD_GATEWAY); + statusOfException.put(ResourceNotFoundException.class, Response.Status.NOT_FOUND); + } + + private final Monitor monitor; + private final MessageBus messageBus; + + @Override + public void process(DataReferenceRetrievalDto dto) { + dto.getPayload().setErrorMessage(getErrorMessage(dto)); + dto.getPayload() + .setErrorStatus( + statusOfException.getOrDefault( + dto.getFinalException().getClass(), Response.Status.INTERNAL_SERVER_ERROR)); + log(dto); + messageBus.send(Channel.RESULT, dto); + } + + private String getErrorMessage(DataReferenceRetrievalDto dto) { + return Objects.nonNull(dto.getFinalException()) + ? dto.getFinalException().getMessage() + : "Unrecognized Exception."; + } + + private void log(DataReferenceRetrievalDto dto) { + monitor.info( + String.format( + "[%s] Sending ERROR message to RESULT channel: %s / %s ", + dto.getTraceId(), + dto.getPayload().getErrorMessage(), + dto.getPayload().getErrorStatus())); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/ResultService.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/ResultService.java new file mode 100644 index 000000000..494237abe --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/ResultService.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.service; + +import static java.util.Objects.isNull; +import static java.util.concurrent.TimeUnit.SECONDS; + +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Listener; + +@RequiredArgsConstructor +public class ResultService implements Listener { + private final int CAPACITY = 1; + private final int DEFAULT_TIMEOUT; + private final Map> results = new ConcurrentHashMap<>(); + private final Monitor monitor; + + public ProcessData pull(String id) throws InterruptedException { + return pull(id, DEFAULT_TIMEOUT, SECONDS); + } + + public ProcessData pull(String id, long timeout, TimeUnit unit) throws InterruptedException { + if (!results.containsKey(id)) { + initiate(id); + } + ProcessData result = results.get(id).poll(timeout, unit); + results.remove(id); + return result; + } + + @Override + public void process(DataReferenceRetrievalDto dto) { + if (isNull(dto) || isNull(dto.getPayload())) { + throw new IllegalArgumentException(); + } + logReceivedResult(dto); + add(dto.getTraceId(), dto.getPayload()); + } + + private void add(String id, ProcessData processData) { + if (!results.containsKey(id)) { + initiate(id); + } + try { + results.get(id).add(processData); + } catch (IllegalStateException e) { + logIgnoredResult(id, processData); + } + } + + private void initiate(String id) { + results.put(id, new ArrayBlockingQueue<>(CAPACITY)); + } + + private void logReceivedResult(DataReferenceRetrievalDto dto) { + monitor.info( + String.format( + "[%s] Result received: %s", dto.getTraceId(), getResultInfo(dto.getPayload()))); + } + + private void logIgnoredResult(String id, ProcessData processData) { + monitor.warning( + String.format( + "[%s] Other Result was already returned! Result '%s' will be ignored!", + id, getResultInfo(processData))); + } + + private String getResultInfo(ProcessData processData) { + return Objects.nonNull(processData.getErrorMessage()) + ? processData.getErrorMessage() + : processData.getEndpointDataReference().getId(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreService.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreService.java new file mode 100644 index 000000000..6c3818379 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreService.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.service.objectstore; + +import java.util.List; + +public interface ObjectStoreService { + void put(String key, ObjectType objectType, Object object); + + T get(String key, ObjectType objectType, Class type); + + void remove(String key, ObjectType objectType); + + List get(ObjectType objectType, Class type); +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreServiceInMemory.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreServiceInMemory.java new file mode 100644 index 000000000..3e1a8190a --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreServiceInMemory.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.service.objectstore; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class ObjectStoreServiceInMemory implements ObjectStoreService { + private final ObjectMapper mapper; + private final Map map = new HashMap<>(); + + @Override + public void put(String key, ObjectType objectType, Object object) { + try { + map.put(getKey(key, objectType), mapper.writeValueAsString(object)); + } catch (JsonProcessingException e) { + e.printStackTrace(); + throw new IllegalArgumentException(); + } + } + + @Override + public T get(String key, ObjectType objectType, Class type) { + String json = map.get(getKey(key, objectType)); + return Objects.isNull(json) ? null : map(type, json); + } + + @Override + public List get(ObjectType objectType, Class type) { + return map.entrySet().stream() + .filter(entry -> entry.getKey().startsWith(objectType.name())) + .map(Map.Entry::getValue) + .map(s -> map(type, s)) + .collect(Collectors.toList()); + } + + @Override + public void remove(String key, ObjectType objectType) { + map.remove(getKey(key, objectType)); + } + + private String getKey(String key, ObjectType objectType) { + return objectType.name() + key; + } + + private T map(Class type, String json) { + T object = null; + try { + object = mapper.readValue(json, type); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return object; + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreServiceSql.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreServiceSql.java new file mode 100644 index 000000000..b16daea50 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectStoreServiceSql.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.service.objectstore; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import org.eclipse.edc.util.collection.CollectionUtil; +import org.eclipse.tractusx.edc.cp.adapter.store.SqlObjectStore; +import org.eclipse.tractusx.edc.cp.adapter.store.model.ObjectEntity; + +@AllArgsConstructor +public class ObjectStoreServiceSql implements ObjectStoreService { + private final ObjectMapper mapper; + private final SqlObjectStore objectStore; + + @Override + public void put(String key, ObjectType objectType, Object object) { + ObjectEntity entity = + ObjectEntity.builder() + .id(key) + .type(objectType.name()) + .object(objectToJson(object, objectType.name())) + .build(); + objectStore.saveMessage(entity); + } + + @Override + public T get(String key, ObjectType objectType, Class type) { + ObjectEntity entity = objectStore.find(key, objectType.name()); + if (Objects.isNull(entity)) { + return null; + } + return jsonToObject(entity, type); + } + + @Override + public List get(ObjectType objectType, Class type) { + List entities = objectStore.find(objectType.name()); + if (CollectionUtil.isEmpty(entities)) { + return List.of(); + } + return entities.stream().map(entity -> jsonToObject(entity, type)).collect(Collectors.toList()); + } + + @Override + public void remove(String key, ObjectType objectType) { + objectStore.deleteMessage(key, objectType.name()); + } + + private String objectToJson(Object object, String type) { + if (Objects.isNull(object)) { + return null; + } + try { + return mapper.writeValueAsString(object); + } catch (JsonProcessingException e) { + e.printStackTrace(); + throw new IllegalArgumentException(String.format("Can not parse object of type %s", type)); + } + } + + private T jsonToObject(ObjectEntity entity, Class type) { + try { + return mapper.readValue(entity.getObject(), type); + } catch (JsonProcessingException e) { + e.printStackTrace(); + throw new IllegalArgumentException(String.format("Can not parse object of type %s", type)); + } + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectType.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectType.java new file mode 100644 index 000000000..5cbee2d0f --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/service/objectstore/ObjectType.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.service.objectstore; + +public enum ObjectType { + DTO, + CONTRACT_INFO, + DATA_REFERENCE, + RESULT +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/SqlObjectStore.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/SqlObjectStore.java new file mode 100644 index 000000000..4a5ec94a9 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/SqlObjectStore.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store; + +import static org.eclipse.edc.sql.SqlQueryExecutor.executeQuery; +import static org.eclipse.edc.sql.SqlQueryExecutor.executeQuerySingle; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.Instant; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.eclipse.edc.spi.persistence.EdcPersistenceException; +import org.eclipse.edc.sql.store.AbstractSqlStore; +import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; +import org.eclipse.edc.transaction.spi.TransactionContext; +import org.eclipse.tractusx.edc.cp.adapter.store.model.ObjectEntity; +import org.eclipse.tractusx.edc.cp.adapter.store.schema.ObjectStoreStatements; + +public class SqlObjectStore extends AbstractSqlStore { + private final ObjectStoreStatements statements; + + public SqlObjectStore( + DataSourceRegistry dataSourceRegistry, + String dataSourceName, + TransactionContext transactionContext, + ObjectMapper objectMapper, + ObjectStoreStatements statements) { + super(dataSourceRegistry, dataSourceName, transactionContext, objectMapper); + this.statements = statements; + } + + public void saveMessage(ObjectEntity objectEntity) { + long now = Instant.now().toEpochMilli(); + transactionContext.execute( + () -> { + try (var conn = getConnection()) { + var template = statements.getSaveObjectTemplate(); + executeQuery( + conn, + template, + objectEntity.getId(), + now, + objectEntity.getType(), + objectEntity.getObject()); + } catch (SQLException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + }); + } + + public ObjectEntity find(String id, String type) { + return transactionContext.execute( + () -> { + try (var connection = getConnection()) { + var sql = statements.getFindByIdAndTypeTemplate(); + return executeQuerySingle(connection, false, this::mapObjectEntity, sql, id, type); + } catch (SQLException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + }); + } + + public List find(String type) { + return transactionContext.execute( + () -> { + try (var connection = getConnection()) { + var sql = statements.getFindByTypeTemplate(); + Stream stream = + executeQuery(connection, false, this::mapObjectEntity, sql, type); + List result = stream.collect(Collectors.toList()); + stream.close(); + return result; + } catch (SQLException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + }); + } + + public void deleteMessage(String id, String type) { + transactionContext.execute( + () -> { + try (var connection = getConnection()) { + var stmt = statements.getDeleteTemplate(); + executeQuery(connection, stmt, id, type); + } catch (SQLException | IllegalStateException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + }); + } + + private ObjectEntity mapObjectEntity(ResultSet resultSet) throws SQLException { + return ObjectEntity.builder() + .id(resultSet.getString(statements.getIdColumn())) + .createdAt(resultSet.getLong(statements.getCreatedAtColumn())) + .type(resultSet.getString(statements.getTypeColumn())) + .object(resultSet.getString(statements.getObjectColumn())) + .build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/SqlQueueStore.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/SqlQueueStore.java new file mode 100644 index 000000000..0d808fae1 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/SqlQueueStore.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store; + +import static org.eclipse.edc.sql.SqlQueryExecutor.executeQuery; +import static org.eclipse.edc.sql.SqlQueryExecutor.executeQuerySingle; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.Clock; +import java.time.Instant; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.eclipse.edc.spi.persistence.EdcPersistenceException; +import org.eclipse.edc.sql.lease.SqlLeaseContextBuilder; +import org.eclipse.edc.sql.store.AbstractSqlStore; +import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; +import org.eclipse.edc.transaction.spi.TransactionContext; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.store.model.QueueMessage; +import org.eclipse.tractusx.edc.cp.adapter.store.schema.QueueStatements; + +public class SqlQueueStore extends AbstractSqlStore { + private final QueueStatements statements; + private final SqlLeaseContextBuilder leaseContext; + + public SqlQueueStore( + DataSourceRegistry dataSourceRegistry, + String dataSourceName, + TransactionContext transactionContext, + ObjectMapper objectMapper, + QueueStatements statements, + String connectorId, + Clock clock) { + super(dataSourceRegistry, dataSourceName, transactionContext, objectMapper); + this.statements = statements; + leaseContext = SqlLeaseContextBuilder.with(transactionContext, connectorId, statements, clock); + } + + public void saveMessage(QueueMessage queueMessage) { + long now = Instant.now().toEpochMilli(); + transactionContext.execute( + () -> { + try (var conn = getConnection()) { + var template = statements.getSaveMessageTemplate(); + executeQuery( + conn, + template, + now, + UUID.randomUUID().toString(), + queueMessage.getChannel(), + toJson(queueMessage.getMessage()), + queueMessage.getInvokeAfter()); + } catch (SQLException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + }); + } + + public QueueMessage findById(String id) { + return transactionContext.execute( + () -> { + try (var connection = getConnection()) { + var sql = statements.getFindByIdTemplate(); + return executeQuerySingle(connection, false, this::mapQueueMessage, sql, id); + } catch (SQLException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + }); + } + + public void deleteMessage(String id) { + transactionContext.execute( + () -> { + var existing = findById(id); + + if (existing != null) { + try (var connection = getConnection()) { + breakLease(connection, id); + var stmt = statements.getDeleteTemplate(); + executeQuery(connection, stmt, id); + } catch (SQLException | IllegalStateException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + } + }); + } + + public void updateMessage(QueueMessage queueMessage) { + transactionContext.execute( + () -> { + var existing = findById(queueMessage.getId()); + + if (existing != null) { + try (var connection = getConnection()) { + var stmt = statements.getUpdateTemplate(); + breakLease(connection, queueMessage.getId()); + executeQuery( + connection, + stmt, + queueMessage.getChannel(), + toJson(queueMessage.getMessage()), + queueMessage.getInvokeAfter(), + queueMessage.getId()); + } catch (SQLException | IllegalStateException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + } + }); + } + + public List findMessagesToSend(int max) { + long now = Instant.now().toEpochMilli(); + return transactionContext.execute( + () -> { + try (var connection = getConnection()) { + var sql = statements.getMessagesToSendTemplate(); + Stream stream = + executeQuery(connection, false, this::mapQueueMessage, sql, now, max); + List result = + stream + .map(queueMessage -> getLeasedQueueMessage(connection, queueMessage)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + stream.close(); + return result; + } catch (SQLException e) { + e.printStackTrace(); + throw new EdcPersistenceException(e); + } + }); + } + + private QueueMessage getLeasedQueueMessage(Connection connection, QueueMessage queueMessage) { + try { + acquireLease(connection, queueMessage.getId()); + return queueMessage; + } catch (IllegalStateException e) { + return null; + } + } + + private void acquireLease(Connection connection, String id) { + leaseContext.withConnection(connection).acquireLease(id); + } + + private void breakLease(Connection connection, String id) { + leaseContext.withConnection(connection).breakLease(id); + } + + private QueueMessage mapQueueMessage(ResultSet resultSet) throws SQLException { + return QueueMessage.builder() + .id(resultSet.getString(statements.getIdColumn())) + .message( + fromJson( + resultSet.getString(statements.getMessageColumn()), + DataReferenceRetrievalDto.class)) + .invokeAfter(resultSet.getLong(statements.getInvokeAfterColumn())) + .createdAt(resultSet.getLong(statements.getCreatedAtColumn())) + .channel(resultSet.getString(statements.getChannelColumn())) + .build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/model/ObjectEntity.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/model/ObjectEntity.java new file mode 100644 index 000000000..ffefe3927 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/model/ObjectEntity.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class ObjectEntity { + private String id; + private long createdAt; + private String type; + private String object; +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/model/QueueMessage.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/model/QueueMessage.java new file mode 100644 index 000000000..e3d1ec8bb --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/model/QueueMessage.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; + +@Getter +@Setter +@Builder +public class QueueMessage { + private String id; + private long createdAt; + private String channel; + private Message message; + private long invokeAfter; +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/BaseSqlDialectObjectStoreStatements.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/BaseSqlDialectObjectStoreStatements.java new file mode 100644 index 000000000..caa7fb39a --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/BaseSqlDialectObjectStoreStatements.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store.schema; + +import static java.lang.String.format; + +import org.eclipse.edc.sql.dialect.BaseSqlDialect; + +public class BaseSqlDialectObjectStoreStatements implements ObjectStoreStatements { + @Override + public String getSaveObjectTemplate() { + return format( + "INSERT INTO %s (%s, %s, %s, %s) VALUES(?, ?, ?, ?%s)", + getObjectStoreTable(), + getIdColumn(), + getCreatedAtColumn(), + getTypeColumn(), + getObjectColumn(), + getFormatJsonOperator()); + } + + @Override + public String getFindByIdAndTypeTemplate() { + return format( + "SELECT * FROM %s WHERE %s = ? AND %s = ?", + getObjectStoreTable(), getIdColumn(), getTypeColumn()); + } + + @Override + public String getFindByTypeTemplate() { + return format("SELECT * FROM %s WHERE %s = ?", getObjectStoreTable(), getTypeColumn()); + } + + @Override + public String getDeleteTemplate() { + return format( + "DELETE FROM %s WHERE %s = ? AND %s = ?;", + getObjectStoreTable(), getIdColumn(), getTypeColumn()); + } + + protected String getFormatJsonOperator() { + return BaseSqlDialect.getJsonCastOperator(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/BaseSqlDialectQueueStatements.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/BaseSqlDialectQueueStatements.java new file mode 100644 index 000000000..7bf19422c --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/BaseSqlDialectQueueStatements.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store.schema; + +import static java.lang.String.format; + +import org.eclipse.edc.sql.dialect.BaseSqlDialect; + +public class BaseSqlDialectQueueStatements implements QueueStatements { + + @Override + public String getSaveMessageTemplate() { + return format( + "INSERT INTO %s (%s, %s, %s, %s, %s) VALUES(?, ?, ?, ?%s, ?)", + getQueueTable(), + getCreatedAtColumn(), + getIdColumn(), + getChannelColumn(), + getMessageColumn(), + getInvokeAfterColumn(), + getFormatJsonOperator()); + } + + @Override + public String getAllMessagesTemplate() { + return format("SELECT * FROM %s ", getQueueTable()); + } + + @Override + public String getMessagesToSendTemplate() { + return format( + "SELECT * FROM %s WHERE %s <= ? AND %s IS NULL LIMIT ?", + getQueueTable(), getInvokeAfterColumn(), getLeaseIdColumn()); + } + ; + + @Override + public String getDeleteTemplate() { + return format("DELETE FROM %s WHERE %s = ?", getQueueTable(), getIdColumn()); + } + + @Override + public String getFindByIdTemplate() { + return format("SELECT * FROM %s WHERE %s = ?", getQueueTable(), getIdColumn()); + } + + @Override + public String getUpdateTemplate() { + return format( + "UPDATE %s SET %s=?, %s=?%s, %s=? WHERE %s=?", + getQueueTable(), + getChannelColumn(), + getMessageColumn(), + getFormatJsonOperator(), + getInvokeAfterColumn(), + getIdColumn()); + } + + @Override + public String getDeleteLeaseTemplate() { + return format("DELETE FROM %s WHERE %s = ?;", getLeaseTableName(), getLeaseIdColumn()); + } + + @Override + public String getInsertLeaseTemplate() { + return format( + "INSERT INTO %s (%s, %s, %s, %s)" + "VALUES (?,?,?,?);", + getLeaseTableName(), + getLeaseIdColumn(), + getLeasedByColumn(), + getLeasedAtColumn(), + getLeaseDurationColumn()); + } + + @Override + public String getUpdateLeaseTemplate() { + return format( + "UPDATE %s SET %s=? WHERE %s = ?;", getQueueTable(), getLeaseIdColumn(), getIdColumn()); + } + + @Override + public String getFindLeaseByEntityTemplate() { + return format( + "SELECT * FROM %s WHERE %s = (SELECT lease_id FROM %s WHERE %s=? )", + getLeaseTableName(), getLeaseIdColumn(), getQueueTable(), getIdColumn()); + } + + protected String getFormatJsonOperator() { + return BaseSqlDialect.getJsonCastOperator(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/ObjectStoreStatements.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/ObjectStoreStatements.java new file mode 100644 index 000000000..57f60988a --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/ObjectStoreStatements.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store.schema; + +public interface ObjectStoreStatements { + default String getObjectStoreTable() { + return "edc_cpadapter_object_store"; + } + + default String getIdColumn() { + return "id"; + } + + default String getCreatedAtColumn() { + return "created_at"; + } + + default String getTypeColumn() { + return "type"; + } + + default String getObjectColumn() { + return "object"; + } + + String getSaveObjectTemplate(); + + String getFindByIdAndTypeTemplate(); + + String getFindByTypeTemplate(); + + String getDeleteTemplate(); +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/QueueStatements.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/QueueStatements.java new file mode 100644 index 000000000..918734c2a --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/QueueStatements.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store.schema; + +import org.eclipse.edc.sql.lease.LeaseStatements; + +/** Defines all statements that are needed for the ContractDefinition store */ +public interface QueueStatements extends LeaseStatements { + default String getQueueTable() { + return "edc_cpadapter_queue"; + } + + default String getIdColumn() { + return "id"; + } + + default String getCreatedAtColumn() { + return "created_at"; + } + + default String getChannelColumn() { + return "channel"; + } + + default String getMessageColumn() { + return "message"; + } + + default String getInvokeAfterColumn() { + return "invoke_after"; + } + + String getAllMessagesTemplate(); + + String getMessagesToSendTemplate(); + + String getSaveMessageTemplate(); + + String getDeleteTemplate(); + + String getFindByIdTemplate(); + + String getUpdateTemplate(); +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/postgres/PostgresDialectObjectStoreStatements.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/postgres/PostgresDialectObjectStoreStatements.java new file mode 100644 index 000000000..85a078981 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/postgres/PostgresDialectObjectStoreStatements.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store.schema.postgres; + +import org.eclipse.edc.sql.dialect.PostgresDialect; +import org.eclipse.tractusx.edc.cp.adapter.store.schema.BaseSqlDialectObjectStoreStatements; + +public class PostgresDialectObjectStoreStatements extends BaseSqlDialectObjectStoreStatements { + /** + * Overridable operator to convert strings to JSON. For postgres, this is the "::json" operator + */ + @Override + protected String getFormatJsonOperator() { + return PostgresDialect.getJsonCastOperator(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/postgres/PostgresDialectQueueStatements.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/postgres/PostgresDialectQueueStatements.java new file mode 100644 index 000000000..cdafaf4f3 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/store/schema/postgres/PostgresDialectQueueStatements.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.store.schema.postgres; + +import org.eclipse.edc.sql.dialect.PostgresDialect; +import org.eclipse.tractusx.edc.cp.adapter.store.schema.BaseSqlDialectQueueStatements; + +public class PostgresDialectQueueStatements extends BaseSqlDialectQueueStatements { + + /** + * Overridable operator to convert strings to JSON. For postgres, this is the "::json" operator + */ + @Override + protected String getFormatJsonOperator() { + return PostgresDialect.getJsonCastOperator(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/util/ExpiringMap.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/util/ExpiringMap.java new file mode 100644 index 000000000..657ca8f92 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/util/ExpiringMap.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.util; + +import java.time.Instant; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class ExpiringMap { + private final Map map = new HashMap<>(); + private final Map entryTimeMap = new HashMap<>(); + private long expireAfter = 2 * 60; + + public ExpiringMap() {} + + public ExpiringMap(long expireAfter) { + this.expireAfter = expireAfter; + } + + public void put(K key, V value) { + map.put(key, value); + entryTimeMap.put(key, now()); + } + + public V get(K key) { + return get(key, expireAfter); + } + + public V get(K key, long expireAfter) { + V value = map.get(key); + + if (Objects.isNull(value)) { + return null; + } + + Long entryTime = entryTimeMap.get(key); + if (Objects.isNull(entryTime)) { + map.remove(key); + return null; + } + + if (entryTime + expireAfter < now()) { + return null; + } + + return value; + } + + public void remove(K key) { + map.remove(key); + entryTimeMap.remove(key); + } + + private long now() { + return Instant.now().getEpochSecond(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/util/LockMap.java b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/util/LockMap.java new file mode 100644 index 000000000..c8014ee9b --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/java/org/eclipse/tractusx/edc/cp/adapter/util/LockMap.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + +/** + * When CP-Adapter works in InMemory mode, LockMap is used to prevent race condition of two events. + * This implementation will not work if both events will be handled by two separate EDC instances + * (persistent mode), but edc.cp.adapter.service.objectstore.ObjectStoreServiceSql#put(...) method + * will not allow to save both events in the table as PRIMARY_KE collision would appear. + */ +public class LockMap { + private final Map lock = new HashMap<>(); + + public void lock(String id) { + addLock(id); + lock.get(id).lock(); + } + + public void unlock(String id) { + addLock(id); + lock.get(id).unlock(); + } + + public void removeLock(String id) { + addLock(id); + lock.remove(id); + } + + private void addLock(String id) { + synchronized (this) { + lock.putIfAbsent(id, new ReentrantLock()); + } + } +} diff --git a/edc-extensions/control-plane-adapter/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/control-plane-adapter/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..30008be0f --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,14 @@ +# +# Copyright (c) 2022 ZF Friedrichshafen AG +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# ZF Friedrichshafen AG - Initial API and Implementation +# + +org.eclipse.tractusx.edc.cp.adapter.ApiAdapterExtension diff --git a/edc-extensions/control-plane-adapter/src/main/resources/control-plane-adapter.jpg b/edc-extensions/control-plane-adapter/src/main/resources/control-plane-adapter.jpg new file mode 100644 index 000000000..00fd1241b Binary files /dev/null and b/edc-extensions/control-plane-adapter/src/main/resources/control-plane-adapter.jpg differ diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/HttpControllerTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/HttpControllerTest.java new file mode 100644 index 000000000..0d0f6add3 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/HttpControllerTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; + +import jakarta.ws.rs.core.Response; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.eclipse.tractusx.edc.cp.adapter.service.ResultService; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Mockito; + +public class HttpControllerTest { + @Mock ApiAdapterConfig config = Mockito.mock(ApiAdapterConfig.class); + Integer RETRY_NUMBER = 3; + + @Test + public void getAssetSynchronous_shouldReturnBadRequestIfNoAssetIdParam() { + // given + Monitor monitor = Mockito.mock(Monitor.class); + ResultService resultService = Mockito.mock(ResultService.class); + MessageBus messageBus = Mockito.mock(MessageBus.class); + when(config.getDefaultMessageRetryNumber()).thenReturn(RETRY_NUMBER); + HttpController httpController = new HttpController(monitor, resultService, messageBus, config); + + // when + Response response = httpController.getAssetSynchronous(null, "providerUrl", null, false, null); + + // then + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + } + + @Test + public void getAssetSynchronous_shouldReturnBadRequestIfNoProviderUrlParam() { + // given + Monitor monitor = Mockito.mock(Monitor.class); + ResultService resultService = Mockito.mock(ResultService.class); + MessageBus messageBus = Mockito.mock(MessageBus.class); + ApiAdapterConfig config = Mockito.mock(ApiAdapterConfig.class); + when(config.getDefaultMessageRetryNumber()).thenReturn(RETRY_NUMBER); + HttpController httpController = new HttpController(monitor, resultService, messageBus, config); + + // when + Response response = httpController.getAssetSynchronous("assetId", null, null, false, null); + + // then + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); + } + + @Test + public void getAssetSynchronous_shouldReturnErrorStatusIfOccurred() throws InterruptedException { + // given + Monitor monitor = Mockito.mock(Monitor.class); + ResultService resultService = Mockito.mock(ResultService.class); + MessageBus messageBus = Mockito.mock(MessageBus.class); + ApiAdapterConfig config = Mockito.mock(ApiAdapterConfig.class); + when(config.getDefaultMessageRetryNumber()).thenReturn(RETRY_NUMBER); + HttpController httpController = new HttpController(monitor, resultService, messageBus, config); + + when(resultService.pull(anyString())) + .thenReturn( + ProcessData.builder() + .errorStatus(Response.Status.BAD_GATEWAY) + .endpointDataReference(getEndpointDataReference()) + .build()); + + // when + Response response = + httpController.getAssetSynchronous("assetId", "providerUrl", null, false, null); + + // then + assertEquals(Response.Status.BAD_GATEWAY.getStatusCode(), response.getStatus()); + } + + @Test + public void getAssetSynchronous_shouldReturnOkResponse() throws InterruptedException { + // given + Monitor monitor = Mockito.mock(Monitor.class); + ResultService resultService = Mockito.mock(ResultService.class); + MessageBus messageBus = Mockito.mock(MessageBus.class); + ApiAdapterConfig config = Mockito.mock(ApiAdapterConfig.class); + when(config.getDefaultMessageRetryNumber()).thenReturn(RETRY_NUMBER); + HttpController httpController = new HttpController(monitor, resultService, messageBus, config); + when(resultService.pull(anyString())) + .thenReturn( + ProcessData.builder().endpointDataReference(getEndpointDataReference()).build()); + + // when + Response response = + httpController.getAssetSynchronous("assetId", "providerUrl", null, false, null); + + // then + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + } + + private EndpointDataReference getEndpointDataReference() { + return EndpointDataReference.Builder.newInstance() + .endpoint("endpoint") + .authCode("authCode") + .authKey("authKey") + .build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/messaging/InMemoryMessageBusTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/messaging/InMemoryMessageBusTest.java new file mode 100644 index 000000000..abf500a96 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/messaging/InMemoryMessageBusTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class InMemoryMessageBusTest { + @Mock Monitor monitor; + @Mock Listener listener; + @Mock ListenerService listenerService; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void send_shouldCallListenerOnce() throws InterruptedException { + // given + Message message = new DataReferenceRetrievalDto(null, 3); + when(listenerService.getListener(any())).thenReturn(listener); + MessageBus messageBus = new InMemoryMessageBus(monitor, listenerService, 3); + + // when + messageBus.send(Channel.INITIAL, message); + + // then + Thread.sleep(50); + verify(listener, times(1)).process(any(DataReferenceRetrievalDto.class)); + } + + @Test + public void send_shouldCallListenerWithRetryOnException() throws InterruptedException { + // given + Message message = new DataReferenceRetrievalDto(null, 3); + when(listenerService.getListener(any())).thenReturn(listener); + doThrow(new IllegalStateException()).doNothing().when(listener).process(any()); + MessageBus messageBus = new InMemoryMessageBus(monitor, listenerService, 3); + + // when + messageBus.send(Channel.INITIAL, message); + + // then + Thread.sleep(1000); + verify(listener, times(2)).process(any(DataReferenceRetrievalDto.class)); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/messaging/SqlMessageBusTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/messaging/SqlMessageBusTest.java new file mode 100644 index 000000000..a7a953c3c --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/messaging/SqlMessageBusTest.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.messaging; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.*; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; +import org.eclipse.edc.transaction.spi.TransactionContext; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.store.SqlQueueStore; +import org.eclipse.tractusx.edc.cp.adapter.store.model.QueueMessage; +import org.eclipse.tractusx.edc.cp.adapter.store.schema.QueueStatements; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class SqlMessageBusTest { + @Mock Monitor monitor; + @Mock Listener listener; + @Mock ListenerService listenerService; + @Mock SqlQueueStore store; + @Mock DataSourceRegistry dataSourceRegistry; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void send_shouldCallListenerOnce() throws InterruptedException { + // given + Message message = new DataReferenceRetrievalDto(null, 3); + when(listenerService.getListener(any())).thenReturn(listener); + SqlMessageBus messageBus = + new SqlMessageBus(monitor, listenerService, inMemoryFakeStore(), 2, 10); + + // when + messageBus.send(Channel.INITIAL, message); + Thread.sleep(60); + messageBus.deliverMessages(10); + + // then + Thread.sleep(60); + verify(listener, times(1)).process(any(DataReferenceRetrievalDto.class)); + } + + @Test + public void send_shouldCallListenerWithRetryOnException() throws InterruptedException { + // given + Message message = new DataReferenceRetrievalDto(null, 3); + when(listenerService.getListener(any())).thenReturn(listener); + doThrow(new IllegalStateException()).doNothing().when(listener).process(any()); + SqlMessageBus messageBus = + new SqlMessageBus(monitor, listenerService, inMemoryFakeStore(), 2, 10); + + // when + messageBus.send(Channel.INITIAL, message); + messageBus.deliverMessages(10); + Thread.sleep(60); + + // then + verify(listener, times(2)).process(any(DataReferenceRetrievalDto.class)); + } + + @Test + public void send_shouldSendToDlqIfErrorLimitReached() throws InterruptedException { + // given + Message message = new DataReferenceRetrievalDto(null, 3); + message.setErrorNumber(10); + when(listenerService.getListener(any())).thenReturn(listener); + doThrow(new IllegalStateException()).doNothing().when(listener).process(any()); + SqlMessageBus messageBus = + new SqlMessageBus(monitor, listenerService, inMemoryFakeStore(), 2, 10); + + // when + messageBus.send(Channel.INITIAL, message); + Thread.sleep(60); + + // then + verify(listenerService).getListener(eq(Channel.DLQ)); + } + + private SqlQueueStore inMemoryFakeStore() { + return new SqlQueueStore( + dataSourceRegistry, + "dsname", + getFakeTransactionContext(), + new ObjectMapper(), + getFakeStatements(), + "cid", + getFakeClock()) { + + private final Map map = new HashMap<>(); + + @Override + public void saveMessage(QueueMessage queueMessage) { + String id = UUID.randomUUID().toString(); + queueMessage.setId(id); + map.put(id, queueMessage); + } + + @Override + public QueueMessage findById(String id) { + return map.get(id); + } + + @Override + public void deleteMessage(String id) { + map.remove(id); + } + + @Override + public void updateMessage(QueueMessage queueMessage) { + map.remove(queueMessage.getId()); + map.put(queueMessage.getId(), queueMessage); + } + + @Override + public List findMessagesToSend(int max) { + return new ArrayList<>(map.values()); + } + }; + } + + private Clock getFakeClock() { + return new Clock() { + @Override + public ZoneId getZone() { + return null; + } + + @Override + public Clock withZone(ZoneId zone) { + return null; + } + + @Override + public Instant instant() { + return null; + } + }; + } + + @NotNull + private QueueStatements getFakeStatements() { + return new QueueStatements() { + @Override + public String getAllMessagesTemplate() { + return null; + } + + @Override + public String getMessagesToSendTemplate() { + return null; + } + + @Override + public String getSaveMessageTemplate() { + return null; + } + + @Override + public String getDeleteTemplate() { + return null; + } + + @Override + public String getFindByIdTemplate() { + return null; + } + + @Override + public String getUpdateTemplate() { + return null; + } + + @Override + public String getDeleteLeaseTemplate() { + return null; + } + + @Override + public String getInsertLeaseTemplate() { + return null; + } + + @Override + public String getUpdateLeaseTemplate() { + return null; + } + + @Override + public String getFindLeaseByEntityTemplate() { + return null; + } + }; + } + + private TransactionContext getFakeTransactionContext() { + return new TransactionContext() { + @Override + public void execute(TransactionBlock transactionBlock) {} + + @Override + public T execute(ResultTransactionBlock resultTransactionBlock) { + return null; + } + + @Override + public void registerSynchronization(TransactionSynchronization transactionSynchronization) {} + }; + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogRetrieverTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogRetrieverTest.java new file mode 100644 index 000000000..22f1946ed --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/CatalogRetrieverTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.eclipse.edc.catalog.spi.Catalog; +import org.eclipse.edc.connector.contract.spi.types.offer.ContractOffer; +import org.eclipse.edc.connector.spi.catalog.CatalogService; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.types.domain.asset.Asset; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class CatalogRetrieverTest { + @Mock CatalogService catalogService; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void getEntireCatalog_shouldReturnEntireCatalogIfMoreThanOnePage() { + // given + CatalogRetriever catalogRetriever = new CatalogRetriever(50, catalogService); + when(catalogService.getByProviderUrl(anyString(), any())) + .thenReturn(getCatalogResult(50), getCatalogResult(50), getCatalogResult(10)); + + // when + Catalog catalog = catalogRetriever.getEntireCatalog("providerUrl", "assetId"); + + // then + assertEquals(110, catalog.getContractOffers().size()); + } + + @Test + public void getEntireCatalog_shouldEmptyCatalogIfNoResults() { + // given + CatalogRetriever catalogRetriever = new CatalogRetriever(50, catalogService); + when(catalogService.getByProviderUrl(anyString(), any())).thenReturn(getCatalogResult(0)); + + // when + Catalog catalog = catalogRetriever.getEntireCatalog("providerUrl", "assetId"); + + // then + assertEquals(0, catalog.getContractOffers().size()); + } + + private CompletableFuture getCatalogResult(int offersNumber) { + List contractOffers = + IntStream.range(0, offersNumber) + .mapToObj(operand -> getContractOffer()) + .collect(Collectors.toList()); + + return CompletableFuture.completedFuture( + Catalog.Builder.newInstance().id("id").contractOffers(contractOffers).build()); + } + + private ContractOffer getContractOffer() { + Asset asset = Asset.Builder.newInstance().id("assetId").build(); + return ContractOffer.Builder.newInstance() + .id("id") + .asset(asset) + .policy(Policy.Builder.newInstance().build()) + .contractStart(ZonedDateTime.now()) + .contractEnd(ZonedDateTime.now().plusDays(1)) + .build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractAgreementRetrieverTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractAgreementRetrieverTest.java new file mode 100644 index 000000000..ad4cda3c0 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractAgreementRetrieverTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.time.Instant; +import java.util.stream.Stream; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; +import org.eclipse.edc.connector.spi.contractagreement.ContractAgreementService; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.service.spi.result.ServiceResult; +import org.eclipse.edc.spi.monitor.Monitor; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class ContractAgreementRetrieverTest { + @Mock Monitor monitor; + @Mock ContractAgreementService agreementService; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void getExistingContractByAssetId_shouldReturnValidContract() { + // given + long now = Instant.now().getEpochSecond(); + when(agreementService.query(any())).thenReturn(getResult(now + 1000)); + ContractAgreementRetriever retriever = + new ContractAgreementRetriever(monitor, agreementService); + + // when + ContractAgreement contractAgreement = retriever.getExistingContractByAssetId("id"); + + // then + Assertions.assertNotNull(contractAgreement); + } + + @Test + public void getExistingContractByAssetId_shouldNotReturnExpiredContract() { + // given + long now = Instant.now().getEpochSecond(); + when(agreementService.query(any())).thenReturn(getResult(now - 1000)); + ContractAgreementRetriever retriever = + new ContractAgreementRetriever(monitor, agreementService); + + // when + ContractAgreement contractAgreement = retriever.getExistingContractByAssetId("id"); + + // then + Assertions.assertNull(contractAgreement); + } + + private ServiceResult> getResult(long endDate) { + long now = Instant.now().getEpochSecond(); + return ServiceResult.success( + Stream.of( + ContractAgreement.Builder.newInstance() + .id("id") + .assetId("assetId") + .contractStartDate(now - 2000) + .contractEndDate(endDate) + .providerAgentId("providerId") + .consumerAgentId("consumerId") + .policy(Policy.Builder.newInstance().build()) + .build())); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractNegotiationHandlerTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractNegotiationHandlerTest.java new file mode 100644 index 000000000..7d82766a9 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnegotiation/ContractNegotiationHandlerTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnegotiation; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; + +import java.time.Instant; +import java.time.ZonedDateTime; +import java.util.List; +import org.eclipse.edc.catalog.spi.Catalog; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.connector.contract.spi.types.offer.ContractOffer; +import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationService; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.types.domain.asset.Asset; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class ContractNegotiationHandlerTest { + @Mock Monitor monitor; + @Mock MessageBus messageBus; + @Mock ContractNegotiationService contractNegotiationService; + @Mock CatalogCachedRetriever catalogRetriever; + @Mock ContractAgreementRetriever agreementRetriever; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void process_shouldNotInitializeContractNegotiationWhenContractAlreadyAvailable() { + // given + ContractNegotiationHandler contractNegotiationHandler = + new ContractNegotiationHandler( + monitor, messageBus, contractNegotiationService, catalogRetriever, agreementRetriever); + + when(agreementRetriever.getExistingContractByAssetId(anyString())) + .thenReturn(getValidContractAgreement()); + + // when + contractNegotiationHandler.process(new DataReferenceRetrievalDto(getProcessData(), 3)); + + // then + verify(contractNegotiationService, times(0)).initiateNegotiation(any()); + verify(messageBus, times(1)).send(any(), any(Message.class)); + } + + @Test + public void process_shouldInitializeContractNegotiationWhenExistingContractExpired() { + // given + ContractNegotiationHandler contractNegotiationHandler = + new ContractNegotiationHandler( + monitor, messageBus, contractNegotiationService, catalogRetriever, agreementRetriever); + + when(agreementRetriever.getExistingContractByAssetId(anyString())) + .thenReturn(getExpiredContractAgreement()); + when(catalogRetriever.getEntireCatalog(anyString(), anyString(), anyInt())) + .thenReturn(getCatalog()); + when(contractNegotiationService.initiateNegotiation(any())) + .thenReturn(getContractNegotiation()); + + // when + contractNegotiationHandler.process(new DataReferenceRetrievalDto(getProcessData(), 3)); + + // then + verify(contractNegotiationService, times(1)).initiateNegotiation(any()); + verify(messageBus, times(1)).send(any(), any(Message.class)); + } + + @Test + public void process_shouldInitiateContractNegotiationAndSendDtoFurtherIfAgreementNotExist() { + // given + ContractNegotiationHandler contractNegotiationHandler = + new ContractNegotiationHandler( + monitor, messageBus, contractNegotiationService, catalogRetriever, agreementRetriever); + + when(agreementRetriever.getExistingContractByAssetId(anyString())).thenReturn(null); + when(catalogRetriever.getEntireCatalog(anyString(), anyString(), anyInt())) + .thenReturn(getCatalog()); + when(contractNegotiationService.initiateNegotiation(any())) + .thenReturn(getContractNegotiation()); + + // when + contractNegotiationHandler.process(new DataReferenceRetrievalDto(getProcessData(), 3)); + + // then + verify(contractNegotiationService, times(1)).initiateNegotiation(any()); + verify(messageBus, times(1)).send(any(), any(Message.class)); + } + + private ProcessData getProcessData() { + return ProcessData.builder() + .assetId("assetId") + .provider("provider") + .catalogExpiryTime(30) + .contractAgreementReuseOn(true) + .build(); + } + + private ContractNegotiation getContractNegotiation() { + return ContractNegotiation.Builder.newInstance() + .id("contractNegotiationId") + .counterPartyId("counterPartyId") + .counterPartyAddress("counterPartyAddress") + .protocol("protocol") + .build(); + } + + private Catalog getCatalog() { + return Catalog.Builder.newInstance() + .id("id") + .contractOffers(List.of(getContractOffer())) + .build(); + } + + private ContractOffer getContractOffer() { + Asset asset = Asset.Builder.newInstance().id("assetId").build(); + return ContractOffer.Builder.newInstance() + .id("id") + .asset(asset) + .contractStart(ZonedDateTime.now()) + .contractEnd(ZonedDateTime.now().plusDays(1)) + .policy(Policy.Builder.newInstance().build()) + .build(); + } + + private ContractAgreement getValidContractAgreement() { + long now = Instant.now().getEpochSecond(); + return ContractAgreement.Builder.newInstance() + .id("id") + .assetId("assetId") + .contractStartDate(now - 5000) + .contractEndDate(now + 5000) + .consumerAgentId("consumer") + .providerAgentId("provider") + .policy(Policy.Builder.newInstance().build()) + .build(); + } + + private ContractAgreement getExpiredContractAgreement() { + long now = Instant.now().getEpochSecond(); + return ContractAgreement.Builder.newInstance() + .id("id") + .assetId("assetId") + .contractStartDate(now - 5000) + .contractEndDate(now - 1000) + .consumerAgentId("consumer") + .providerAgentId("provider") + .policy(Policy.Builder.newInstance().build()) + .build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNegotiationListenerTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNegotiationListenerTest.java new file mode 100644 index 000000000..5d0e83553 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNegotiationListenerTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.times; + +import jakarta.ws.rs.core.Response; +import org.eclipse.edc.connector.contract.spi.negotiation.observe.ContractNegotiationListener; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiationStates; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class ContractNegotiationListenerTest { + @Mock Monitor monitor; + @Mock MessageBus messageBus; + @Mock ContractNotificationSyncService syncService; + @Mock DataTransferInitializer dataTransfer; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void confirmed_shouldNotInitiateTransferIfMessageNotAvailable() { + // given + ContractNegotiationListener listener = + new ContractNegotiationListenerImpl(monitor, messageBus, syncService, dataTransfer); + ContractNegotiation contractNegotiation = getConfirmedContractNegotiation(); + + // when + listener.confirmed(contractNegotiation); + + // then + verify(syncService, times(1)).exchangeConfirmedContract(any(), any()); + verify(dataTransfer, times(0)).initiate(any()); + verify(messageBus, times(0)).send(eq(Channel.DATA_REFERENCE), any(Message.class)); + } + + @Test + public void confirmed_shouldInitiateTransferIfMessageIsAvailable() { + // given + when(syncService.exchangeConfirmedContract(any(), any())) + .thenReturn(new DataReferenceRetrievalDto(getProcessData(), 3)); + verify(dataTransfer, times(0)).initiate(any()); + + ContractNegotiationListener listener = + new ContractNegotiationListenerImpl(monitor, messageBus, syncService, dataTransfer); + ContractNegotiation contractNegotiation = getConfirmedContractNegotiation(); + + // when + listener.confirmed(contractNegotiation); + + // then + verify(dataTransfer, times(1)).initiate(any()); + verify(messageBus, times(1)).send(eq(Channel.DATA_REFERENCE), any(Message.class)); + } + + @Test + public void preDeclined_shouldSendErrorResultIfMessageIsAvailable() { + // given + when(syncService.exchangeDeclinedContract(any())) + .thenReturn(new DataReferenceRetrievalDto(getProcessData(), 3)); + ContractNegotiationListener listener = + new ContractNegotiationListenerImpl(monitor, messageBus, syncService, dataTransfer); + ContractNegotiation contractNegotiation = getConfirmedContractNegotiation(); + + // when + listener.declined(contractNegotiation); + + // then + ArgumentCaptor messageArg = + ArgumentCaptor.forClass(DataReferenceRetrievalDto.class); + verify(messageBus, times(1)).send(eq(Channel.RESULT), messageArg.capture()); + Assertions.assertEquals( + Response.Status.BAD_GATEWAY, messageArg.getValue().getPayload().getErrorStatus()); + } + + @Test + public void preError_shouldSendErrorResultIfMessageIsAvailable() { + // given + when(syncService.exchangeErrorContract(any())) + .thenReturn(new DataReferenceRetrievalDto(getProcessData(), 3)); + ContractNegotiationListener listener = + new ContractNegotiationListenerImpl(monitor, messageBus, syncService, dataTransfer); + ContractNegotiation contractNegotiation = getConfirmedContractNegotiation(); + + // when + listener.failed(contractNegotiation); + + // then + ArgumentCaptor messageArg = + ArgumentCaptor.forClass(DataReferenceRetrievalDto.class); + verify(messageBus, times(1)).send(eq(Channel.RESULT), messageArg.capture()); + Assertions.assertEquals( + Response.Status.BAD_GATEWAY, messageArg.getValue().getPayload().getErrorStatus()); + } + + private ContractNegotiation getConfirmedContractNegotiation() { + return ContractNegotiation.Builder.newInstance() + .state(ContractNegotiationStates.CONFIRMED.code()) + .id("contractNegotiationId") + .counterPartyId("counterPartyId") + .counterPartyAddress("counterPartyAddress") + .protocol("protocol") + .contractAgreement( + ContractAgreement.Builder.newInstance() + .id("contractAgreementId") + .providerAgentId("providerAgentId") + .consumerAgentId("consumerAgentId") + .assetId("assetId") + .policy(Policy.Builder.newInstance().build()) + .build()) + .build(); + } + + private ProcessData getProcessData() { + return ProcessData.builder().assetId("assetId").provider("provider").build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationHandlerTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationHandlerTest.java new file mode 100644 index 000000000..c2e0480b3 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractNotificationHandlerTest.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiationStates; +import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationService; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class ContractNotificationHandlerTest { + @Mock Monitor monitor; + @Mock MessageBus messageBus; + @Mock ContractNegotiationService contractNegotiationService; + @Mock ContractNotificationSyncService syncService; + @Mock DataTransferInitializer dataTransfer; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void process_shouldNotInitiateTransferWhenNoContractNotification() { + // given + ContractNotificationHandler contractNotificationHandler = + new ContractNotificationHandler( + monitor, messageBus, syncService, contractNegotiationService, dataTransfer); + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(getProcessData(), 3); + + // when + contractNotificationHandler.process(dto); + + // then + verify(syncService, times(1)).exchangeDto(any()); + verify(dataTransfer, times(0)).initiate(any()); + verify(messageBus, times(0)).send(eq(Channel.DATA_REFERENCE), any(Message.class)); + } + + @Test + public void process_shouldInitiateTransferWhenContractConfirmedFromCache() { + // given + ContractNotificationHandler contractNotificationHandler = + new ContractNotificationHandler( + monitor, messageBus, syncService, contractNegotiationService, dataTransfer); + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(getProcessData(), 3); + dto.getPayload().setContractConfirmed(true); + + // when + contractNotificationHandler.process(dto); + + // then + verify(dataTransfer, times(1)).initiate(any()); + verify(messageBus, times(1)).send(eq(Channel.DATA_REFERENCE), any(Message.class)); + } + + @Test + public void process_shouldInitiateTransferWhenContractAlreadyConfirmedAtProvider() { + // given + when(contractNegotiationService.findbyId(any())).thenReturn(getConfirmedContractNegotiation()); + ContractNotificationHandler contractNotificationHandler = + new ContractNotificationHandler( + monitor, messageBus, syncService, contractNegotiationService, dataTransfer); + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(getProcessData(), 3); + + // when + contractNotificationHandler.process(dto); + + // then + verify(syncService, times(0)).exchangeDto(any()); + verify(dataTransfer, times(1)).initiate(any()); + verify(messageBus, times(1)).send(eq(Channel.DATA_REFERENCE), any(Message.class)); + } + + @Test + public void process_shouldInitiateTransferWhenContractConfirmedByNotification() { + // given + when(syncService.exchangeDto(any())) + .thenReturn( + new ContractInfo("confirmedContractAgreementId", ContractInfo.ContractState.CONFIRMED)); + ContractNotificationHandler contractNotificationHandler = + new ContractNotificationHandler( + monitor, messageBus, syncService, contractNegotiationService, dataTransfer); + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(getProcessData(), 3); + + // when + contractNotificationHandler.process(dto); + + // then + verify(dataTransfer, times(1)).initiate(any()); + verify(messageBus, times(1)).send(eq(Channel.DATA_REFERENCE), any(Message.class)); + verify(syncService, times(1)).removeContractInfo(any()); + } + + private ContractNegotiation getConfirmedContractNegotiation() { + return ContractNegotiation.Builder.newInstance() + .state(ContractNegotiationStates.CONFIRMED.code()) + .id("contractNegotiationId") + .counterPartyId("counterPartyId") + .counterPartyAddress("counterPartyAddress") + .protocol("protocol") + .contractAgreement( + ContractAgreement.Builder.newInstance() + .id("contractAgreementId") + .providerAgentId("providerAgentId") + .consumerAgentId("consumerAgentId") + .assetId("assetId") + .policy(Policy.Builder.newInstance().build()) + .build()) + .build(); + } + + private ProcessData getProcessData() { + return ProcessData.builder().assetId("assetId").provider("provider").build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractSyncServiceTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractSyncServiceTest.java new file mode 100644 index 000000000..720cc0b37 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/contractnotification/ContractSyncServiceTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.contractnotification; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreServiceInMemory; +import org.eclipse.tractusx.edc.cp.adapter.util.LockMap; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ContractSyncServiceTest { + + @Test + public void exchangeConfirmedContract_shouldReturnDtoIfAvailable() { + // given + ContractSyncService syncService = + new ContractSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + syncService.exchangeDto(getDataReferenceRetrievalDto()); + + // when + DataReferenceRetrievalDto dto = + syncService.exchangeConfirmedContract("negotiationId", "agreementId"); + + // then + Assertions.assertNotNull(dto); + } + + @Test + public void exchangeConfirmedContract_shouldReturnNullIfDtoNotAvailable() { + // given + ContractSyncService syncService = + new ContractSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + + // when + DataReferenceRetrievalDto dto = + syncService.exchangeConfirmedContract("negotiationId", "agreementId"); + + // then + Assertions.assertNull(dto); + } + + @Test + public void exchangeDeclinedContract_shouldReturnDtoIfAvailable() { + // given + ContractSyncService syncService = + new ContractSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + syncService.exchangeDto(getDataReferenceRetrievalDto()); + + // when + DataReferenceRetrievalDto dto = syncService.exchangeDeclinedContract("negotiationId"); + + // then + Assertions.assertNotNull(dto); + } + + @Test + public void exchangeDeclinedContract_shouldReturnNullIfDtoNotAvailable() { + // given + ContractSyncService syncService = + new ContractSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + + // when + DataReferenceRetrievalDto dto = syncService.exchangeDeclinedContract("negotiationId"); + + // then + Assertions.assertNull(dto); + } + + @Test + public void exchangeErrorContract_shouldReturnDtoIfAvailable() { + // given + ContractSyncService syncService = + new ContractSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + syncService.exchangeDto(getDataReferenceRetrievalDto()); + + // when + DataReferenceRetrievalDto dto = syncService.exchangeErrorContract("negotiationId"); + + // then + Assertions.assertNotNull(dto); + } + + @Test + public void exchangeErrorContract_shouldReturnNullIfDtoNotAvailable() { + // given + ContractSyncService syncService = + new ContractSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + + // when + DataReferenceRetrievalDto dto = syncService.exchangeErrorContract("negotiationId"); + + // then + Assertions.assertNull(dto); + } + + @Test + public void exchangeDto_shouldReturnContractInfoIfAvailable() { + // given + ContractSyncService syncService = + new ContractSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + syncService.exchangeConfirmedContract("negotiationId", "agreementId"); + + // when + ContractInfo contractInfo = syncService.exchangeDto(getDataReferenceRetrievalDto()); + + // then + Assertions.assertNotNull(contractInfo); + } + + @Test + public void exchangeDto_shouldReturnNullIfContractInfoNotAvailable() { + // given + ContractSyncService syncService = + new ContractSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + + // when + ContractInfo contractInfo = syncService.exchangeDto(getDataReferenceRetrievalDto()); + + // then + Assertions.assertNull(contractInfo); + } + + private DataReferenceRetrievalDto getDataReferenceRetrievalDto() { + ProcessData processData = ProcessData.builder().assetId("assetId").provider("provider").build(); + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(processData, 3); + dto.getPayload().setContractNegotiationId("negotiationId"); + return dto; + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefSyncServiceTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefSyncServiceTest.java new file mode 100644 index 000000000..0b0e537f7 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataRefSyncServiceTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreServiceInMemory; +import org.eclipse.tractusx.edc.cp.adapter.util.LockMap; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class DataRefSyncServiceTest { + + @Test + public void exchangeDto_shouldReturnDataReferenceIfAvailable() { + // given + DataRefSyncService syncService = + new DataRefSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + syncService.exchangeDataReference(getEndpointDataReference(), "agreementId"); + + // when + EndpointDataReference dataReference = + syncService.exchangeDto(getDataReferenceRetrievalDto(), "agreementId"); + + // then + Assertions.assertNotNull(dataReference); + } + + @Test + public void exchangeDto_shouldReturnNullIfDataReferenceNotAvailable() { + // given + DataRefSyncService syncService = + new DataRefSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + + // when + EndpointDataReference dataReference = + syncService.exchangeDto(getDataReferenceRetrievalDto(), "agreementId"); + + // then + Assertions.assertNull(dataReference); + } + + @Test + public void exchangeDataReference_shouldReturnDtoIfAvailable() { + // given + DataRefSyncService syncService = + new DataRefSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + syncService.exchangeDto(getDataReferenceRetrievalDto(), "agreementId"); + + // when + DataReferenceRetrievalDto dto = + syncService.exchangeDataReference(getEndpointDataReference(), "agreementId"); + + // then + Assertions.assertNotNull(dto); + } + + @Test + public void exchangeDataReference_shouldReturnNullIfDtoNotAvailable() { + // given + DataRefSyncService syncService = + new DataRefSyncService(new ObjectStoreServiceInMemory(new ObjectMapper()), new LockMap()); + + // when + DataReferenceRetrievalDto dto = + syncService.exchangeDataReference(getEndpointDataReference(), "agreementId"); + + // then + Assertions.assertNull(dto); + } + + private EndpointDataReference getEndpointDataReference() { + return EndpointDataReference.Builder.newInstance() + .endpoint("endpoint") + .authCode("authCode") + .authKey("authKey") + .build(); + } + + private DataReferenceRetrievalDto getDataReferenceRetrievalDto() { + ProcessData processData = ProcessData.builder().assetId("assetId").provider("provider").build(); + return new DataReferenceRetrievalDto(processData, 3); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceErrorHandlerTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceErrorHandlerTest.java new file mode 100644 index 000000000..167a47479 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceErrorHandlerTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.edc.connector.spi.transferprocess.TransferProcessService; +import org.eclipse.edc.connector.transfer.spi.types.TransferProcessStates; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreService; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectStoreServiceInMemory; +import org.eclipse.tractusx.edc.cp.adapter.service.objectstore.ObjectType; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class DataReferenceErrorHandlerTest { + @Mock Monitor monitor; + @Mock MessageBus messageBus; + @Mock TransferProcessService transferProcessService; + ObjectStoreService storeService = new ObjectStoreServiceInMemory(new ObjectMapper()); + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + storeService.put("key1", ObjectType.DTO, getDto()); + storeService.put("key2", ObjectType.DTO, getDto()); + } + + @Test + public void validateActiveProcesses_shouldSkipIfNoError() { + // given + when(transferProcessService.getState("transferId")) + .thenReturn(TransferProcessStates.COMPLETED.name()); + DataReferenceErrorHandler errorHandler = + new DataReferenceErrorHandler(monitor, messageBus, storeService, transferProcessService); + + // when + errorHandler.validateActiveProcesses(); + + // then + verify(messageBus, times(0)).send(eq(Channel.RESULT), any(Message.class)); + } + + @Test + public void validateActiveProcesses_shouldHandleErrorReference() { + // given + when(transferProcessService.getState("transferId")) + .thenReturn(TransferProcessStates.COMPLETED.name()) + .thenReturn(TransferProcessStates.ERROR.name()); + DataReferenceErrorHandler errorHandler = + new DataReferenceErrorHandler(monitor, messageBus, storeService, transferProcessService); + + // when + errorHandler.validateActiveProcesses(); + + // then + verify(messageBus, times(1)).send(eq(Channel.RESULT), any(Message.class)); + } + + @Test + public void validateActiveProcesses_shouldHandleCancelledReference() { + // given + when(transferProcessService.getState("transferId")) + .thenReturn(TransferProcessStates.COMPLETED.name()) + .thenReturn(TransferProcessStates.CANCELLED.name()); + DataReferenceErrorHandler errorHandler = + new DataReferenceErrorHandler(monitor, messageBus, storeService, transferProcessService); + + // when + errorHandler.validateActiveProcesses(); + + // then + verify(messageBus, times(1)).send(eq(Channel.RESULT), any(Message.class)); + } + + private DataReferenceRetrievalDto getDto() { + return new DataReferenceRetrievalDto(getProcessData(), 3); + } + + private ProcessData getProcessData() { + return ProcessData.builder() + .assetId("assetId") + .provider("provider") + .contractAgreementId("agreementId") + .transferProcessId("transferId") + .build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceHandlerTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceHandlerTest.java new file mode 100644 index 000000000..138dbe974 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/DataReferenceHandlerTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class DataReferenceHandlerTest { + @Mock Monitor monitor; + @Mock MessageBus messageBus; + @Mock DataRefNotificationSyncService notificationSyncService; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void process_shouldNotSendResultWhenDataReferenceNotAvailable() { + // given + DataReferenceHandler dataReferenceHandler = + new DataReferenceHandler(monitor, messageBus, notificationSyncService); + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(getProcessData(), 3); + + // when + dataReferenceHandler.process(dto); + + // then + verify(notificationSyncService, times(1)).exchangeDto(eq(dto), any()); + verify(messageBus, times(0)).send(eq(Channel.RESULT), any(Message.class)); + } + + @Test + public void process_shouldSendResultWhenDataReferenceIsAvailable() { + // given + when(notificationSyncService.exchangeDto(any(), any())).thenReturn(getEndpointDataReference()); + DataReferenceHandler dataReferenceHandler = + new DataReferenceHandler(monitor, messageBus, notificationSyncService); + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(getProcessData(), 3); + + // when + dataReferenceHandler.process(dto); + + // then + verify(messageBus, times(1)).send(eq(Channel.RESULT), any(Message.class)); + verify(notificationSyncService, times(1)).removeDataReference(any()); + } + + private EndpointDataReference getEndpointDataReference() { + return EndpointDataReference.Builder.newInstance() + .endpoint("endpoint") + .authCode("authCode") + .authKey("authKey") + .build(); + } + + private ProcessData getProcessData() { + return ProcessData.builder().assetId("assetId").provider("provider").build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/EndpointDataReferenceReceiverTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/EndpointDataReferenceReceiverTest.java new file mode 100644 index 000000000..9d0d983c4 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/process/datareference/EndpointDataReferenceReceiverTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.process.datareference; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +import org.eclipse.edc.connector.transfer.spi.edr.EndpointDataReferenceReceiver; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Channel; +import org.eclipse.tractusx.edc.cp.adapter.messaging.Message; +import org.eclipse.tractusx.edc.cp.adapter.messaging.MessageBus; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class EndpointDataReferenceReceiverTest { + @Mock Monitor monitor; + @Mock MessageBus messageBus; + @Mock DataRefNotificationSyncService syncService; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void send_shouldNotSendResultWhenMessageNotAvailable() { + // given + EndpointDataReferenceReceiver referenceReceiver = + new EndpointDataReferenceReceiverImpl(monitor, messageBus, syncService); + + // when + referenceReceiver.send(getEndpointDataReference()); + + // then + verify(messageBus, times(0)).send(eq(Channel.RESULT), any(Message.class)); + } + + @Test + public void send_shouldSendResultWhenMessageIsAvailable() { + // given + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(getProcessData(), 3); + when(syncService.exchangeDataReference(any(), any())).thenReturn(dto); + EndpointDataReferenceReceiver referenceReceiver = + new EndpointDataReferenceReceiverImpl(monitor, messageBus, syncService); + + // when + referenceReceiver.send(getEndpointDataReference()); + + // then + verify(messageBus, times(1)).send(eq(Channel.RESULT), any(Message.class)); + verify(syncService, times(1)).removeDto(any()); + } + + private EndpointDataReference getEndpointDataReference() { + return EndpointDataReference.Builder.newInstance() + .endpoint("endpoint") + .authCode("authCode") + .authKey("authKey") + .build(); + } + + private ProcessData getProcessData() { + return ProcessData.builder().assetId("assetId").provider("provider").build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/service/ResultServiceTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/service/ResultServiceTest.java new file mode 100644 index 000000000..2b7bff25f --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/service/ResultServiceTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.service; + +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.concurrent.TimeUnit; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.cp.adapter.dto.DataReferenceRetrievalDto; +import org.eclipse.tractusx.edc.cp.adapter.dto.ProcessData; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class ResultServiceTest { + @Mock Monitor monitor; + + @BeforeEach + void init() { + MockitoAnnotations.openMocks(this); + } + + @Test + public void pull_shouldReturnDataReferenceWhenMessageOccursFirst() throws InterruptedException { + // given + ResultService resultService = new ResultService(20, monitor); + String endpointDataRefId = "456"; + DataReferenceRetrievalDto dto = getDto(endpointDataRefId); + ProcessData processData; + + // when + resultService.process(dto); + processData = resultService.pull(dto.getTraceId(), 200, TimeUnit.MILLISECONDS); + + // then + Assertions.assertEquals(endpointDataRefId, processData.getEndpointDataReference().getId()); + } + + @Test + public void pull_shouldReturnDataReferenceWhenMessageOccursSecond() throws InterruptedException { + // given + ResultService resultService = new ResultService(20, monitor); + String endpointDataRefId = "456"; + DataReferenceRetrievalDto dto = getDto(endpointDataRefId); + ProcessData processData; + + // when + processMessageWithDelay(resultService, dto); + processData = resultService.pull(dto.getTraceId(), 1000, TimeUnit.MILLISECONDS); + + // then + Assertions.assertEquals(endpointDataRefId, processData.getEndpointDataReference().getId()); + } + + @Test + public void pull_shouldReturnNullOnTimeout() throws InterruptedException { + // given + ResultService resultService = new ResultService(20, monitor); + + // when + ProcessData processData = resultService.pull("123", 500, TimeUnit.MILLISECONDS); + + // then + Assertions.assertNull(processData); + } + + @Test + public void process_shouldThrowIllegalArgumentExceptionIfNoDataPayload() { + // given + ResultService resultService = new ResultService(20, monitor); + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(null, 3); + + // when then + try { + resultService.process(dto); + fail("Method should throw IllegalArgumentException"); + } catch (IllegalArgumentException ignored) { + } + } + + private void processMessageWithDelay(ResultService resultService, DataReferenceRetrievalDto dto) { + new Thread( + () -> { + sleep(400); + resultService.process(dto); + }) + .start(); + } + + private DataReferenceRetrievalDto getDto(String endpointDataRefId) { + DataReferenceRetrievalDto dto = new DataReferenceRetrievalDto(getProcessData(), 3); + dto.getPayload() + .setEndpointDataReference( + EndpointDataReference.Builder.newInstance() + .id(endpointDataRefId) + .endpoint("e") + .authCode("c") + .authKey("k") + .build()); + return dto; + } + + private void sleep(long milisec) { + try { + Thread.sleep(milisec); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private ProcessData getProcessData() { + return ProcessData.builder().assetId("assetId").provider("provider").build(); + } +} diff --git a/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/util/ExpiringMapTest.java b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/util/ExpiringMapTest.java new file mode 100644 index 000000000..a9ed2a9b5 --- /dev/null +++ b/edc-extensions/control-plane-adapter/src/test/java/org/eclipse/tractusx/edc/cp/adapter/util/ExpiringMapTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * ZF Friedrichshafen AG - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.cp.adapter.util; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ExpiringMapTest { + + private static final String KEY = "key"; + private static final String VAL = "value"; + + @Test + public void get_shouldGetWhenNotExpired() { + // given + ExpiringMap expiringMap = new ExpiringMap<>(60); + expiringMap.put(KEY, VAL); + + // when + String value = expiringMap.get(KEY); + + // then + Assertions.assertEquals(VAL, value); + } + + @Test + public void get_shouldGetNullWhenExpired() throws InterruptedException { + // given + ExpiringMap expiringMap = new ExpiringMap<>(0); + expiringMap.put(KEY, VAL); + + // when + Thread.sleep(1000); + String value = expiringMap.get(KEY, 0); + + // then + Assertions.assertNull(value); + } + + @Test + public void get_shouldGetNullWhenRemoved() throws InterruptedException { + // given + ExpiringMap expiringMap = new ExpiringMap<>(0); + expiringMap.put(KEY, VAL); + + // when + expiringMap.remove(KEY); + String value = expiringMap.get(KEY, 1000); + + // then + Assertions.assertNull(value); + } +} diff --git a/edc-extensions/cx-oauth2/build.gradle.kts b/edc-extensions/cx-oauth2/build.gradle.kts new file mode 100644 index 000000000..8e7dd8111 --- /dev/null +++ b/edc-extensions/cx-oauth2/build.gradle.kts @@ -0,0 +1,14 @@ + +plugins { + `java-library` + `maven-publish` +} + +dependencies { + implementation(edc.spi.core) + implementation(edc.spi.oauth2) + implementation(edc.spi.jwt) + implementation(libs.slf4j.api) + implementation(libs.nimbus.jwt) + implementation(libs.okhttp) +} diff --git a/edc-extensions/cx-oauth2/pom.xml b/edc-extensions/cx-oauth2/pom.xml deleted file mode 100644 index 63e48cf6e..000000000 --- a/edc-extensions/cx-oauth2/pom.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - - - edc-extensions - net.catenax.edc.extensions - 0.1.6 - - 4.0.0 - - cx-oauth2 - jar - - - ${project.basedir}/src/main/java - ${originalSourceDirectory} - ${project.build.directory}/delombok - ${project.groupId}_${project.artifactId} - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - ${project.build.sourceEncoding} - - - org.projectlombok - lombok - ${org.projectlombok.lombok.version} - - - - - - - org.projectlombok - lombok-maven-plugin - ${org.projectlombok.lombok.maven.plugin.version} - - - generate-sources - - delombok - - - - - ${originalSourceDirectory} - ${delombokSourceDirectory} - false - UTF-8 - - skip - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - - - - - - org.eclipse.dataspaceconnector - core-spi - - - org.eclipse.dataspaceconnector - oauth2-spi - - - org.eclipse.dataspaceconnector - jwt-spi - - - - - org.eclipse.dataspaceconnector - jwt-spi - - - - - - org.projectlombok - lombok - - - org.slf4j - slf4j-api - - - com.nimbusds - nimbus-jose-jwt - - - com.squareup.okhttp3 - okhttp - - - - - org.junit.jupiter - junit-jupiter - test - - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - - - diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/OAuth2Extension.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/OAuth2Extension.java deleted file mode 100644 index 310d82729..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/OAuth2Extension.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2; - -import java.net.URI; -import lombok.NonNull; -import lombok.Setter; -import okhttp3.OkHttpClient; -import org.eclipse.dataspaceconnector.iam.oauth2.spi.Oauth2JwtDecoratorRegistry; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.EdcSetting; -import org.eclipse.dataspaceconnector.spi.iam.IdentityService; -import org.eclipse.dataspaceconnector.spi.jwt.TokenGenerationService; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationService; -import org.eclipse.dataspaceconnector.spi.system.*; - -@Provides(IdentityService.class) -@Requires({ - OkHttpClient.class, - Oauth2JwtDecoratorRegistry.class, - TokenGenerationService.class, - TokenValidationService.class -}) -public class OAuth2Extension implements ServiceExtension { - - @EdcSetting private static final String TOKEN_URL = "edc.oauth.token.url"; - - @EdcSetting private static final String PROVIDER_AUDIENCE = "edc.oauth.provider.audience"; - - @Inject @Setter private OkHttpClient okHttpClient; - - @Inject @Setter private Oauth2JwtDecoratorRegistry jwtDecoratorRegistry; - - @Inject @Setter private TokenGenerationService tokenGenerationService; - - @Inject @Setter private TokenValidationService tokenValidationService; - - @Override - public void initialize(@NonNull final ServiceExtensionContext serviceExtensionContext) { - final String tokenUrl = serviceExtensionContext.getSetting(TOKEN_URL, null); - if (tokenUrl == null) { - throw new EdcException("Missing required setting: " + TOKEN_URL); - } - - final URI tokenUri = URI.create(tokenUrl); - - final OAuth2IdentityService oAuth2IdentityService = - new OAuth2IdentityService( - tokenUri, - okHttpClient, - serviceExtensionContext.getTypeManager(), - jwtDecoratorRegistry, - tokenGenerationService, - tokenValidationService); - - serviceExtensionContext.registerService(IdentityService.class, oAuth2IdentityService); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/OAuth2IdentityService.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/OAuth2IdentityService.java deleted file mode 100644 index b1c4dac0f..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/OAuth2IdentityService.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2020 - 2022 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * Fraunhofer Institute for Software and Systems Engineering - Improvements - * Microsoft Corporation - Use IDS Webhook address for JWT audience claim - * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - improvements - * Mercedes-Benz Tech Innovation GmbH - Refactoring - * - */ - -package net.catenax.edc.oauth2; - -import java.net.URI; -import java.util.LinkedHashMap; -import java.util.Objects; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import okhttp3.FormBody; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.iam.ClaimToken; -import org.eclipse.dataspaceconnector.spi.iam.IdentityService; -import org.eclipse.dataspaceconnector.spi.iam.TokenParameters; -import org.eclipse.dataspaceconnector.spi.iam.TokenRepresentation; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecoratorRegistry; -import org.eclipse.dataspaceconnector.spi.jwt.TokenGenerationService; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationService; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.eclipse.dataspaceconnector.spi.types.TypeManager; - -@RequiredArgsConstructor -public class OAuth2IdentityService implements IdentityService { - - private static final String GRANT_TYPE_CLIENT_CREDENTIALS = "client_credentials"; - private static final String CLIENT_ASSERTION_TYPE_JWT_BEARER = - "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"; - private static final String CONTENT_TYPE_APPLICATION_FORM_URLENCODED = - "application/x-www-form-urlencoded"; - private static final String CONTENT_TYPE = "Content-Type"; - private static final String RESOURCE = "resource"; - private static final String CLIENT_ASSERTION_TYPE = "client_assertion_type"; - private static final String GRANT_TYPE = "grant_type"; - private static final String CLIENT_ASSERTION = "client_assertion"; - private static final String SCOPE = "scope"; - - @NonNull private final URI tokenUrl; - @NonNull private final OkHttpClient httpClient; - @NonNull private final TypeManager typeManager; - @NonNull private final JwtDecoratorRegistry jwtDecoratorRegistry; - @NonNull private final TokenGenerationService tokenGenerationService; - @NonNull private final TokenValidationService tokenValidationService; - - @Override - public Result obtainClientCredentials( - @NonNull final TokenParameters tokenParameters) { - final Result jwtCreationResult = - tokenGenerationService.generate(jwtDecoratorRegistry.getAll().toArray(JwtDecorator[]::new)); - if (jwtCreationResult.failed()) { - return jwtCreationResult; - } - - final String assertion = jwtCreationResult.getContent().getToken(); - - final FormBody.Builder requestBodyBuilder = - new FormBody.Builder() - .add(CLIENT_ASSERTION_TYPE, CLIENT_ASSERTION_TYPE_JWT_BEARER) - .add(GRANT_TYPE, GRANT_TYPE_CLIENT_CREDENTIALS) - .add(CLIENT_ASSERTION, assertion) - .add(SCOPE, tokenParameters.getScope()) - .add(RESOURCE, tokenParameters.getAudience()); - - try { - final HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.get(tokenUrl)); - final Request request = - new Request.Builder() - .url(httpUrl) - .addHeader(CONTENT_TYPE, CONTENT_TYPE_APPLICATION_FORM_URLENCODED) - .post(requestBodyBuilder.build()) - .build(); - - try (final Response response = httpClient.newCall(request).execute()) { - try (final ResponseBody responseBody = response.body()) { - if (!response.isSuccessful()) { - final String message = responseBody == null ? "" : responseBody.string(); - return Result.failure(message); - } - - if (responseBody == null) { - return Result.failure(""); - } - - final String responsePayload = responseBody.string(); - - @SuppressWarnings("rawtypes") - LinkedHashMap deserialized = typeManager.readValue(responsePayload, LinkedHashMap.class); - - final String token = (String) deserialized.get("access_token"); - - final TokenRepresentation tokenRepresentation = - TokenRepresentation.Builder.newInstance().token(token).build(); - - return Result.success(tokenRepresentation); - } - } - } catch (final Exception exception) { - throw new EdcException(exception); - } - } - - @Override - public Result verifyJwtToken( - @NonNull final TokenRepresentation tokenRepresentation, final String audience) { - return tokenValidationService.validate(tokenRepresentation); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JsonWebKey.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JsonWebKey.java deleted file mode 100644 index 70712fbd7..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JsonWebKey.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * Mercedes-Benz Tech Innovation GmbH - refactoring - */ - -package net.catenax.edc.oauth2.jwk; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import lombok.Data; - -@Data -public class JsonWebKey { - @JsonProperty("kty") - private String kty; - - @JsonProperty("use") - private String use; - - @JsonProperty("kid") - private String kid; - - @JsonProperty("x5t") - private String x5t; - - @JsonProperty("n") - private String nn; - - @JsonProperty("e") - private String ee; - - @JsonProperty("x5c") - private List x5c; - - @JsonProperty("alg") - private String alg; -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JsonWebKeySet.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JsonWebKeySet.java deleted file mode 100644 index a4cc93716..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JsonWebKeySet.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Microsoft Corporation - initial API and implementation - * Mercedes-Benz Tech Innovation GmbH - refactoring - * - */ - -package net.catenax.edc.oauth2.jwk; - -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.List; -import lombok.Data; - -@Data -public class JsonWebKeySet { - @JsonProperty("keys") - private List keys; -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JwkPublicKeyResolver.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JwkPublicKeyResolver.java deleted file mode 100644 index 80b31255e..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/JwkPublicKeyResolver.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwk; - -import java.net.URI; -import java.security.PublicKey; -import java.time.Duration; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.iam.PublicKeyResolver; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.eclipse.dataspaceconnector.spi.types.TypeManager; -import org.jetbrains.annotations.Nullable; - -@RequiredArgsConstructor -public class JwkPublicKeyResolver implements PublicKeyResolver { - private final Object synchronizationMonitor = new Object(); - - @NonNull private final URI jsonWebKeySetUri; - - @NonNull private final OkHttpClient httpClient; - - @NonNull private final TypeManager typeManager; - - @NonNull private final Monitor monitor; - - @NonNull private final List jsonWebKeyReaders; - - @NonNull private final Duration interval; - - private final Map keys = new HashMap<>(); - private final AtomicReference executorServiceReference = - new AtomicReference<>(); - - public void start() { - synchronized (synchronizationMonitor) { - if (executorServiceReference.get() != null) { - return; - } - - final Result> result = synchronizeKeys(); - if (result.failed()) { - throw new EdcException( - String.format( - "Could not synchronize keys with identity provider (%s): %s", - jsonWebKeySetUri, result.getFailureDetail())); - } - - final ScheduledExecutorService scheduledExecutorService = - Executors.newSingleThreadScheduledExecutor(); - executorServiceReference.set(scheduledExecutorService); - - scheduledExecutorService.scheduleWithFixedDelay( - this::synchronizeKeys, interval.getSeconds(), interval.getSeconds(), TimeUnit.SECONDS); - } - } - - public void stop() { - synchronized (synchronizationMonitor) { - if (executorServiceReference.get() == null) { - return; - } - - final ScheduledExecutorService scheduledExecutorService = - executorServiceReference.getAndSet(null); - - if (scheduledExecutorService.isTerminated()) { - return; - } - - scheduledExecutorService.shutdownNow(); - } - } - - @Override - public @Nullable PublicKey resolveKey(final String keyId) { - if (keyId == null) { - return null; - } - - synchronized (synchronizationMonitor) { - return keys.get(keyId); - } - } - - protected Result> synchronizeKeys() { - final Result> fetchedKeys = fetchKeys(); - - if (fetchedKeys.succeeded()) { - synchronized (synchronizationMonitor) { - keys.clear(); - keys.putAll(fetchedKeys.getContent()); - } - } - - return fetchedKeys; - } - - protected Result> fetchKeys() { - try { - final HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.get(jsonWebKeySetUri)); - final Request request = new Request.Builder().url(httpUrl).get().build(); - try (final Response response = httpClient.newCall(request).execute()) { - if (response.code() == 200) { - final JsonWebKeySet jsonWebKeySet; - try (final ResponseBody body = response.body()) { - - if (body == null) { - final String message = - String.format( - "Unable to refresh identity provider (%s) keys. An empty response was returned.", - jsonWebKeySetUri); - monitor.severe(message); - return Result.failure(message); - } - - jsonWebKeySet = typeManager.readValue(body.string(), JsonWebKeySet.class); - } - - final List nonNullKeys = - Optional.ofNullable(jsonWebKeySet.getKeys()).orElseGet(Collections::emptyList); - if (nonNullKeys.isEmpty()) { - final String message = - String.format("No keys returned from identity provider (%s).", jsonWebKeySetUri); - monitor.warning(message); - return Result.failure(message); - } - - return Result.success(deserializeKeys(nonNullKeys)); - } else { - final String message = - String.format( - "Unable to refresh identity provider (%s) keys. Response code was: %s", - jsonWebKeySetUri, response.code()); - monitor.severe(message); - return Result.failure(message); - } - } - } catch (final Exception exception) { - final String message = - String.format( - "Error resolving identity (%s) provider keys: %s", - jsonWebKeySetUri, exception.getMessage()); - monitor.severe(message, exception); - return Result.failure(message); - } - } - - private Map deserializeKeys(final List jsonWebKeys) { - final Map keyMap = new HashMap<>(); - for (final JsonWebKey jsonWebKey : - Optional.ofNullable(jsonWebKeys).orElseGet(Collections::emptyList)) { - jsonWebKeyReaders.stream() - .filter(reader -> reader.canRead(jsonWebKey)) - .findFirst() - .flatMap(reader -> reader.read(jsonWebKey)) - .ifPresent(keyHolder -> keyMap.put(keyHolder.getKeyId(), keyHolder.getPublicKey())); - } - return keyMap; - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/RsaPublicKeyReader.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/RsaPublicKeyReader.java deleted file mode 100644 index c6098b70b..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/RsaPublicKeyReader.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwk; - -import java.math.BigInteger; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.spec.RSAPublicKeySpec; -import java.util.Base64; -import java.util.Optional; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; - -@RequiredArgsConstructor -public class RsaPublicKeyReader implements PublicKeyReader { - private static final String RSA = "RSA"; - private static final KeyFactory KEY_FACTORY; - - static { - try { - KEY_FACTORY = KeyFactory.getInstance(RSA); - } catch (final NoSuchAlgorithmException noSuchAlgorithmException) { - throw new RuntimeException(noSuchAlgorithmException.getMessage(), noSuchAlgorithmException); - } - } - - @NonNull private final Monitor monitor; - - @Override - public boolean canRead(final JsonWebKey jsonWebKey) { - return Optional.ofNullable(jsonWebKey).map(JsonWebKey::getKty).stream() - .allMatch(RSA::equalsIgnoreCase); - } - - @Override - public Optional read(final JsonWebKey jsonWebKey) { - try { - final BigInteger modulus = unsignedInt(jsonWebKey.getNn()); - final BigInteger exponent = unsignedInt(jsonWebKey.getEe()); - final RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, exponent); - final PublicKey publicKey = KEY_FACTORY.generatePublic(rsaPublicKeySpec); - final PublicKeyHolder publicKeyHolder = - PublicKeyHolder.builder().keyId(jsonWebKey.getKid()).publicKey(publicKey).build(); - - return Optional.of(publicKeyHolder); - } catch (final GeneralSecurityException generalSecurityException) { - monitor.severe( - "Error parsing identity provider public key, skipping. The kid is: " - + jsonWebKey.getKid()); - } - return Optional.empty(); - } - - private BigInteger unsignedInt(@NonNull final String value) { - return new BigInteger(1, Base64.getUrlDecoder().decode(value)); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/DapsJwtDecorator.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/DapsJwtDecorator.java deleted file mode 100644 index 3e7f90950..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/DapsJwtDecorator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2020, 2021 Microsoft Corporation - * - * 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: - * Amadeus - initial API and implementation - * - */ - -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.Map; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; - -public class DapsJwtDecorator implements JwtDecorator { - - @Override - public Map claims() { - return Map.of( - "@context", - "https://w3id.org/idsa/contexts/context.jsonld", - "@type", - "ids:DatRequestToken"); - } - - @Override - public Map headers() { - return Map.of(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/ExpJwtDecorator.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/ExpJwtDecorator.java deleted file mode 100644 index 4168f7e63..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/ExpJwtDecorator.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.time.Clock; -import java.time.Duration; -import java.util.Date; -import java.util.Map; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; - -@RequiredArgsConstructor -public class ExpJwtDecorator implements JwtDecorator { - @NonNull private final Clock clock; - - @NonNull private final Duration expiration; - - @Override - public Map claims() { - return Map.of( - JWTClaimNames.EXPIRATION_TIME, - Date.from(clock.instant().plusSeconds(expiration.toSeconds()))); - } - - @Override - public Map headers() { - return Map.of(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IdsAudJwtDecorator.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IdsAudJwtDecorator.java deleted file mode 100644 index 673ca7372..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IdsAudJwtDecorator.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.Collections; -import java.util.Map; -import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; - -@RequiredArgsConstructor -public class IdsAudJwtDecorator implements JwtDecorator { - - @Override - public Map claims() { - return Map.of(JWTClaimNames.AUDIENCE, Collections.singletonList("idsc:IDS_CONNECTORS_ALL")); - } - - @Override - public Map headers() { - return Map.of(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IssJwtDecorator.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IssJwtDecorator.java deleted file mode 100644 index 32303d14a..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IssJwtDecorator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.Map; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; - -@RequiredArgsConstructor -public class IssJwtDecorator implements JwtDecorator { - - @NonNull private final String clientId; - - @Override - public Map claims() { - return Map.of(JWTClaimNames.ISSUER, clientId); - } - - @Override - public Map headers() { - return Map.of(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JWTClaimNames.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JWTClaimNames.java deleted file mode 100644 index f1649b8c0..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JWTClaimNames.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -public final class JWTClaimNames { - public static final String ISSUER = "iss"; - public static final String SUBJECT = "sub"; - public static final String AUDIENCE = "aud"; - public static final String EXPIRATION_TIME = "exp"; - public static final String NOT_BEFORE = "nbf"; - public static final String ISSUED_AT = "iat"; - public static final String JWT_ID = "jti"; -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JtiJwtDecorator.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JtiJwtDecorator.java deleted file mode 100644 index 39590d1a6..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JtiJwtDecorator.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.Map; -import java.util.UUID; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; - -public class JtiJwtDecorator implements JwtDecorator { - - @Override - public Map claims() { - return Map.of(JWTClaimNames.JWT_ID, UUID.randomUUID().toString()); - } - - @Override - public Map headers() { - return Map.of(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JwtDecoratorExtension.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JwtDecoratorExtension.java deleted file mode 100644 index 510875a2c..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/JwtDecoratorExtension.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.time.Duration; -import java.util.Optional; -import java.util.stream.Stream; -import lombok.NonNull; -import lombok.Setter; -import org.eclipse.dataspaceconnector.iam.oauth2.spi.Oauth2JwtDecoratorRegistry; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.EdcSetting; -import org.eclipse.dataspaceconnector.spi.security.CertificateResolver; -import org.eclipse.dataspaceconnector.spi.system.*; - -@Provides(Oauth2JwtDecoratorRegistry.class) -@Requires(CertificateResolver.class) -public class JwtDecoratorExtension implements ServiceExtension { - - @EdcSetting - private static final String TOKEN_EXPIRATION_SECONDS = "edc.oauth.token.expiration.seconds"; - - private static final Duration DEFAULT_EXPIRATION = Duration.ofMinutes(5); - - @EdcSetting private static final String PUBLIC_KEY_ALIAS = "edc.oauth.public.key.alias"; - - @EdcSetting private static final String CLIENT_ID = "edc.oauth.client.id"; - - @Inject @Setter private CertificateResolver certificateResolver; - - @Override - public void initialize(@NonNull final ServiceExtensionContext serviceExtensionContext) { - final Oauth2JwtDecoratorRegistry oauth2JwtDecoratorRegistry = - new Oauth2JwtDecoratorRegistryRegistryImpl(); - - Stream.of( - audJwtDecorator(), - expJwtDecorator(serviceExtensionContext), - iatJwtDecorator(serviceExtensionContext), - issJwtDecorator(serviceExtensionContext), - jtiJwtDecorator(), - subJwtDecorator(serviceExtensionContext), - x5tJwtDecorator(serviceExtensionContext, certificateResolver), - dapsJwtDecorator()) - .forEach(oauth2JwtDecoratorRegistry::register); - - serviceExtensionContext.registerService( - Oauth2JwtDecoratorRegistry.class, oauth2JwtDecoratorRegistry); - } - - private DapsJwtDecorator dapsJwtDecorator() { - return new DapsJwtDecorator(); - } - - private IdsAudJwtDecorator audJwtDecorator() { - return new IdsAudJwtDecorator(); - } - - private ExpJwtDecorator expJwtDecorator( - @NonNull final ServiceExtensionContext serviceExtensionContext) { - final Duration expiration = - Duration.ofSeconds( - serviceExtensionContext - .getConfig() - .getLong(TOKEN_EXPIRATION_SECONDS, DEFAULT_EXPIRATION.toSeconds())); - - return new ExpJwtDecorator(serviceExtensionContext.getClock(), expiration); - } - - private IatJwtDecorator iatJwtDecorator( - @NonNull final ServiceExtensionContext serviceExtensionContext) { - return new IatJwtDecorator(serviceExtensionContext.getClock()); - } - - private IssJwtDecorator issJwtDecorator( - @NonNull final ServiceExtensionContext serviceExtensionContext) { - final String issuer = serviceExtensionContext.getConfig().getString(CLIENT_ID); - - return new IssJwtDecorator(issuer); - } - - private JtiJwtDecorator jtiJwtDecorator() { - return new JtiJwtDecorator(); - } - - private SubJwtDecorator subJwtDecorator( - @NonNull final ServiceExtensionContext serviceExtensionContext) { - final String subject = serviceExtensionContext.getConfig().getString(CLIENT_ID); - - return new SubJwtDecorator(subject); - } - - private X5tJwtDecorator x5tJwtDecorator( - @NonNull final ServiceExtensionContext serviceExtensionContext, - @NonNull final CertificateResolver certificateResolver) { - final String publicKeyAlias = serviceExtensionContext.getSetting(PUBLIC_KEY_ALIAS, null); - if (publicKeyAlias == null) { - throw new EdcException("Missing required setting: " + PUBLIC_KEY_ALIAS); - } - - final X509Certificate certificate = - Optional.ofNullable(certificateResolver.resolveCertificate(publicKeyAlias)) - .orElseThrow( - () -> - new EdcException( - String.format("Public certificate not found: %s", publicKeyAlias))); - - final byte[] encodedCertificate; - try { - encodedCertificate = certificate.getEncoded(); - } catch (final CertificateEncodingException certificateEncodingException) { - throw new EdcException( - "Failed to encode certificate: " + certificateEncodingException.getMessage(), - certificateEncodingException); - } - - return new X5tJwtDecorator(encodedCertificate); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/Oauth2JwtDecoratorRegistryRegistryImpl.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/Oauth2JwtDecoratorRegistryRegistryImpl.java deleted file mode 100644 index b57d9737d..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/Oauth2JwtDecoratorRegistryRegistryImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2022 Amadeus - * - * 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: - * Amadeus - Initial implementation - * - */ - -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import org.eclipse.dataspaceconnector.iam.oauth2.spi.Oauth2JwtDecoratorRegistry; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; - -/** Registry for Oauth2 JWT decorators. */ -public class Oauth2JwtDecoratorRegistryRegistryImpl implements Oauth2JwtDecoratorRegistry { - private final List list = new CopyOnWriteArrayList<>(); - - @Override - public void register(final JwtDecorator decorator) { - list.add(decorator); - } - - @Override - public void unregister(final JwtDecorator decorator) { - list.remove(decorator); - } - - @Override - public Collection getAll() { - return new ArrayList<>(list); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/X5tJwtDecorator.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/X5tJwtDecorator.java deleted file mode 100644 index 9b8903936..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/X5tJwtDecorator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import com.nimbusds.jose.util.Base64URL; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Base64; -import java.util.Map; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; - -@RequiredArgsConstructor -public class X5tJwtDecorator implements JwtDecorator { - private static final String SHA_1 = "SHA-1"; - - @NonNull private final byte[] encodedCertificate; - - public static String sha1Base64Fingerprint(final byte[] bytes) { - try { - final MessageDigest messageDigest = MessageDigest.getInstance(SHA_1); - messageDigest.update(bytes); - return Base64.getEncoder().encodeToString(messageDigest.digest()); - } catch (NoSuchAlgorithmException e) { - throw new EdcException(e); - } - } - - @Override - public Map claims() { - return Map.of(); - } - - @Override - public Map headers() { - return Map.of("x5t", new Base64URL(sha1Base64Fingerprint(encodedCertificate))); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/generator/JwtTokenGenerationService.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/generator/JwtTokenGenerationService.java deleted file mode 100644 index b4c4f3a27..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/generator/JwtTokenGenerationService.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2022 Amadeus - * - * 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: - * Amadeus - initial API and implementation - * Microsoft Corporation - Simplified token representation - * Mercedes Benz Tech Innovation - Rename class, add Type-Safety - * - */ - -package net.catenax.edc.oauth2.jwt.generator; - -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWSAlgorithm; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSSigner; -import com.nimbusds.jose.crypto.ECDSASigner; -import com.nimbusds.jose.crypto.RSASSASigner; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; -import java.security.PrivateKey; -import java.security.interfaces.ECPrivateKey; -import java.util.Map.Entry; -import lombok.NonNull; -import lombok.SneakyThrows; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.iam.TokenRepresentation; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; -import org.eclipse.dataspaceconnector.spi.jwt.TokenGenerationService; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.jetbrains.annotations.NotNull; - -public class JwtTokenGenerationService implements TokenGenerationService { - private static final String KEY_ALGO_RSA = "RSA"; - private static final String KEY_ALGO_EC = "EC"; - - private final JWSAlgorithm jwsAlgorithm; - private final JWSSigner jwsSigner; - - public JwtTokenGenerationService(@NonNull final PrivateKey privateKey) { - this.jwsAlgorithm = getJWSAlgorithm(privateKey.getAlgorithm()); - this.jwsSigner = getJWSSigner(privateKey.getAlgorithm(), privateKey); - } - - @SneakyThrows - private static JWSSigner getJWSSigner( - @NonNull final String algorithm, @NonNull final PrivateKey privateKey) { - if (algorithm.equals(KEY_ALGO_EC)) { - return new ECDSASigner((ECPrivateKey) privateKey); - } - - if (algorithm.equals(KEY_ALGO_RSA)) { - return new RSASSASigner(privateKey); - } - - throw new EdcException("Unsupported key algorithm: " + algorithm); - } - - private static JWSAlgorithm getJWSAlgorithm(@NonNull final String algorithm) { - if (algorithm.equals(KEY_ALGO_EC)) { - return JWSAlgorithm.ES256; - } - - if (algorithm.equals(KEY_ALGO_RSA)) { - return JWSAlgorithm.RS256; - } - - throw new EdcException("Unsupported key algorithm: " + algorithm); - } - - @Override - public Result generate(@NotNull @NonNull final JwtDecorator... decorators) { - - final JWSHeader.Builder headerBuilder = new JWSHeader.Builder(jwsAlgorithm); - final JWTClaimsSet.Builder claimsBuilder = new JWTClaimsSet.Builder(); - - for (JwtDecorator decorator : decorators) { - for (Entry claim : decorator.claims().entrySet()) { - claimsBuilder.claim(claim.getKey(), claim.getValue()); - } - headerBuilder.customParams(decorator.headers()); - } - - final JWTClaimsSet jwtClaimSet = claimsBuilder.build(); - - final SignedJWT signedJwt = new SignedJWT(headerBuilder.build(), jwtClaimSet); - try { - signedJwt.sign(jwsSigner); - } catch (final JOSEException joseException) { - return Result.failure("Failed to sign token"); - } - - return Result.success( - TokenRepresentation.Builder.newInstance().token(signedJwt.serialize()).build()); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/generator/JwtTokenGenerationServiceExtension.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/generator/JwtTokenGenerationServiceExtension.java deleted file mode 100644 index 2d239045b..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/generator/JwtTokenGenerationServiceExtension.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.generator; - -import java.security.PrivateKey; -import lombok.NonNull; -import lombok.Setter; -import org.eclipse.dataspaceconnector.spi.EdcSetting; -import org.eclipse.dataspaceconnector.spi.jwt.TokenGenerationService; -import org.eclipse.dataspaceconnector.spi.security.PrivateKeyResolver; -import org.eclipse.dataspaceconnector.spi.system.*; - -@Provides(TokenGenerationService.class) -@Requires(PrivateKeyResolver.class) -public class JwtTokenGenerationServiceExtension implements ServiceExtension { - - @EdcSetting private static final String PRIVATE_KEY_ALIAS = "edc.oauth.private.key.alias"; - - @Inject @Setter private PrivateKeyResolver privateKeyResolver; - - @Override - public void initialize(@NonNull final ServiceExtensionContext serviceExtensionContext) { - final PrivateKey privateKey = privateKey(serviceExtensionContext); - final TokenGenerationService tokenGenerationService = new JwtTokenGenerationService(privateKey); - - serviceExtensionContext.registerService(TokenGenerationService.class, tokenGenerationService); - } - - private PrivateKey privateKey(final ServiceExtensionContext serviceExtensionContext) { - final String privateKeyAlias = serviceExtensionContext.getConfig().getString(PRIVATE_KEY_ALIAS); - return privateKeyResolver.resolvePrivateKey(privateKeyAlias, PrivateKey.class); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/AudValidationRule.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/AudValidationRule.java deleted file mode 100644 index 3f46930ff..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/AudValidationRule.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.validation; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import lombok.SneakyThrows; -import net.catenax.edc.oauth2.jwt.decorator.JWTClaimNames; -import org.eclipse.dataspaceconnector.spi.iam.ClaimToken; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationRule; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -@RequiredArgsConstructor -public class AudValidationRule implements TokenValidationRule { - @NonNull private final String audience; - - @NonNull private final Monitor monitor; - - /** - * Validates the JWT by checking the audience, nbf, and expiration. Accessible for testing. - * - * @param toVerify The jwt including the claims. - * @param additional No more additional information needed for this validation, can be null. - */ - @Override - @SneakyThrows - public Result checkRule( - @NotNull ClaimToken toVerify, @Nullable Map additional) { - final List errors = new ArrayList<>(); - - final Object claim = toVerify.getClaims().get(JWTClaimNames.AUDIENCE); - if (!(claim instanceof List)) { - errors.add("Audience claim is not a list"); - } else { - final List audiences = (List) claim; - audiences.forEach(a -> monitor.info("RECEIVED DAP AUDIENCE TO VERIFY: " + a)); - - if (audiences.isEmpty()) { - errors.add("Required audience (aud) claim is missing in token"); - } else if (!audiences.contains(audience)) { - errors.add("Token audience (aud) claim did not contain connector audience: " + audience); - } - } - - if (errors.isEmpty()) { - return Result.success(); - } else { - return Result.failure(errors); - } - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/ExpValidationRule.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/ExpValidationRule.java deleted file mode 100644 index 36abd84bf..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/ExpValidationRule.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.validation; - -import static java.time.ZoneOffset.UTC; - -import java.time.Clock; -import java.time.Instant; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import net.catenax.edc.oauth2.jwt.decorator.JWTClaimNames; -import org.eclipse.dataspaceconnector.spi.iam.ClaimToken; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationRule; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -@RequiredArgsConstructor -public class ExpValidationRule implements TokenValidationRule { - - @NonNull private final Clock clock; - - /** - * Validates the JWT by checking the audience, nbf, and expiration. Accessible for testing. - * - * @param toVerify The jwt including the claims. - * @param additional No more additional information needed for this validation, can be null. - */ - @Override - public Result checkRule( - @NotNull ClaimToken toVerify, @Nullable Map additional) { - final List errors = new ArrayList<>(); - - final Instant now = clock.instant(); - final Object claim = toVerify.getClaims().get(JWTClaimNames.EXPIRATION_TIME); - if (!(claim instanceof Date)) { - errors.add("Required expiration (exp) claim is missing in token"); - } else { - final Date expires = (Date) claim; - if (now.isAfter(convertToUtcTime(expires))) { - errors.add("Token has expired (exp)"); - } - } - - if (errors.isEmpty()) { - return Result.success(); - } else { - return Result.failure(errors); - } - } - - private static Instant convertToUtcTime(Date date) { - return ZonedDateTime.ofInstant(date.toInstant(), UTC).toInstant(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/IatValidationRule.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/IatValidationRule.java deleted file mode 100644 index a5185e559..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/IatValidationRule.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.validation; - -import static java.time.ZoneOffset.UTC; - -import java.time.Clock; -import java.time.Instant; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import net.catenax.edc.oauth2.jwt.decorator.JWTClaimNames; -import org.eclipse.dataspaceconnector.spi.iam.ClaimToken; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationRule; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -@RequiredArgsConstructor -public class IatValidationRule implements TokenValidationRule { - @NonNull private final Clock clock; - - /** - * Validates the JWT by checking the audience, nbf, and expiration. Accessible for testing. - * - * @param toVerify The jwt including the claims. - * @param additional No more additional information needed for this validation, can be null. - */ - @Override - public Result checkRule( - @NotNull ClaimToken toVerify, @Nullable Map additional) { - List errors = new ArrayList<>(); - - Instant now = clock.instant(); - final Object issuedAtClaim = toVerify.getClaims().get(JWTClaimNames.ISSUED_AT); - if (!(issuedAtClaim instanceof Date)) { - errors.add("Issued at (iat) claim is missing in token"); - } else { - final Object expirationTimeClaim = toVerify.getClaims().get(JWTClaimNames.EXPIRATION_TIME); - if (expirationTimeClaim instanceof Date) { - Date expirationTime = (Date) expirationTimeClaim; - Date issuedAt = (Date) issuedAtClaim; - if (issuedAt.toInstant().isAfter(expirationTime.toInstant())) { - errors.add("Issued at (iat) claim is after expiration time (exp) claim in token"); - } else if (now.isBefore(convertToUtcTime(issuedAt))) { - errors.add("Current date/time before issued at (iat) claim in token"); - } - } - } - - if (errors.isEmpty()) { - return Result.success(); - } else { - return Result.failure(errors); - } - } - - private static Instant convertToUtcTime(Date date) { - return ZonedDateTime.ofInstant(date.toInstant(), UTC).toInstant(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/IdsValidationRule.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/IdsValidationRule.java deleted file mode 100644 index 6a61cd6bf..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/IdsValidationRule.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2022 Fraunhofer Institute for Software and Systems Engineering - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - * - * Contributors: - * Fraunhofer Institute for Software and Systems Engineering - Initial Implementation - * - */ - -package net.catenax.edc.oauth2.jwt.validation; - -import java.util.Map; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.iam.ClaimToken; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationRule; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class IdsValidationRule implements TokenValidationRule { - private final boolean validateReferring; - - public IdsValidationRule(boolean validateReferring) { - this.validateReferring = validateReferring; - } - - /** Validates the JWT by checking extended IDS rules. */ - @Override - public Result checkRule( - @NotNull ClaimToken toVerify, @Nullable Map additional) { - if (additional != null) { - var issuerConnector = additional.get("issuerConnector"); - if (issuerConnector == null) { - return Result.failure("Required issuerConnector is missing in message"); - } - - String securityProfile = null; - if (additional.containsKey("securityProfile")) { - securityProfile = additional.get("securityProfile").toString(); - } - - return verifyTokenIds(additional, issuerConnector.toString(), securityProfile); - - } else { - throw new EdcException("Missing required additional information for IDS token validation"); - } - } - - private Result verifyTokenIds( - Map claims, String issuerConnector, @Nullable String securityProfile) { - - // referringConnector (DAT, optional) vs issuerConnector (Message-Header, - // mandatory) - var referringConnector = claims.get("referringConnector"); - - if (validateReferring && !issuerConnector.equals(referringConnector)) { - return Result.failure("referingConnector in token does not match issuerConnector in message"); - } - - // securityProfile (DAT, mandatory) vs securityProfile (Message-Payload, - // optional) - try { - var tokenSecurityProfile = claims.get("securityProfile"); - - if (securityProfile != null && !securityProfile.equals(tokenSecurityProfile)) { - return Result.failure("securityProfile in token does not match securityProfile in payload"); - } - } catch (Exception e) { - // Nothing to do, payload mostly no connector instance - } - - return Result.success(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/JwtValidationExtension.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/JwtValidationExtension.java deleted file mode 100644 index bb1e7b1af..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/JwtValidationExtension.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.validation; - -import java.net.URI; -import java.time.Clock; -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Stream; -import lombok.NonNull; -import lombok.Setter; -import net.catenax.edc.oauth2.jwk.JwkPublicKeyResolver; -import net.catenax.edc.oauth2.jwk.PublicKeyReader; -import net.catenax.edc.oauth2.jwk.RsaPublicKeyReader; -import okhttp3.OkHttpClient; -import org.eclipse.dataspaceconnector.iam.oauth2.spi.Oauth2ValidationRulesRegistry; -import org.eclipse.dataspaceconnector.spi.EdcSetting; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationService; -import org.eclipse.dataspaceconnector.spi.system.*; - -@Provides(TokenValidationService.class) -@Requires({OkHttpClient.class, Clock.class}) -public class JwtValidationExtension implements ServiceExtension { - - @EdcSetting private static final String EDC_IDS_ENDPOINT_AUDIENCE = "edc.ids.endpoint.audience"; - @EdcSetting private static final String NOT_BEFORE_LEEWAY = "edc.oauth.validation.nbf.leeway"; - private static final Duration DEFAULT_NOT_BEFORE_LEEWAY = Duration.ofSeconds(10); - - @EdcSetting - private static final String PROVIDER_JWKS_REFRESH = - "edc.oauth.provider.jwks.refresh"; // in minutes - - private static final Duration DEFAULT_PROVIDER_JWKS_REFRESH = Duration.ofMinutes(5); - - @EdcSetting private static final String PROVIDER_JWKS_URL = "edc.oauth.provider.jwks.url"; - private static final String DEFAULT_JWKS_URL = "http://localhost/empty_jwks_url"; - - @EdcSetting - public static final String EDC_IDS_VALIDATION_REFERRINGCONNECTOR = - "edc.ids.validation.referringconnector"; - - public static final boolean DEFAULT_EDC_IDS_VALIDATION_REFERRINGCONNECTOR = false; - - @Inject @Setter private OkHttpClient okHttpClient; - - @Inject @Setter private Clock clock; - - private JwkPublicKeyResolver jwkPublicKeyResolver; - - @Override - public void initialize(@NonNull final ServiceExtensionContext serviceExtensionContext) { - - final Oauth2ValidationRulesRegistry oauth2ValidationRulesRegistry = - oauth2ValidationRulesRegistry(serviceExtensionContext); - - this.jwkPublicKeyResolver = jwkPublicKeyResolver(serviceExtensionContext); - - final TokenValidationService tokenValidationService = - new TokenValidationServiceImpl(jwkPublicKeyResolver, oauth2ValidationRulesRegistry); - - serviceExtensionContext.registerService(TokenValidationService.class, tokenValidationService); - } - - @Override - public void start() { - Optional.ofNullable(jwkPublicKeyResolver).ifPresent(JwkPublicKeyResolver::start); - } - - @Override - public void shutdown() { - Optional.ofNullable(jwkPublicKeyResolver).ifPresent(JwkPublicKeyResolver::stop); - } - - private Oauth2ValidationRulesRegistry oauth2ValidationRulesRegistry( - final ServiceExtensionContext serviceExtensionContext) { - final Oauth2ValidationRulesRegistry oauth2ValidationRulesRegistry = - new Oauth2ValidationRulesRegistryImpl(); - Stream.of( - audValidationRule(serviceExtensionContext), - expValidationRule(), - iatValidationRule(), - nbfValidationRule(serviceExtensionContext), - idsValidationRule(serviceExtensionContext)) - .forEach(oauth2ValidationRulesRegistry::addRule); - - return oauth2ValidationRulesRegistry; - } - - private JwkPublicKeyResolver jwkPublicKeyResolver( - final ServiceExtensionContext serviceExtensionContext) { - final URI jsonWebKeySetUri = - URI.create( - serviceExtensionContext.getConfig().getString(PROVIDER_JWKS_URL, DEFAULT_JWKS_URL)); - final Duration refreshInterval = - Duration.ofMinutes( - serviceExtensionContext - .getConfig() - .getLong(PROVIDER_JWKS_REFRESH, DEFAULT_PROVIDER_JWKS_REFRESH.toMinutes())); - - final RsaPublicKeyReader rsaPublicKeyReader = - new RsaPublicKeyReader(serviceExtensionContext.getMonitor()); - final List publicKeyReaders = Collections.singletonList(rsaPublicKeyReader); - - return new JwkPublicKeyResolver( - jsonWebKeySetUri, - okHttpClient, - serviceExtensionContext.getTypeManager(), - serviceExtensionContext.getMonitor(), - publicKeyReaders, - refreshInterval); - } - - private AudValidationRule audValidationRule( - final ServiceExtensionContext serviceExtensionContext) { - final String audience = - Objects.requireNonNull( - serviceExtensionContext.getConfig().getString(EDC_IDS_ENDPOINT_AUDIENCE)); - - return new AudValidationRule(audience, serviceExtensionContext.getMonitor()); - } - - private ExpValidationRule expValidationRule() { - return new ExpValidationRule(clock); - } - - private IatValidationRule iatValidationRule() { - return new IatValidationRule(clock); - } - - private NbfValidationRule nbfValidationRule( - final ServiceExtensionContext serviceExtensionContext) { - final Duration nbfLeeway = - Duration.ofSeconds( - serviceExtensionContext - .getConfig() - .getLong(NOT_BEFORE_LEEWAY, DEFAULT_NOT_BEFORE_LEEWAY.toSeconds())); - - return new NbfValidationRule(nbfLeeway, clock); - } - - private IdsValidationRule idsValidationRule( - final ServiceExtensionContext serviceExtensionContext) { - boolean validateReferring = - serviceExtensionContext.getSetting( - EDC_IDS_VALIDATION_REFERRINGCONNECTOR, DEFAULT_EDC_IDS_VALIDATION_REFERRINGCONNECTOR); - - return new IdsValidationRule(validateReferring); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/NbfValidationRule.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/NbfValidationRule.java deleted file mode 100644 index 88672b8cb..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/NbfValidationRule.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwt.validation; - -import static java.time.ZoneOffset.UTC; - -import java.time.Clock; -import java.time.Duration; -import java.time.Instant; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import net.catenax.edc.oauth2.jwt.decorator.JWTClaimNames; -import org.eclipse.dataspaceconnector.spi.iam.ClaimToken; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationRule; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -@RequiredArgsConstructor -public class NbfValidationRule implements TokenValidationRule { - @NonNull private final Duration notBeforeValidationLeeway; - - @NonNull private final Clock clock; - - /** - * Validates the JWT by checking the audience, nbf, and expiration. Accessible for testing. - * - * @param toVerify The jwt including the claims. - * @param additional No more additional information needed for this validation, can be null. - */ - @Override - public Result checkRule( - @NotNull ClaimToken toVerify, @Nullable Map additional) { - final List errors = new ArrayList<>(); - - final Instant now = clock.instant(); - final Instant leewayNow = now.plusSeconds(notBeforeValidationLeeway.toSeconds()); - - final Object claim = toVerify.getClaims().get(JWTClaimNames.NOT_BEFORE); - if (!(claim instanceof Date)) { - errors.add("Required not before (nbf) claim is missing in token"); - } else { - final Date notBefore = (Date) claim; - if (leewayNow.isBefore(dateToInstant(notBefore))) { - errors.add("Current date/time with leeway before the not before (nbf) claim in token"); - } - } - - if (errors.isEmpty()) { - return Result.success(); - } else { - return Result.failure(errors); - } - } - - private static Instant dateToInstant(final Date date) { - return ZonedDateTime.ofInstant(date.toInstant(), UTC).toInstant(); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/Oauth2ValidationRulesRegistryImpl.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/Oauth2ValidationRulesRegistryImpl.java deleted file mode 100644 index b779a96cc..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/Oauth2ValidationRulesRegistryImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2022 Amadeus - * - * 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: - * Amadeus - Initial implementation - * - */ - -package net.catenax.edc.oauth2.jwt.validation; - -import java.util.ArrayList; -import java.util.List; -import lombok.NoArgsConstructor; -import org.eclipse.dataspaceconnector.iam.oauth2.spi.Oauth2ValidationRulesRegistry; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationRule; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationRulesRegistry; - -/** Registry for Oauth2 validation rules. */ -@NoArgsConstructor -public class Oauth2ValidationRulesRegistryImpl - implements Oauth2ValidationRulesRegistry, TokenValidationRulesRegistry { - - private final List rules = new ArrayList<>(); - - @Override - public void addRule(TokenValidationRule rule) { - rules.add(rule); - } - - @Override - public List getRules() { - return new ArrayList<>(rules); - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/TokenValidationServiceImpl.java b/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/TokenValidationServiceImpl.java deleted file mode 100644 index 6a7e4e17f..000000000 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/validation/TokenValidationServiceImpl.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2022 Amadeus - * - * 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: - * Amadeus - initial API and implementation - * - */ - -package net.catenax.edc.oauth2.jwt.validation; - -import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.JWSHeader; -import com.nimbusds.jose.JWSVerifier; -import com.nimbusds.jose.crypto.factories.DefaultJWSVerifierFactory; -import com.nimbusds.jwt.JWTClaimsSet; -import com.nimbusds.jwt.SignedJWT; -import java.security.PublicKey; -import java.text.ParseException; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.iam.ClaimToken; -import org.eclipse.dataspaceconnector.spi.iam.PublicKeyResolver; -import org.eclipse.dataspaceconnector.spi.iam.TokenRepresentation; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationRulesRegistry; -import org.eclipse.dataspaceconnector.spi.jwt.TokenValidationService; -import org.eclipse.dataspaceconnector.spi.result.Result; - -@RequiredArgsConstructor -public class TokenValidationServiceImpl implements TokenValidationService { - - @NonNull private final PublicKeyResolver publicKeyResolver; - - @NonNull private final TokenValidationRulesRegistry rulesRegistry; - - @Override - public Result validate(@NonNull final TokenRepresentation tokenRepresentation) { - final String token = tokenRepresentation.getToken(); - final Map additional = tokenRepresentation.getAdditional(); - final JWTClaimsSet claimsSet; - try { - final SignedJWT signedJwt = SignedJWT.parse(token); - final String publicKeyId = signedJwt.getHeader().getKeyID(); - final Result verifierCreationResult = - createVerifier(signedJwt.getHeader(), publicKeyId); - - if (verifierCreationResult.failed()) { - return Result.failure(verifierCreationResult.getFailureMessages()); - } - - if (!signedJwt.verify(verifierCreationResult.getContent())) { - return Result.failure("Token verification failed"); - } - - claimsSet = signedJwt.getJWTClaimsSet(); - var claimToken = ClaimToken.Builder.newInstance().claims(claimsSet.getClaims()).build(); - - final List errors = - rulesRegistry.getRules().stream() - .map(r -> r.checkRule(claimToken, additional)) - .filter(Result::failed) - .map(Result::getFailureMessages) - .flatMap(Collection::stream) - .collect(Collectors.toList()); - - if (!errors.isEmpty()) { - return Result.failure(errors); - } - - final ClaimToken.Builder tokenBuilder = ClaimToken.Builder.newInstance(); - - claimsSet.getClaims().entrySet().stream() - .map(entry -> Map.entry(entry.getKey(), Objects.toString(entry.getValue()))) - .filter(entry -> entry.getValue() != null) - .forEach(entry -> tokenBuilder.claim(entry.getKey(), entry.getValue())); - - return Result.success(tokenBuilder.build()); - - } catch (final JOSEException e) { - return Result.failure(e.getMessage()); - } catch (final ParseException e) { - return Result.failure("Failed to decode token"); - } - } - - private Result createVerifier(final JWSHeader header, final String publicKeyId) { - final PublicKey publicKey = publicKeyResolver.resolveKey(publicKeyId); - if (publicKey == null) { - return Result.failure("Failed to resolve public key with id: " + publicKeyId); - } - try { - return Result.success(new DefaultJWSVerifierFactory().createJWSVerifier(header, publicKey)); - } catch (final JOSEException e) { - return Result.failure("Failed to create verifier"); - } - } -} diff --git a/edc-extensions/cx-oauth2/src/main/java/org/eclipse/tractusx/edc/oauth2/CXOAuth2Extension.java b/edc-extensions/cx-oauth2/src/main/java/org/eclipse/tractusx/edc/oauth2/CXOAuth2Extension.java new file mode 100644 index 000000000..4b5bffc74 --- /dev/null +++ b/edc-extensions/cx-oauth2/src/main/java/org/eclipse/tractusx/edc/oauth2/CXOAuth2Extension.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.oauth2; + +import java.util.Map; +import org.eclipse.edc.iam.oauth2.spi.CredentialsRequestAdditionalParametersProvider; +import org.eclipse.edc.runtime.metamodel.annotation.Provider; +import org.eclipse.edc.spi.system.ServiceExtension; + +public class CXOAuth2Extension implements ServiceExtension { + + @Override + public String name() { + return "CX OAuth2"; + } + + @Provider + public CredentialsRequestAdditionalParametersProvider + credentialsRequestAdditionalParametersProvider() { + return tokenParameters -> Map.of("resource", tokenParameters.getAudience()); + } +} diff --git a/edc-extensions/cx-oauth2/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension b/edc-extensions/cx-oauth2/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension deleted file mode 100644 index 0303255e4..000000000 --- a/edc-extensions/cx-oauth2/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: -# Mercedes-Benz Tech Innovation GmbH - Initial ServiceExtension file -# -# -net.catenax.edc.oauth2.jwt.decorator.JwtDecoratorExtension -net.catenax.edc.oauth2.jwt.validation.JwtValidationExtension -net.catenax.edc.oauth2.jwt.generator.JwtTokenGenerationServiceExtension -net.catenax.edc.oauth2.OAuth2Extension diff --git a/edc-extensions/cx-oauth2/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/cx-oauth2/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..2e60a45f0 --- /dev/null +++ b/edc-extensions/cx-oauth2/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,21 @@ +# +# Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2022 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +org.eclipse.tractusx.edc.oauth2.CXOAuth2Extension diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwk/JwkPublicKeyResolverTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwk/JwkPublicKeyResolverTest.java deleted file mode 100644 index 8d90b5000..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwk/JwkPublicKeyResolverTest.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.oauth2.jwk; - -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; - -import java.net.URI; -import java.security.PublicKey; -import java.time.Duration; -import java.util.Collections; -import java.util.Optional; -import okhttp3.Call; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.types.TypeManager; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -class JwkPublicKeyResolverTest { - - private static final String JWKS_KEY_ID = "e600c72b-125a-4b30-86a5-9697af62f2a1"; - private static final String JWKS_PUBLIC_KEY = - "MIICujCCAaKgAwIBAgIECI8fsTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExR0ZXN0LWFsZXgucmVhY2g1Lm5ldDAeFw0yMDA3MjkwOTM0MjlaFw0yMjAyMTcxNDIwMzNaMB8xHTAbBgNVBAMTFHRlc3QtYWxleC5yZWFjaDUubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlzRszUeQ4WiSqvmYxMP10ngm8ALIoUwMH7Oa8vrZgD5pqalPjetPAxeVcAv2gTyDlOwtB0fGvlQo6n78pd9pTbgrzUjhmFuYN6OCfT6eN/2wu0LmwryFS2mbh7/1DTiKd2tZaRalskPECXTKkeks85HVqanB0860BYlGvQvfgrvhCWXXFJJeXvNwYNFYdDdrFQhoeOAEvRDKg9DdHZf6XzSR6Qk3w51FKn2b7imen/G52itD/kIen1hqqB2Jwt9SWyX5MSGySY2QwC18F6Dfs8L+t0mwCo6grGW9264Z5vlO0PWssEqGIX/ez6nk1ZdHXhoXwJ0W+6QzeQlUN8jNoQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAETbMWro4HI4ZuqtnjMZrgEOpx6WhAtxpMx5XFPVWbdp/DpPySotoWbbD6qCtYc34E+ec7mH7aHVap+Gl2IyeSHTht4FXfF9q/1Oj/fis/4DDi1iq00rJsU18D71mZ9FGWCWlO1nhW1KSTGbRJ3E0wSrNabcvaXcwEHokR3zm+xfRWjtbrq2hQ19R16xyOLVy4zrF95QxP4UN+Cvm8nmYur6bSqv+gCMvDsl+O/gtRHGgpUukHEJwnee1R3+1aIv+9zOF3HaaUC5neOLBFITGmeXgi8G2IhbG+JoXh/GUkb66TZUlUAM3qXYNL9Nf+2MQ7nAPTXcxlmImFUUrnv0c3"; - private static final String JWKS = - String.format( - "{" - + " \"keys\": [" - + " {" - + " \"kty\": \"RSA\"," - + " \"e\": \"AQAB\"," - + " \"x5t\": \"NjU3NDI5ZTZhODU0YjQzMGFiYzkwNGNkZDkwNmZkMzZmOWEzNWVmMQ\"," - + " \"use\": \"sig\"," - + " \"kid\": \"%s\"," - + " \"x5c\": [" - + " \"%s\"" - + " ]," - + " \"alg\": \"RS256\"," - + " \"n\": \"lzRszUeQ4WiSqvmYxMP10ngm8ALIoUwMH7Oa8vrZgD5pqalPjetPAxeVcAv2gTyDlOwtB0fGvlQo6n78pd9pTbgrzUjhmFuYN6OCfT6eN_2wu0LmwryFS2mbh7_1DTiKd2tZaRalskPECXTKkeks85HVqanB0860BYlGvQvfgrvhCWXXFJJeXvNwYNFYdDdrFQhoeOAEvRDKg9DdHZf6XzSR6Qk3w51FKn2b7imen_G52itD_kIen1hqqB2Jwt9SWyX5MSGySY2QwC18F6Dfs8L-t0mwCo6grGW9264Z5vlO0PWssEqGIX_ez6nk1ZdHXhoXwJ0W-6QzeQlUN8jNoQ\"" - + " }" - + " ]" - + "}", - JWKS_KEY_ID, JWKS_PUBLIC_KEY); - - private static final URI JWKS_URI = URI.create("https://localhost/.well-known/jwks.json"); - private static final Duration INTERVAL = Duration.ofSeconds(1); - - private JwkPublicKeyResolver jwkPublicKeyResolver; - - // mocks - private OkHttpClient httpClient; - private Monitor monitor; - private PublicKeyReader publicKeyReader; - - @BeforeEach - void setUp() { - httpClient = mock(OkHttpClient.class); - monitor = mock(Monitor.class); - publicKeyReader = mock(PublicKeyReader.class); - - Mockito.when(publicKeyReader.canRead(any(JsonWebKey.class))).thenReturn(true); - Mockito.when(publicKeyReader.read(any(JsonWebKey.class))) - .thenAnswer( - (i) -> { - final JsonWebKey jsonWebKey = i.getArgument(0); - - if (jsonWebKey.getKid().equals(JWKS_KEY_ID)) { - final PublicKeyHolder publicKeyHolder = - PublicKeyHolder.builder() - .keyId(JWKS_KEY_ID) - .publicKey(Mockito.mock(PublicKey.class)) - .build(); - return Optional.of(publicKeyHolder); - } else { - return Optional.empty(); - } - }); - Mockito.when(httpClient.newCall(any(Request.class))) - .thenAnswer( - (i) -> { - final Response response; - - final Request request = i.getArgument(0); - if (request.url().toString().equals(JWKS_URI.toString())) { - final ResponseBody responseBody = - ResponseBody.create(JWKS, MediaType.get("application/json")); - response = - new Response.Builder() - .request(request) - .protocol(Protocol.HTTP_1_0) - .body(responseBody) - .message("ok") - .code(200) - .build(); - } else { - response = new Response.Builder().code(404).build(); - } - - final Call call = Mockito.mock(Call.class); - Mockito.when(call.execute()).thenReturn(response); - return call; - }); - - final TypeManager typeManager = new TypeManager(); - jwkPublicKeyResolver = - new JwkPublicKeyResolver( - JWKS_URI, - httpClient, - typeManager, - monitor, - Collections.singletonList(publicKeyReader), - INTERVAL); - } - - @Test - void testPublicKeyNullForKeyIdNotFound() { - jwkPublicKeyResolver.start(); - final PublicKey key = jwkPublicKeyResolver.resolveKey("foo"); - - Assertions.assertNull(key); - } - - @Test - void testPublicKeyFoundById() { - jwkPublicKeyResolver.start(); - final PublicKey key = jwkPublicKeyResolver.resolveKey(JWKS_KEY_ID); - - Assertions.assertNotNull(key); - } - - @Test - void testExceptionOnIdentityProviderRespondingWithNon200() { - Mockito.when(httpClient.newCall(any(Request.class))) - .thenAnswer( - (i) -> { - final Response response = new Response.Builder().code(404).build(); - - final Call call = Mockito.mock(Call.class); - Mockito.when(call.execute()).thenReturn(response); - return call; - }); - - Assertions.assertThrows(EdcException.class, () -> jwkPublicKeyResolver.start()); - } - - @Test - void testExceptionOnIdentityProviderRespondingWithEmptyBody() { - Mockito.when(httpClient.newCall(any(Request.class))) - .thenAnswer( - (i) -> { - final Response response = new Response.Builder().code(200).build(); - - final Call call = Mockito.mock(Call.class); - Mockito.when(call.execute()).thenReturn(response); - return call; - }); - - Assertions.assertThrows(EdcException.class, () -> jwkPublicKeyResolver.start()); - } - - @Test - void testExceptionOnIdentityProviderRespondingWithEmptyJwks() { - Mockito.when(httpClient.newCall(any(Request.class))) - .thenAnswer( - (i) -> { - final ResponseBody responseBody = - ResponseBody.create("{ \"keys\": [] }", MediaType.get("application/json")); - final Response response = new Response.Builder().code(200).body(responseBody).build(); - - final Call call = Mockito.mock(Call.class); - Mockito.when(call.execute()).thenReturn(response); - return call; - }); - - Assertions.assertThrows(EdcException.class, () -> jwkPublicKeyResolver.start()); - } - - @Test - void testExceptionOnHttpClientException() { - Mockito.when(httpClient.newCall(any(Request.class))).thenThrow(new RuntimeException()); - - Assertions.assertThrows(EdcException.class, () -> jwkPublicKeyResolver.start()); - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwk/RsaPublicKeyReaderTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwk/RsaPublicKeyReaderTest.java deleted file mode 100644 index b530ba980..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwk/RsaPublicKeyReaderTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.oauth2.jwk; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.Optional; -import lombok.SneakyThrows; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -class RsaPublicKeyReaderTest { - private static final String JWKS_KEY_ID = "e600c72b-125a-4b30-86a5-9697af62f2a1"; - private static final String JWKS_PUBLIC_KEY = - "MIICujCCAaKgAwIBAgIECI8fsTANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDExR0ZXN0LWFsZXgucmVhY2g1Lm5ldDAeFw0yMDA3MjkwOTM0MjlaFw0yMjAyMTcxNDIwMzNaMB8xHTAbBgNVBAMTFHRlc3QtYWxleC5yZWFjaDUubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlzRszUeQ4WiSqvmYxMP10ngm8ALIoUwMH7Oa8vrZgD5pqalPjetPAxeVcAv2gTyDlOwtB0fGvlQo6n78pd9pTbgrzUjhmFuYN6OCfT6eN/2wu0LmwryFS2mbh7/1DTiKd2tZaRalskPECXTKkeks85HVqanB0860BYlGvQvfgrvhCWXXFJJeXvNwYNFYdDdrFQhoeOAEvRDKg9DdHZf6XzSR6Qk3w51FKn2b7imen/G52itD/kIen1hqqB2Jwt9SWyX5MSGySY2QwC18F6Dfs8L+t0mwCo6grGW9264Z5vlO0PWssEqGIX/ez6nk1ZdHXhoXwJ0W+6QzeQlUN8jNoQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAETbMWro4HI4ZuqtnjMZrgEOpx6WhAtxpMx5XFPVWbdp/DpPySotoWbbD6qCtYc34E+ec7mH7aHVap+Gl2IyeSHTht4FXfF9q/1Oj/fis/4DDi1iq00rJsU18D71mZ9FGWCWlO1nhW1KSTGbRJ3E0wSrNabcvaXcwEHokR3zm+xfRWjtbrq2hQ19R16xyOLVy4zrF95QxP4UN+Cvm8nmYur6bSqv+gCMvDsl+O/gtRHGgpUukHEJwnee1R3+1aIv+9zOF3HaaUC5neOLBFITGmeXgi8G2IhbG+JoXh/GUkb66TZUlUAM3qXYNL9Nf+2MQ7nAPTXcxlmImFUUrnv0c3"; - private static final String JWKS = - String.format( - "{" - + " \"keys\": [" - + " {" - + " \"kty\": \"RSA\"," - + " \"e\": \"AQAB\"," - + " \"x5t\": \"NjU3NDI5ZTZhODU0YjQzMGFiYzkwNGNkZDkwNmZkMzZmOWEzNWVmMQ\"," - + " \"use\": \"sig\"," - + " \"kid\": \"%s\"," - + " \"x5c\": [" - + " \"%s\"" - + " ]," - + " \"alg\": \"RS256\"," - + " \"n\": \"lzRszUeQ4WiSqvmYxMP10ngm8ALIoUwMH7Oa8vrZgD5pqalPjetPAxeVcAv2gTyDlOwtB0fGvlQo6n78pd9pTbgrzUjhmFuYN6OCfT6eN_2wu0LmwryFS2mbh7_1DTiKd2tZaRalskPECXTKkeks85HVqanB0860BYlGvQvfgrvhCWXXFJJeXvNwYNFYdDdrFQhoeOAEvRDKg9DdHZf6XzSR6Qk3w51FKn2b7imen_G52itD_kIen1hqqB2Jwt9SWyX5MSGySY2QwC18F6Dfs8L-t0mwCo6grGW9264Z5vlO0PWssEqGIX_ez6nk1ZdHXhoXwJ0W-6QzeQlUN8jNoQ\"" - + " }" - + " ]" - + "}", - JWKS_KEY_ID, JWKS_PUBLIC_KEY); - - private RsaPublicKeyReader publicKeyReader; - - // mocks - private Monitor monitor; - - @BeforeEach - void setUp() { - monitor = Mockito.mock(Monitor.class); - publicKeyReader = new RsaPublicKeyReader(monitor); - } - - @Test - void testCanRead() { - final JsonWebKey jwk = deserializeKey(); - - Assertions.assertTrue(publicKeyReader.canRead(jwk)); - } - - @Test - void testReadSuccess() { - final JsonWebKey jwk = deserializeKey(); - - final Optional key = publicKeyReader.read(jwk); - - Assertions.assertTrue(key.isPresent()); - } - - @SneakyThrows - private JsonWebKey deserializeKey() { - final ObjectMapper objectMapper = new ObjectMapper(); - final JsonWebKeySet jwks = objectMapper.readValue(JWKS, JsonWebKeySet.class); - final JsonWebKey jwk = jwks.getKeys().get(0); - - return jwk; - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/DapsJwtDecoratorTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/DapsJwtDecoratorTest.java deleted file mode 100644 index 99ed5ae93..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/DapsJwtDecoratorTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Test - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class DapsJwtDecoratorTest { - - @Test - void decorate() { - final DapsJwtDecorator decorator = new DapsJwtDecorator(); - - Assertions.assertTrue(decorator.claims().containsKey("@context")); - Assertions.assertEquals( - "https://w3id.org/idsa/contexts/context.jsonld", decorator.claims().get("@context")); - - Assertions.assertTrue(decorator.claims().containsKey("@type")); - Assertions.assertEquals("ids:DatRequestToken", decorator.claims().get("@type")); - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/ExpJwtDecoratorTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/ExpJwtDecoratorTest.java deleted file mode 100644 index fe5a3e903..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/ExpJwtDecoratorTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Test - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.time.Clock; -import java.time.Duration; -import java.time.Instant; -import java.util.Date; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -class ExpJwtDecoratorTest { - - @Test - void decorate() { - final Clock clock = Mockito.mock(Clock.class); - final Duration expiration = Duration.ofSeconds(100); - - final ExpJwtDecorator decorator = new ExpJwtDecorator(clock, expiration); - - Mockito.when(clock.instant()).thenReturn(Instant.ofEpochSecond(0)); - - Assertions.assertTrue(decorator.claims().containsKey(JWTClaimNames.EXPIRATION_TIME)); - Assertions.assertEquals( - new Date(100000), decorator.claims().get(JWTClaimNames.EXPIRATION_TIME)); - } - - @Test - void constructorNull() { - Assertions.assertThrows(NullPointerException.class, () -> new ExpJwtDecorator(null, null)); - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IatJwtDecoratorTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IatJwtDecoratorTest.java deleted file mode 100644 index 898903e62..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IatJwtDecoratorTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Test - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.time.Clock; -import java.time.Instant; -import java.util.Date; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -class IatJwtDecoratorTest { - - @Test - void decorate() { - final Clock clock = Mockito.mock(Clock.class); - - final IatJwtDecorator decorator = new IatJwtDecorator(clock); - - Mockito.when(clock.instant()).thenReturn(Instant.ofEpochSecond(0)); - - Assertions.assertTrue(decorator.claims().containsKey(JWTClaimNames.ISSUED_AT)); - Assertions.assertEquals(new Date(0), decorator.claims().get(JWTClaimNames.ISSUED_AT)); - } - - @Test - void constructorNull() { - Assertions.assertThrows(NullPointerException.class, () -> new IatJwtDecorator(null)); - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IdsAudJwtDecoratorTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IdsAudJwtDecoratorTest.java deleted file mode 100644 index b9180e5ec..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IdsAudJwtDecoratorTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Test - * - */ - -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.List; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class IdsAudJwtDecoratorTest { - - @Test - void decorate() { - final String expectedAudience = "idsc:IDS_CONNECTORS_ALL"; - final IdsAudJwtDecorator decorator = new IdsAudJwtDecorator(); - - Assertions.assertTrue(decorator.claims().containsKey(JWTClaimNames.AUDIENCE)); - Assertions.assertEquals( - List.of(expectedAudience), decorator.claims().get(JWTClaimNames.AUDIENCE)); - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IssJwtDecoratorTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IssJwtDecoratorTest.java deleted file mode 100644 index fba6a1d52..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/IssJwtDecoratorTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Test - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.UUID; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class IssJwtDecoratorTest { - - @Test - void decorate() { - final String expectedIssuer = UUID.randomUUID().toString(); - final IssJwtDecorator decorator = new IssJwtDecorator(expectedIssuer); - - Assertions.assertTrue(decorator.claims().containsKey(JWTClaimNames.ISSUER)); - Assertions.assertEquals(expectedIssuer, decorator.claims().get(JWTClaimNames.ISSUER)); - } - - @Test - void constructorNull() { - Assertions.assertThrows(NullPointerException.class, () -> new IssJwtDecorator(null)); - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/JtiJwtDecoratorTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/JtiJwtDecoratorTest.java deleted file mode 100644 index 681113b38..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/JtiJwtDecoratorTest.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Test - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class JtiJwtDecoratorTest { - - @Test - void decorate() { - final JtiJwtDecorator decorator = new JtiJwtDecorator(); - - Assertions.assertTrue(decorator.claims().containsKey(JWTClaimNames.JWT_ID)); - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/Oauth2JwtDecoratorRegistryRegistryImplTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/Oauth2JwtDecoratorRegistryRegistryImplTest.java deleted file mode 100644 index e11b78a38..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/Oauth2JwtDecoratorRegistryRegistryImplTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Test - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.Arrays; -import java.util.Map; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class Oauth2JwtDecoratorRegistryRegistryImplTest { - - private final Oauth2JwtDecoratorRegistryRegistryImpl oauth2JwtDecoratorRegistryRegistry = - new Oauth2JwtDecoratorRegistryRegistryImpl(); - - @Test - void test() { - final A_JwtDecorator a = new A_JwtDecorator(); - final B_JwtDecorator b = new B_JwtDecorator(); - final C_JwtDecorator c = new C_JwtDecorator(); - - oauth2JwtDecoratorRegistryRegistry.register(a); - - Assertions.assertNotNull(oauth2JwtDecoratorRegistryRegistry.getAll()); - Assertions.assertEquals(1, oauth2JwtDecoratorRegistryRegistry.getAll().size()); - - oauth2JwtDecoratorRegistryRegistry.register(b); - - Assertions.assertNotNull(oauth2JwtDecoratorRegistryRegistry.getAll()); - Assertions.assertEquals(2, oauth2JwtDecoratorRegistryRegistry.getAll().size()); - - oauth2JwtDecoratorRegistryRegistry.register(c); - - Assertions.assertNotNull(oauth2JwtDecoratorRegistryRegistry.getAll()); - Assertions.assertEquals(3, oauth2JwtDecoratorRegistryRegistry.getAll().size()); - - Assertions.assertTrue( - oauth2JwtDecoratorRegistryRegistry.getAll().containsAll(Arrays.asList(a, b, c))); - - oauth2JwtDecoratorRegistryRegistry.unregister(c); - - Assertions.assertNotNull(oauth2JwtDecoratorRegistryRegistry.getAll()); - Assertions.assertEquals(2, oauth2JwtDecoratorRegistryRegistry.getAll().size()); - - Assertions.assertTrue( - oauth2JwtDecoratorRegistryRegistry.getAll().containsAll(Arrays.asList(a, b))); - - oauth2JwtDecoratorRegistryRegistry.unregister(b); - - Assertions.assertNotNull(oauth2JwtDecoratorRegistryRegistry.getAll()); - Assertions.assertEquals(1, oauth2JwtDecoratorRegistryRegistry.getAll().size()); - - Assertions.assertTrue(oauth2JwtDecoratorRegistryRegistry.getAll().contains(a)); - - oauth2JwtDecoratorRegistryRegistry.unregister(a); - - Assertions.assertNotNull(oauth2JwtDecoratorRegistryRegistry.getAll()); - Assertions.assertTrue(oauth2JwtDecoratorRegistryRegistry.getAll().isEmpty()); - } - - private static class A_JwtDecorator implements JwtDecorator { - @Override - public Map claims() { - return null; - } - - @Override - public Map headers() { - return null; - } - } - - private static class B_JwtDecorator implements JwtDecorator { - @Override - public Map claims() { - return null; - } - - @Override - public Map headers() { - return null; - } - } - - private static class C_JwtDecorator implements JwtDecorator { - @Override - public Map claims() { - return null; - } - - @Override - public Map headers() { - return null; - } - } -} diff --git a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/SubJwtDecoratorTest.java b/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/SubJwtDecoratorTest.java deleted file mode 100644 index 4dc4f32eb..000000000 --- a/edc-extensions/cx-oauth2/src/test/java/net/catenax/edc/oauth2/jwt/decorator/SubJwtDecoratorTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Test - * - */ -package net.catenax.edc.oauth2.jwt.decorator; - -import java.util.UUID; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class SubJwtDecoratorTest { - - @Test - void decorate() { - final String expectedSubject = UUID.randomUUID().toString(); - final SubJwtDecorator decorator = new SubJwtDecorator(expectedSubject); - - Assertions.assertTrue(decorator.claims().containsKey(JWTClaimNames.SUBJECT)); - Assertions.assertEquals(expectedSubject, decorator.claims().get(JWTClaimNames.SUBJECT)); - } - - @Test - void constructorNull() { - Assertions.assertThrows(NullPointerException.class, () -> new SubJwtDecorator(null)); - } -} diff --git a/edc-extensions/data-encryption/build.gradle.kts b/edc-extensions/data-encryption/build.gradle.kts new file mode 100644 index 000000000..f619da546 --- /dev/null +++ b/edc-extensions/data-encryption/build.gradle.kts @@ -0,0 +1,11 @@ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + api(edc.spi.core) + implementation(edc.spi.dataplane.transfer) + implementation(libs.bouncyCastle.bcpkix) +} diff --git a/edc-extensions/data-encryption/pom.xml b/edc-extensions/data-encryption/pom.xml deleted file mode 100644 index ff36a89c6..000000000 --- a/edc-extensions/data-encryption/pom.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - edc-extensions - net.catenax.edc.extensions - 0.1.6 - - 4.0.0 - - data-encryption - jar - - - ${project.basedir}/src/main/java - ${originalSourceDirectory} - ${project.build.directory}/delombok - ${project.groupId}_${project.artifactId} - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - ${project.build.sourceEncoding} - - - org.projectlombok - lombok - ${org.projectlombok.lombok.version} - - - - - - - org.projectlombok - lombok-maven-plugin - ${org.projectlombok.lombok.maven.plugin.version} - - - generate-sources - - delombok - - - - - ${originalSourceDirectory} - ${delombokSourceDirectory} - false - UTF-8 - - skip - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - - - - - - - org.eclipse.dataspaceconnector - core-spi - - - org.eclipse.dataspaceconnector - data-plane-transfer-spi - - - - - org.projectlombok - lombok - - - org.bouncycastle - bcpkix-jdk15on - ${org.bouncycastle.bcpkix-jdk15on.version} - - - - - org.junit.jupiter - junit-jupiter - test - - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - - - diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/CryptoAlgorithm.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/CryptoAlgorithm.java deleted file mode 100644 index 0bc71c673..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/CryptoAlgorithm.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.data.encryption.algorithms; - -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import net.catenax.edc.data.encryption.data.DecryptedData; -import net.catenax.edc.data.encryption.data.EncryptedData; -import net.catenax.edc.data.encryption.key.CryptoKey; - -public interface CryptoAlgorithm { - EncryptedData encrypt(DecryptedData data, T key) - throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, - NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException; - - DecryptedData decrypt(EncryptedData data, T key) - throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, - NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException; -} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoDataFactory.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoDataFactory.java deleted file mode 100644 index c6abab6e6..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoDataFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.data.encryption.data; - -public interface CryptoDataFactory { - - DecryptedData decryptedFromText(String text); - - DecryptedData decryptedFromBase64(String base64); - - DecryptedData decryptedFromBytes(byte[] bytes); - - EncryptedData encryptedFromText(String text); - - EncryptedData encryptedFromBase64(String base64); - - EncryptedData encryptedFromBytes(byte[] bytes); -} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/DecryptedData.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/DecryptedData.java deleted file mode 100644 index 903823757..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/DecryptedData.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.data.encryption.data; - -public interface DecryptedData extends CryptoData {} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/EncryptedData.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/EncryptedData.java deleted file mode 100644 index 033f0ceeb..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/EncryptedData.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.data.encryption.data; - -public interface EncryptedData extends CryptoData {} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/AesDataEncrypterConfiguration.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/AesDataEncrypterConfiguration.java deleted file mode 100644 index 3357f7eff..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/AesDataEncrypterConfiguration.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.data.encryption.encrypter; - -import java.time.Duration; -import lombok.NonNull; -import lombok.Value; - -@Value -public class AesDataEncrypterConfiguration { - @NonNull String keySetAlias; - boolean cachingEnabled; - @NonNull Duration cachingDuration; -} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterFactory.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterFactory.java deleted file mode 100644 index 382c8086a..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterFactory.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.data.encryption.encrypter; - -import lombok.RequiredArgsConstructor; -import net.catenax.edc.data.encryption.algorithms.CryptoAlgorithm; -import net.catenax.edc.data.encryption.algorithms.aes.AesAlgorithm; -import net.catenax.edc.data.encryption.data.CryptoDataFactory; -import net.catenax.edc.data.encryption.data.CryptoDataFactoryImpl; -import net.catenax.edc.data.encryption.key.AesKey; -import net.catenax.edc.data.encryption.key.CryptoKeyFactory; -import net.catenax.edc.data.encryption.provider.AesKeyProvider; -import net.catenax.edc.data.encryption.provider.CachingKeyProvider; -import net.catenax.edc.data.encryption.provider.KeyProvider; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.security.Vault; -import org.eclipse.dataspaceconnector.transfer.dataplane.spi.security.DataEncrypter; - -@RequiredArgsConstructor -public class DataEncrypterFactory { - - public static final String AES_ALGORITHM = "AES"; - public static final String NONE = "NONE"; - - private final Vault vault; - private final Monitor monitor; - private final CryptoKeyFactory keyFactory; - - public DataEncrypter createNoneEncrypter() { - return new DataEncrypter() { - @Override - public String encrypt(String data) { - return data; - } - - @Override - public String decrypt(String data) { - return data; - } - }; - } - - public DataEncrypter createAesEncrypter(AesDataEncrypterConfiguration configuration) { - KeyProvider keyProvider = - new AesKeyProvider(vault, configuration.getKeySetAlias(), keyFactory); - - if (configuration.isCachingEnabled()) { - keyProvider = new CachingKeyProvider<>(keyProvider, configuration.getCachingDuration()); - } - - final CryptoDataFactory cryptoDataFactory = new CryptoDataFactoryImpl(); - final CryptoAlgorithm algorithm = new AesAlgorithm(cryptoDataFactory); - - return new AesDataEncrypterImpl(algorithm, monitor, keyProvider, algorithm, cryptoDataFactory); - } -} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKey.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKey.java deleted file mode 100644 index cf3ca2da5..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKey.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.data.encryption.key; - -public interface CryptoKey {} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKeyFactoryImpl.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKeyFactoryImpl.java deleted file mode 100644 index 398088a95..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKeyFactoryImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.data.encryption.key; - -import lombok.Value; -import org.bouncycastle.util.encoders.Base64; - -public class CryptoKeyFactoryImpl implements CryptoKeyFactory { - - public AesKey fromBase64(String base64) { - return fromBytes(Base64.decode(base64)); - } - - public AesKey fromBytes(byte[] key) { - int bitLength = key.length * Byte.SIZE; - if (!(bitLength == 128 || bitLength == 192 || bitLength == 256)) { - throw new IllegalArgumentException("Invalid AES key length: " + bitLength); - } - - return new AesKeyImpl(key, Base64.toBase64String(key)); - } - - @Value - private static class AesKeyImpl implements AesKey { - byte[] bytes; - String base64; - } -} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/AesKeyProvider.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/AesKeyProvider.java deleted file mode 100644 index be9802013..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/AesKeyProvider.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.data.encryption.provider; - -import java.util.Arrays; -import java.util.function.Predicate; -import java.util.stream.Stream; -import lombok.RequiredArgsConstructor; -import net.catenax.edc.data.encryption.DataEncryptionExtension; -import net.catenax.edc.data.encryption.key.AesKey; -import net.catenax.edc.data.encryption.key.CryptoKeyFactory; -import org.bouncycastle.util.encoders.Base64; -import org.eclipse.dataspaceconnector.spi.security.Vault; - -@RequiredArgsConstructor -public class AesKeyProvider implements KeyProvider { - - private static final String KEY_SEPARATOR = ","; - - private final Vault vault; - private final String vaultKeyAlias; - private final CryptoKeyFactory cryptoKeyFactory; - - @Override - public Stream getDecryptionKeySet() { - return getKeysStream(); - } - - @Override - public AesKey getEncryptionKey() { - return getKeysStream() - .findFirst() - .orElseThrow( - () -> - new RuntimeException( - DataEncryptionExtension.NAME + ": Vault must contain at least one key.")); - } - - private Stream getKeysStream() { - return Arrays.stream(getKeys().split(KEY_SEPARATOR)) - .map(String::trim) - .filter(Predicate.not(String::isEmpty)) - .map(Base64::decode) - .map(cryptoKeyFactory::fromBytes); - } - - private String getKeys() { - String keys = vault.resolveSecret(vaultKeyAlias); - return keys == null ? "" : keys; - } -} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/util/ArrayUtil.java b/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/util/ArrayUtil.java deleted file mode 100644 index f632c8121..000000000 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/util/ArrayUtil.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.data.encryption.util; - -public class ArrayUtil { - - private ArrayUtil() {} - - public static byte[] concat(byte[] a, byte[] b) { - byte[] c = new byte[a.length + b.length]; - System.arraycopy(a, 0, c, 0, a.length); - System.arraycopy(b, 0, c, a.length, b.length); - return c; - } - - public static String byteArrayToHex(byte[] a) { - StringBuilder sb = new StringBuilder(a.length * 2); - for (byte b : a) sb.append(String.format("%02x", b)); - return sb.toString(); - } - - public static byte[] subArray(byte[] a, int startIndex, int length) { - if (startIndex + length > a.length) { - throw new IllegalArgumentException("Start index + length is greater than array length"); - } - - byte[] b = new byte[length]; - System.arraycopy(a, startIndex, b, 0, length); - return b; - } -} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/DataEncryptionExtension.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/DataEncryptionExtension.java similarity index 55% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/DataEncryptionExtension.java rename to edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/DataEncryptionExtension.java index 5f9446dfa..8024bc276 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/DataEncryptionExtension.java +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/DataEncryptionExtension.java @@ -1,52 +1,57 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption; +package org.eclipse.tractusx.edc.data.encryption; import java.time.Duration; import java.util.List; import java.util.stream.Collectors; -import net.catenax.edc.data.encryption.encrypter.AesDataEncrypterConfiguration; -import net.catenax.edc.data.encryption.encrypter.DataEncrypterFactory; -import net.catenax.edc.data.encryption.key.AesKey; -import net.catenax.edc.data.encryption.key.CryptoKeyFactory; -import net.catenax.edc.data.encryption.key.CryptoKeyFactoryImpl; -import net.catenax.edc.data.encryption.provider.AesKeyProvider; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.EdcSetting; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.security.Vault; -import org.eclipse.dataspaceconnector.spi.system.Provides; -import org.eclipse.dataspaceconnector.spi.system.Requires; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtension; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.connector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.runtime.metamodel.annotation.Provides; +import org.eclipse.edc.runtime.metamodel.annotation.Requires; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.tractusx.edc.data.encryption.encrypter.AesDataEncrypterConfiguration; +import org.eclipse.tractusx.edc.data.encryption.encrypter.DataEncrypterFactory; +import org.eclipse.tractusx.edc.data.encryption.key.AesKey; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKeyFactory; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKeyFactoryImpl; +import org.eclipse.tractusx.edc.data.encryption.provider.AesKeyProvider; @Provides({DataEncrypter.class}) @Requires({Vault.class}) public class DataEncryptionExtension implements ServiceExtension { - public static final String NAME = "Data Encryption Extension"; + public static final String EXTENSION_NAME = "Data Encryption Extension"; - @EdcSetting public static final String ENCRYPTION_KEY_SET = "edc.data.encryption.keys.alias"; + public static final String ENCRYPTION_KEY_SET = "edc.data.encryption.keys.alias"; - @EdcSetting public static final String ENCRYPTION_ALGORITHM = "edc.data.encryption.algorithm"; + public static final String ENCRYPTION_ALGORITHM = "edc.data.encryption.algorithm"; public static final String ENCRYPTION_ALGORITHM_DEFAULT = DataEncrypterFactory.AES_ALGORITHM; - @EdcSetting public static final String CACHING_ENABLED = "edc.data.encryption.caching.enabled"; + public static final String CACHING_ENABLED = "edc.data.encryption.caching.enabled"; public static final boolean CACHING_ENABLED_DEFAULT = false; - @EdcSetting public static final String CACHING_SECONDS = "edc.data.encryption.caching.seconds"; + public static final String CACHING_SECONDS = "edc.data.encryption.caching.seconds"; public static final int CACHING_SECONDS_DEFAULT = 3600; private static final CryptoKeyFactory cryptoKeyFactory = new CryptoKeyFactoryImpl(); @@ -57,7 +62,7 @@ public class DataEncryptionExtension implements ServiceExtension { @Override public String name() { - return NAME; + return EXTENSION_NAME; } @Override @@ -75,7 +80,8 @@ public void start() { final String keyAlias = configuration.getKeySetAlias(); final String keySecret = vault.resolveSecret(keyAlias); if (keySecret == null || keySecret.isEmpty()) { - throw new EdcException(NAME + ": No vault key secret found for alias " + keyAlias); + throw new EdcException( + EXTENSION_NAME + ": No vault key secret found for alias " + keyAlias); } try { @@ -83,10 +89,12 @@ public void start() { final List keys = aesKeyProvider.getDecryptionKeySet().collect(Collectors.toList()); monitor.debug( String.format( - "Started " + NAME + ": Found %s registered AES keys in vault.", keys.size())); + "Started " + EXTENSION_NAME + ": Found %s registered AES keys in vault.", + keys.size())); } catch (Exception e) { throw new EdcException( - NAME + ": AES keys from vault must be comma separated and Base64 encoded.", e); + EXTENSION_NAME + ": AES keys from vault must be comma separated and Base64 encoded.", + e); } } } @@ -108,7 +116,7 @@ public void initialize(ServiceExtensionContext context) { } else { final String msg = String.format( - DataEncryptionExtension.NAME + DataEncryptionExtension.EXTENSION_NAME + ": Unsupported encryption algorithm '%s'. Supported algorithms are '%s', '%s'.", algorithm, DataEncrypterFactory.AES_ALGORITHM, @@ -123,7 +131,7 @@ private static AesDataEncrypterConfiguration createAesConfiguration( ServiceExtensionContext context) { final String key = context.getSetting(ENCRYPTION_KEY_SET, null); if (key == null) { - throw new EdcException(NAME + ": Missing setting " + ENCRYPTION_KEY_SET); + throw new EdcException(EXTENSION_NAME + ": Missing setting " + ENCRYPTION_KEY_SET); } final boolean cachingEnabled = context.getSetting(CACHING_ENABLED, CACHING_ENABLED_DEFAULT); diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/CryptoAlgorithm.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/CryptoAlgorithm.java new file mode 100644 index 000000000..a49cce44d --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/CryptoAlgorithm.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.algorithms; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import org.eclipse.tractusx.edc.data.encryption.data.DecryptedData; +import org.eclipse.tractusx.edc.data.encryption.data.EncryptedData; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKey; + +public interface CryptoAlgorithm { + EncryptedData encrypt(DecryptedData data, T key) + throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, + NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException; + + DecryptedData decrypt(EncryptedData data, T key) + throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, + NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException; +} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/AesAlgorithm.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesAlgorithm.java similarity index 74% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/AesAlgorithm.java rename to edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesAlgorithm.java index 6214fe90e..69c54a173 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/AesAlgorithm.java +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesAlgorithm.java @@ -1,17 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2023 ZF Friedrichshafen AG + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.algorithms.aes; +package org.eclipse.tractusx.edc.data.encryption.algorithms.aes; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -25,13 +32,13 @@ import javax.crypto.spec.SecretKeySpec; import lombok.NonNull; import lombok.SneakyThrows; -import net.catenax.edc.data.encryption.algorithms.CryptoAlgorithm; -import net.catenax.edc.data.encryption.data.CryptoDataFactory; -import net.catenax.edc.data.encryption.data.DecryptedData; -import net.catenax.edc.data.encryption.data.EncryptedData; -import net.catenax.edc.data.encryption.key.AesKey; -import net.catenax.edc.data.encryption.util.ArrayUtil; import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.eclipse.tractusx.edc.data.encryption.algorithms.CryptoAlgorithm; +import org.eclipse.tractusx.edc.data.encryption.data.CryptoDataFactory; +import org.eclipse.tractusx.edc.data.encryption.data.DecryptedData; +import org.eclipse.tractusx.edc.data.encryption.data.EncryptedData; +import org.eclipse.tractusx.edc.data.encryption.key.AesKey; +import org.eclipse.tractusx.edc.data.encryption.util.ArrayUtil; import org.jetbrains.annotations.NotNull; public class AesAlgorithm implements CryptoAlgorithm { diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/AesInitializationVectorIterator.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesInitializationVectorIterator.java similarity index 53% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/AesInitializationVectorIterator.java rename to edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesInitializationVectorIterator.java index e7121c613..cd0a6b1ec 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/AesInitializationVectorIterator.java +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesInitializationVectorIterator.java @@ -1,22 +1,30 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2023 ZF Friedrichshafen AG + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.algorithms.aes; +package org.eclipse.tractusx.edc.data.encryption.algorithms.aes; import java.security.SecureRandom; import java.util.Iterator; import java.util.NoSuchElementException; -import net.catenax.edc.data.encryption.util.ArrayUtil; +import lombok.SneakyThrows; +import org.eclipse.tractusx.edc.data.encryption.util.ArrayUtil; public class AesInitializationVectorIterator implements Iterator { @@ -53,6 +61,7 @@ public byte[] next() { return ArrayUtil.concat(random, counter.getBytes()); } + @SneakyThrows public byte[] getNextRandom() { byte[] newVector = new byte[RANDOM_SIZE]; secureRandom.nextBytes(newVector); diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/ByteCounter.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/ByteCounter.java similarity index 62% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/ByteCounter.java rename to edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/ByteCounter.java index 4208d4ec6..55eec8184 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/algorithms/aes/ByteCounter.java +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/ByteCounter.java @@ -1,17 +1,23 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.algorithms.aes; +package org.eclipse.tractusx.edc.data.encryption.algorithms.aes; /** Big Endian Byte Counter */ public class ByteCounter { diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoData.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoData.java new file mode 100644 index 000000000..edb3b3620 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoData.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.data; + +public interface CryptoData { + byte[] getBytes(); + + String getBase64(); +} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoDataFactory.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoDataFactory.java new file mode 100644 index 000000000..a37460111 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoDataFactory.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.data; + +public interface CryptoDataFactory { + + DecryptedData decryptedFromText(String text); + + DecryptedData decryptedFromBase64(String base64); + + DecryptedData decryptedFromBytes(byte[] bytes); + + EncryptedData encryptedFromText(String text); + + EncryptedData encryptedFromBase64(String base64); + + EncryptedData encryptedFromBytes(byte[] bytes); +} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoDataFactoryImpl.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoDataFactoryImpl.java similarity index 67% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoDataFactoryImpl.java rename to edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoDataFactoryImpl.java index 07a1e39fe..b23966170 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoDataFactoryImpl.java +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/CryptoDataFactoryImpl.java @@ -1,17 +1,23 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.data; +package org.eclipse.tractusx.edc.data.encryption.data; import lombok.Value; import org.bouncycastle.util.encoders.Base64; diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/DecryptedData.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/DecryptedData.java new file mode 100644 index 000000000..63c6cf2b1 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/DecryptedData.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.data; + +public interface DecryptedData extends CryptoData {} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/EncryptedData.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/EncryptedData.java new file mode 100644 index 000000000..dd4e8241a --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/data/EncryptedData.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.data; + +public interface EncryptedData extends CryptoData {} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/AesDataEncrypterConfiguration.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/AesDataEncrypterConfiguration.java new file mode 100644 index 000000000..725828acc --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/AesDataEncrypterConfiguration.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.encrypter; + +import java.time.Duration; +import lombok.NonNull; +import lombok.Value; + +@Value +public class AesDataEncrypterConfiguration { + @NonNull String keySetAlias; + boolean cachingEnabled; + @NonNull Duration cachingDuration; +} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/AesDataEncrypterImpl.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/AesDataEncrypterImpl.java similarity index 62% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/AesDataEncrypterImpl.java rename to edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/AesDataEncrypterImpl.java index e3ac3e82b..160f57df0 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/encrypter/AesDataEncrypterImpl.java +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/AesDataEncrypterImpl.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.encrypter; +package org.eclipse.tractusx.edc.data.encryption.encrypter; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; @@ -23,16 +29,16 @@ import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import lombok.RequiredArgsConstructor; -import net.catenax.edc.data.encryption.DataEncryptionExtension; -import net.catenax.edc.data.encryption.algorithms.CryptoAlgorithm; -import net.catenax.edc.data.encryption.data.CryptoDataFactory; -import net.catenax.edc.data.encryption.data.DecryptedData; -import net.catenax.edc.data.encryption.data.EncryptedData; -import net.catenax.edc.data.encryption.key.AesKey; -import net.catenax.edc.data.encryption.provider.KeyProvider; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.connector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.tractusx.edc.data.encryption.DataEncryptionExtension; +import org.eclipse.tractusx.edc.data.encryption.algorithms.CryptoAlgorithm; +import org.eclipse.tractusx.edc.data.encryption.data.CryptoDataFactory; +import org.eclipse.tractusx.edc.data.encryption.data.DecryptedData; +import org.eclipse.tractusx.edc.data.encryption.data.EncryptedData; +import org.eclipse.tractusx.edc.data.encryption.key.AesKey; +import org.eclipse.tractusx.edc.data.encryption.provider.KeyProvider; @RequiredArgsConstructor public class AesDataEncrypterImpl implements DataEncrypter { @@ -76,7 +82,7 @@ public String decrypt(String value) { .orElseThrow( () -> new EdcException( - DataEncryptionExtension.NAME + DataEncryptionExtension.EXTENSION_NAME + ": Failed to decrypt data. This can happen if the key set is empty, contains invalid keys, the decryption key rotated out of the key set or because the data was encrypted by a different algorithm.")); } @@ -93,7 +99,7 @@ private Optional decrypt(EncryptedData data, AesKey key) { | InvalidAlgorithmParameterException e) { monitor.warning( String.format( - DataEncryptionExtension.NAME + DataEncryptionExtension.EXTENSION_NAME + ": Exception decrypting data using key from rotating key set. %s", e.getMessage())); throw new EdcException(e); diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterFactory.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterFactory.java new file mode 100644 index 000000000..916ab245f --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterFactory.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2023 ZF Friedrichshafen AG + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.encrypter; + +import static java.lang.String.format; + +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.tractusx.edc.data.encryption.algorithms.aes.AesAlgorithm; +import org.eclipse.tractusx.edc.data.encryption.data.CryptoDataFactory; +import org.eclipse.tractusx.edc.data.encryption.data.CryptoDataFactoryImpl; +import org.eclipse.tractusx.edc.data.encryption.key.AesKey; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKeyFactory; +import org.eclipse.tractusx.edc.data.encryption.provider.AesKeyProvider; +import org.eclipse.tractusx.edc.data.encryption.provider.CachingKeyProvider; +import org.eclipse.tractusx.edc.data.encryption.provider.KeyProvider; + +@RequiredArgsConstructor +public class DataEncrypterFactory { + + public static final String AES_ALGORITHM = "AES"; + public static final String NONE = "NONE"; + + private final Vault vault; + private final Monitor monitor; + private final CryptoKeyFactory keyFactory; + + public DataEncrypter createNoneEncrypter() { + return new DataEncrypter() { + @Override + public String encrypt(String data) { + return data; + } + + @Override + public String decrypt(String data) { + return data; + } + }; + } + + public DataEncrypter createAesEncrypter(AesDataEncrypterConfiguration configuration) { + KeyProvider keyProvider = + new AesKeyProvider(vault, configuration.getKeySetAlias(), keyFactory); + + if (configuration.isCachingEnabled()) { + keyProvider = new CachingKeyProvider<>(keyProvider, configuration.getCachingDuration()); + } + + final CryptoDataFactory cryptoDataFactory = new CryptoDataFactoryImpl(); + final AesAlgorithm algorithm = new AesAlgorithm(cryptoDataFactory); + + monitor.debug( + format( + "AES algorithm was initialised with SecureRandom algorithm '%s'", + algorithm.getAlgorithm())); + return new AesDataEncrypterImpl(algorithm, monitor, keyProvider, algorithm, cryptoDataFactory); + } +} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/AesKey.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/AesKey.java new file mode 100644 index 000000000..69ef83021 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/AesKey.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.key; + +public interface AesKey extends CryptoKey { + byte[] getBytes(); + + String getBase64(); +} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKey.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKey.java new file mode 100644 index 000000000..f7d8b3601 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKey.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.key; + +public interface CryptoKey {} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactory.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactory.java new file mode 100644 index 000000000..52fdb3c00 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactory.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.key; + +public interface CryptoKeyFactory { + AesKey fromBase64(String base64); + + AesKey fromBytes(byte[] key); +} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactoryImpl.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactoryImpl.java new file mode 100644 index 000000000..f3fa102a4 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactoryImpl.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.key; + +import lombok.Value; +import org.bouncycastle.util.encoders.Base64; + +public class CryptoKeyFactoryImpl implements CryptoKeyFactory { + + public AesKey fromBase64(String base64) { + return fromBytes(Base64.decode(base64)); + } + + public AesKey fromBytes(byte[] key) { + int bitLength = key.length * Byte.SIZE; + if (!(bitLength == 128 || bitLength == 192 || bitLength == 256)) { + throw new IllegalArgumentException("Invalid AES key length: " + bitLength); + } + + return new AesKeyImpl(key, Base64.toBase64String(key)); + } + + @Value + private static class AesKeyImpl implements AesKey { + byte[] bytes; + String base64; + } +} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/AesKeyProvider.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/AesKeyProvider.java new file mode 100644 index 000000000..82b8eccdd --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/AesKeyProvider.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.provider; + +import java.util.Arrays; +import java.util.function.Predicate; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import org.bouncycastle.util.encoders.Base64; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.tractusx.edc.data.encryption.DataEncryptionExtension; +import org.eclipse.tractusx.edc.data.encryption.key.AesKey; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKeyFactory; + +@RequiredArgsConstructor +public class AesKeyProvider implements KeyProvider { + + private static final String KEY_SEPARATOR = ","; + + private final Vault vault; + private final String vaultKeyAlias; + private final CryptoKeyFactory cryptoKeyFactory; + + @Override + public Stream getDecryptionKeySet() { + return getKeysStream(); + } + + @Override + public AesKey getEncryptionKey() { + return getKeysStream() + .findFirst() + .orElseThrow( + () -> + new RuntimeException( + DataEncryptionExtension.EXTENSION_NAME + + ": Vault must contain at least one key.")); + } + + private Stream getKeysStream() { + return Arrays.stream(getKeys().split(KEY_SEPARATOR)) + .map(String::trim) + .filter(Predicate.not(String::isEmpty)) + .map(Base64::decode) + .map(cryptoKeyFactory::fromBytes); + } + + private String getKeys() { + String keys = vault.resolveSecret(vaultKeyAlias); + return keys == null ? "" : keys; + } +} diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/CachingKeyProvider.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/CachingKeyProvider.java similarity index 64% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/CachingKeyProvider.java rename to edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/CachingKeyProvider.java index e33a39551..b4b490918 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/CachingKeyProvider.java +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/CachingKeyProvider.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.provider; +package org.eclipse.tractusx.edc.data.encryption.provider; import java.time.Clock; import java.time.Duration; @@ -22,7 +28,7 @@ import java.util.stream.Stream; import lombok.NonNull; import lombok.Value; -import net.catenax.edc.data.encryption.key.CryptoKey; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKey; public class CachingKeyProvider implements KeyProvider { diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/KeyProvider.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/KeyProvider.java new file mode 100644 index 000000000..86bd2d16d --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/provider/KeyProvider.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.provider; + +import java.util.stream.Stream; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKey; + +public interface KeyProvider { + T getEncryptionKey(); + + Stream getDecryptionKeySet(); +} diff --git a/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/util/ArrayUtil.java b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/util/ArrayUtil.java new file mode 100644 index 000000000..a600f9385 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/java/org/eclipse/tractusx/edc/data/encryption/util/ArrayUtil.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.data.encryption.util; + +public class ArrayUtil { + + private ArrayUtil() {} + + public static byte[] concat(byte[] a, byte[] b) { + byte[] c = new byte[a.length + b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + + public static String byteArrayToHex(byte[] a) { + StringBuilder sb = new StringBuilder(a.length * 2); + for (byte b : a) sb.append(String.format("%02x", b)); + return sb.toString(); + } + + public static byte[] subArray(byte[] a, int startIndex, int length) { + if (startIndex + length > a.length) { + throw new IllegalArgumentException("Start index + length is greater than array length"); + } + + byte[] b = new byte[length]; + System.arraycopy(a, startIndex, b, 0, length); + return b; + } +} diff --git a/edc-extensions/data-encryption/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/data-encryption/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..bce166d66 --- /dev/null +++ b/edc-extensions/data-encryption/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +# +# Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2022 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# +org.eclipse.tractusx.edc.data.encryption.DataEncryptionExtension diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/DataEncryptionExtensionTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/DataEncryptionExtensionTest.java similarity index 73% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/DataEncryptionExtensionTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/DataEncryptionExtensionTest.java index 49fd8dd67..c1e0bbb1a 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/DataEncryptionExtensionTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/DataEncryptionExtensionTest.java @@ -1,24 +1,30 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption; +package org.eclipse.tractusx.edc.data.encryption; -import net.catenax.edc.data.encryption.encrypter.DataEncrypterFactory; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.security.Vault; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.tractusx.edc.data.encryption.encrypter.DataEncrypterFactory; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -60,7 +66,7 @@ void setup() { @Test void testName() { - Assertions.assertEquals(DataEncryptionExtension.NAME, extension.name()); + Assertions.assertEquals(DataEncryptionExtension.EXTENSION_NAME, extension.name()); } @Test diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/AesAlgorithmTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesAlgorithmTest.java similarity index 61% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/AesAlgorithmTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesAlgorithmTest.java index d66459fee..4d19927fb 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/AesAlgorithmTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesAlgorithmTest.java @@ -1,25 +1,31 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.algorithms.aes; +package org.eclipse.tractusx.edc.data.encryption.algorithms.aes; import lombok.SneakyThrows; -import net.catenax.edc.data.encryption.data.CryptoDataFactory; -import net.catenax.edc.data.encryption.data.CryptoDataFactoryImpl; -import net.catenax.edc.data.encryption.data.DecryptedData; -import net.catenax.edc.data.encryption.data.EncryptedData; -import net.catenax.edc.data.encryption.key.AesKey; import org.bouncycastle.util.encoders.Base64; +import org.eclipse.tractusx.edc.data.encryption.data.CryptoDataFactory; +import org.eclipse.tractusx.edc.data.encryption.data.CryptoDataFactoryImpl; +import org.eclipse.tractusx.edc.data.encryption.data.DecryptedData; +import org.eclipse.tractusx.edc.data.encryption.data.EncryptedData; +import org.eclipse.tractusx.edc.data.encryption.key.AesKey; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/AesInitializationVectorIteratorTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesInitializationVectorIteratorTest.java similarity index 66% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/AesInitializationVectorIteratorTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesInitializationVectorIteratorTest.java index d7bf3d885..ceebf50d6 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/AesInitializationVectorIteratorTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/AesInitializationVectorIteratorTest.java @@ -1,24 +1,31 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2023 ZF Friedrichshafen AG + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.algorithms.aes; +package org.eclipse.tractusx.edc.data.encryption.algorithms.aes; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; import lombok.SneakyThrows; -import net.catenax.edc.data.encryption.util.ArrayUtil; +import org.eclipse.tractusx.edc.data.encryption.util.ArrayUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.Mockito; diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/ByteCounterTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/ByteCounterTest.java similarity index 76% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/ByteCounterTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/ByteCounterTest.java index 9beb2e190..5a16343a5 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/algorithms/aes/ByteCounterTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/algorithms/aes/ByteCounterTest.java @@ -1,20 +1,26 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.algorithms.aes; +package org.eclipse.tractusx.edc.data.encryption.algorithms.aes; import java.util.stream.Stream; -import net.catenax.edc.data.encryption.util.ArrayUtil; +import org.eclipse.tractusx.edc.data.encryption.util.ArrayUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtensionContext; diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterAesComponentTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterAesComponentTest.java similarity index 56% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterAesComponentTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterAesComponentTest.java index 717459e4a..aa9140629 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterAesComponentTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterAesComponentTest.java @@ -1,33 +1,39 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.encrypter; +package org.eclipse.tractusx.edc.data.encryption.encrypter; import lombok.SneakyThrows; -import net.catenax.edc.data.encryption.algorithms.CryptoAlgorithm; -import net.catenax.edc.data.encryption.algorithms.aes.AesAlgorithm; -import net.catenax.edc.data.encryption.data.CryptoDataFactory; -import net.catenax.edc.data.encryption.data.CryptoDataFactoryImpl; -import net.catenax.edc.data.encryption.data.DecryptedData; -import net.catenax.edc.data.encryption.data.EncryptedData; -import net.catenax.edc.data.encryption.key.AesKey; -import net.catenax.edc.data.encryption.key.CryptoKeyFactory; -import net.catenax.edc.data.encryption.key.CryptoKeyFactoryImpl; -import net.catenax.edc.data.encryption.provider.AesKeyProvider; -import net.catenax.edc.data.encryption.provider.KeyProvider; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.security.Vault; -import org.eclipse.dataspaceconnector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.connector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.tractusx.edc.data.encryption.algorithms.CryptoAlgorithm; +import org.eclipse.tractusx.edc.data.encryption.algorithms.aes.AesAlgorithm; +import org.eclipse.tractusx.edc.data.encryption.data.CryptoDataFactory; +import org.eclipse.tractusx.edc.data.encryption.data.CryptoDataFactoryImpl; +import org.eclipse.tractusx.edc.data.encryption.data.DecryptedData; +import org.eclipse.tractusx.edc.data.encryption.data.EncryptedData; +import org.eclipse.tractusx.edc.data.encryption.key.AesKey; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKeyFactory; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKeyFactoryImpl; +import org.eclipse.tractusx.edc.data.encryption.provider.AesKeyProvider; +import org.eclipse.tractusx.edc.data.encryption.provider.KeyProvider; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterFactoryTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterFactoryTest.java similarity index 64% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterFactoryTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterFactoryTest.java index 957983503..650fcfec5 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/encrypter/DataEncrypterFactoryTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/encrypter/DataEncrypterFactoryTest.java @@ -1,23 +1,29 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.encrypter; +package org.eclipse.tractusx.edc.data.encryption.encrypter; import java.time.Duration; -import net.catenax.edc.data.encryption.key.CryptoKeyFactoryImpl; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.security.Vault; -import org.eclipse.dataspaceconnector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.connector.transfer.dataplane.spi.security.DataEncrypter; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKeyFactoryImpl; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/key/CryptoKeyFactoryImplTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactoryImplTest.java similarity index 50% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/key/CryptoKeyFactoryImplTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactoryImplTest.java index 00ec3e8e0..73354b76c 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/key/CryptoKeyFactoryImplTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/key/CryptoKeyFactoryImplTest.java @@ -1,17 +1,23 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.key; +package org.eclipse.tractusx.edc.data.encryption.key; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/provider/AesKeyProviderTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/provider/AesKeyProviderTest.java similarity index 61% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/provider/AesKeyProviderTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/provider/AesKeyProviderTest.java index f106ba9c4..04625fdb0 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/provider/AesKeyProviderTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/provider/AesKeyProviderTest.java @@ -1,24 +1,30 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.provider; +package org.eclipse.tractusx.edc.data.encryption.provider; import java.util.List; import java.util.stream.Collectors; -import net.catenax.edc.data.encryption.key.AesKey; -import net.catenax.edc.data.encryption.key.CryptoKeyFactoryImpl; -import org.eclipse.dataspaceconnector.spi.security.Vault; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.tractusx.edc.data.encryption.key.AesKey; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKeyFactoryImpl; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/provider/CachingKeyProviderTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/provider/CachingKeyProviderTest.java similarity index 72% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/provider/CachingKeyProviderTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/provider/CachingKeyProviderTest.java index ea8fc4ffc..390b210f6 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/provider/CachingKeyProviderTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/provider/CachingKeyProviderTest.java @@ -1,23 +1,29 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.provider; +package org.eclipse.tractusx.edc.data.encryption.provider; import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.stream.Stream; -import net.catenax.edc.data.encryption.key.CryptoKey; +import org.eclipse.tractusx.edc.data.encryption.key.CryptoKey; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; diff --git a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/util/ArrayUtilTest.java b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/util/ArrayUtilTest.java similarity index 71% rename from edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/util/ArrayUtilTest.java rename to edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/util/ArrayUtilTest.java index 611585c86..45b604b64 100644 --- a/edc-extensions/data-encryption/src/test/java/net/catenax/edc/data/encryption/util/ArrayUtilTest.java +++ b/edc-extensions/data-encryption/src/test/java/org/eclipse/tractusx/edc/data/encryption/util/ArrayUtilTest.java @@ -1,17 +1,23 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.data.encryption.util; +package org.eclipse.tractusx.edc.data.encryption.util; import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; diff --git a/edc-extensions/dataplane-selector-configuration/build.gradle.kts b/edc-extensions/dataplane-selector-configuration/build.gradle.kts new file mode 100644 index 000000000..70714bd52 --- /dev/null +++ b/edc-extensions/dataplane-selector-configuration/build.gradle.kts @@ -0,0 +1,13 @@ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + api(edc.spi.core) + api(edc.junit) + implementation(edc.spi.dataplane.selector) + implementation(edc.spi.dataplane.transfer) + implementation(libs.bouncyCastle.bcpkix) +} diff --git a/edc-extensions/dataplane-selector-configuration/pom.xml b/edc-extensions/dataplane-selector-configuration/pom.xml deleted file mode 100644 index 82ddc06b6..000000000 --- a/edc-extensions/dataplane-selector-configuration/pom.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - edc-extensions - net.catenax.edc.extensions - 0.1.6 - - 4.0.0 - - dataplane-selector-configuration - jar - - - ${project.groupId}_${project.artifactId} - - - - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - - org.eclipse.dataspaceconnector - core-spi - - - org.eclipse.dataspaceconnector - data-plane-selector-spi - - - - - org.eclipse.dataspaceconnector - junit - test - - - org.eclipse.dataspaceconnector - junit - test-fixtures - test - - - diff --git a/edc-extensions/dataplane-selector-configuration/src/main/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtension.java b/edc-extensions/dataplane-selector-configuration/src/main/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtension.java similarity index 55% rename from edc-extensions/dataplane-selector-configuration/src/main/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtension.java rename to edc-extensions/dataplane-selector-configuration/src/main/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtension.java index 68072498e..d80fd53db 100644 --- a/edc-extensions/dataplane-selector-configuration/src/main/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtension.java +++ b/edc-extensions/dataplane-selector-configuration/src/main/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtension.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial implementation + * 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 net.catenax.edc.dataplane.selector.configuration; +package org.eclipse.tractusx.edc.dataplane.selector.configuration; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -22,76 +28,24 @@ import java.util.Map; import java.util.function.Predicate; import java.util.stream.Collectors; -import org.eclipse.dataspaceconnector.dataplane.selector.DataPlaneSelectorService; -import org.eclipse.dataspaceconnector.dataplane.selector.instance.DataPlaneInstanceImpl; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.EdcSetting; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.system.Requires; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtension; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.spi.system.configuration.Config; - -/** - * This Extension provides functionality to read materialized DataPlane instances from the - * configuration file and add those to the DataPlaneSelectorService during - * configuration/initialization phase of the connector. - * - *

Following configuration keys are made available: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
KeyDescriptionMandatoryExample
edc.dataplane.selector..urlURL to connect to the Data Plane Instance.Xhttp://localhost:8181/control/transfer
edc.dataplane.selector..sourcetypesSource Types in a comma separated List.XHttpData
edc.dataplane.selector..destinationtypesDestination Types in a comma separated List.XHttpProxy
edc.dataplane.selector..propertiesAdditional properties of the Data Plane - * Instance.(X){ "publicApiUrl:": "http://localhost:8181/api/public" - * }
- */ +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; +import org.eclipse.edc.connector.dataplane.selector.spi.instance.DataPlaneInstance; +import org.eclipse.edc.runtime.metamodel.annotation.Requires; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.configuration.Config; + @Requires({DataPlaneSelectorService.class}) public class DataPlaneSelectorConfigurationServiceExtension implements ServiceExtension { - @EdcSetting public static final String CONFIG_PREFIX = "edc.dataplane.selector"; - @EdcSetting public static final String URL_SUFFIX = "url"; - @EdcSetting public static final String DESTINATION_TYPES_SUFFIX = "destinationtypes"; - @EdcSetting public static final String SOURCE_TYPES_SUFFIX = "sourcetypes"; - @EdcSetting public static final String PROPERTIES_SUFFIX = "properties"; - @EdcSetting public static final String PUBLIC_API_URL_PROPERTY = "publicApiUrl"; + public static final String CONFIG_PREFIX = "edc.dataplane.selector"; + public static final String URL_SUFFIX = "url"; + public static final String DESTINATION_TYPES_SUFFIX = "destinationtypes"; + public static final String SOURCE_TYPES_SUFFIX = "sourcetypes"; + public static final String PROPERTIES_SUFFIX = "properties"; + public static final String PUBLIC_API_URL_PROPERTY = "publicApiUrl"; private static final String NAME = "Data Plane Selector Configuration Extension"; private static final String COMMA = ","; @@ -175,8 +129,8 @@ private void configureDataPlaneInstance(final Config config) { return; } - final DataPlaneInstanceImpl.Builder builder = - DataPlaneInstanceImpl.Builder.newInstance().id(id).url(url); + final DataPlaneInstance.Builder builder = + DataPlaneInstance.Builder.newInstance().id(id).url(url); sourceTypes.forEach(builder::allowedSourceType); destinationTypes.forEach(builder::allowedDestType); diff --git a/edc-extensions/dataplane-selector-configuration/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension b/edc-extensions/dataplane-selector-configuration/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension deleted file mode 100644 index f23f403dd..000000000 --- a/edc-extensions/dataplane-selector-configuration/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: -# Mercedes-Benz Tech Innovation GmbH - Initial ServiceExtension file -# -# - -net.catenax.edc.dataplane.selector.configuration.DataPlaneSelectorConfigurationServiceExtension diff --git a/edc-extensions/dataplane-selector-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/dataplane-selector-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..7abfadd3c --- /dev/null +++ b/edc-extensions/dataplane-selector-configuration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,21 @@ +# +# Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2022 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +org.eclipse.tractusx.edc.dataplane.selector.configuration.DataPlaneSelectorConfigurationServiceExtension diff --git a/edc-extensions/dataplane-selector-configuration/src/test/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionEdcExtensionTest.java b/edc-extensions/dataplane-selector-configuration/src/test/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionEdcExtensionTest.java similarity index 80% rename from edc-extensions/dataplane-selector-configuration/src/test/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionEdcExtensionTest.java rename to edc-extensions/dataplane-selector-configuration/src/test/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionEdcExtensionTest.java index 8d162e0d3..fef84076a 100644 --- a/edc-extensions/dataplane-selector-configuration/src/test/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionEdcExtensionTest.java +++ b/edc-extensions/dataplane-selector-configuration/src/test/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionEdcExtensionTest.java @@ -1,27 +1,33 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Added Test + * 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 net.catenax.edc.dataplane.selector.configuration; +package org.eclipse.tractusx.edc.dataplane.selector.configuration; import java.util.HashMap; import java.util.Map; -import org.eclipse.dataspaceconnector.dataplane.selector.DataPlaneSelectorService; -import org.eclipse.dataspaceconnector.junit.extensions.EdcExtension; -import org.eclipse.dataspaceconnector.spi.system.Provides; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtension; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.spi.types.domain.DataAddress; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; +import org.eclipse.edc.junit.extensions.EdcExtension; +import org.eclipse.edc.runtime.metamodel.annotation.Provides; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.domain.DataAddress; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -142,9 +148,7 @@ void registersDataPlaneInstance() { private class TestExtension implements ServiceExtension { public void initialize(ServiceExtensionContext context) { - context.registerService( - org.eclipse.dataspaceconnector.dataplane.selector.DataPlaneSelectorService.class, - dataPlaneSelectorService); + context.registerService(DataPlaneSelectorService.class, dataPlaneSelectorService); } } } diff --git a/edc-extensions/dataplane-selector-configuration/src/test/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionTest.java b/edc-extensions/dataplane-selector-configuration/src/test/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionTest.java similarity index 86% rename from edc-extensions/dataplane-selector-configuration/src/test/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionTest.java rename to edc-extensions/dataplane-selector-configuration/src/test/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionTest.java index 58a744fc5..5a9298e83 100644 --- a/edc-extensions/dataplane-selector-configuration/src/test/java/net/catenax/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionTest.java +++ b/edc-extensions/dataplane-selector-configuration/src/test/java/org/eclipse/tractusx/edc/dataplane/selector/configuration/DataPlaneSelectorConfigurationServiceExtensionTest.java @@ -1,29 +1,35 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Added Test + * 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 net.catenax.edc.dataplane.selector.configuration; +package org.eclipse.tractusx.edc.dataplane.selector.configuration; import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; -import org.eclipse.dataspaceconnector.dataplane.selector.DataPlaneSelectorService; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.spi.system.configuration.Config; -import org.eclipse.dataspaceconnector.spi.system.configuration.ConfigFactory; -import org.eclipse.dataspaceconnector.spi.types.domain.DataAddress; +import org.eclipse.edc.connector.dataplane.selector.spi.DataPlaneSelectorService; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.configuration.Config; +import org.eclipse.edc.spi.system.configuration.ConfigFactory; +import org.eclipse.edc.spi.types.domain.DataAddress; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/hashicorp-vault/build.gradle.kts b/edc-extensions/hashicorp-vault/build.gradle.kts new file mode 100644 index 000000000..90758edd0 --- /dev/null +++ b/edc-extensions/hashicorp-vault/build.gradle.kts @@ -0,0 +1,15 @@ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + implementation(edc.spi.core) + implementation(edc.junit) + implementation(libs.bouncyCastle.bcpkix) + implementation(libs.okhttp) + implementation("org.testcontainers:junit-jupiter:1.17.6") + implementation("org.testcontainers:vault:1.17.6") + testImplementation(libs.mockito.inline) +} diff --git a/edc-extensions/hashicorp-vault/pom.xml b/edc-extensions/hashicorp-vault/pom.xml deleted file mode 100644 index 9d7916162..000000000 --- a/edc-extensions/hashicorp-vault/pom.xml +++ /dev/null @@ -1,199 +0,0 @@ - - - - - net.catenax.edc.extensions - edc-extensions - 0.1.6 - - 4.0.0 - - hashicorp-vault - jar - - - ${project.basedir}/src/main/java - ${originalSourceDirectory} - ${project.build.directory}/delombok - ${project.groupId}_${project.artifactId} - - - - ${sourceDirectory} - - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - ${project.build.sourceEncoding} - - - org.projectlombok - lombok - ${org.projectlombok.lombok.version} - - - - - - - org.projectlombok - lombok-maven-plugin - ${org.projectlombok.lombok.maven.plugin.version} - - - generate-sources - - delombok - - - - - ${originalSourceDirectory} - ${delombokSourceDirectory} - false - UTF-8 - - skip - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - - - - - - org.eclipse.dataspaceconnector - core-spi - - - org.eclipse.dataspaceconnector - junit - test - - - org.eclipse.dataspaceconnector - junit - test-fixtures - test - - - - - org.projectlombok - lombok - - - org.bouncycastle - bcpkix-jdk15on - - - com.squareup.okhttp3 - okhttp - - - - - org.junit.jupiter - junit-jupiter - test - - - org.mockito - mockito-core - test - - - org.mockito - mockito-inline - test - - - org.testcontainers - junit-jupiter - test - - - org.testcontainers - vault - ${org.testcontainers.version} - test - - - ch.qos.logback - logback-core - test - - - org.slf4j - slf4j-api - test - - - org.slf4j - jul-to-slf4j - test - - - org.hamcrest - hamcrest - test - - - - - - - delombok - - ${delombokSourceDirectory} - - - - diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultCreateEntryRequestPayload.java b/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultCreateEntryRequestPayload.java deleted file mode 100644 index 4882c5477..000000000 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultCreateEntryRequestPayload.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.hashicorpvault; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -class HashicorpVaultCreateEntryRequestPayload { - - @JsonProperty("options") - private Options options; - - @JsonProperty("data") - private Map data; - - @Builder - @NoArgsConstructor - @AllArgsConstructor - @Data - @JsonIgnoreProperties(ignoreUnknown = true) - static class Options { - @JsonProperty("cas") - private Integer cas; - } -} diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultCreateEntryResponsePayload.java b/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultCreateEntryResponsePayload.java deleted file mode 100644 index 0818c77a7..000000000 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultCreateEntryResponsePayload.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.hashicorpvault; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -class HashicorpVaultCreateEntryResponsePayload { - - @JsonProperty("data") - private HashicorpVaultEntryMetadata data; -} diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultEntryMetadata.java b/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultEntryMetadata.java deleted file mode 100644 index ce9f16b7b..000000000 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultEntryMetadata.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.hashicorpvault; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -class HashicorpVaultEntryMetadata { - - @JsonProperty("custom_metadata") - private Map customMetadata; - - @JsonProperty("destroyed") - private Boolean destroyed; - - @JsonProperty("version") - private Integer version; -} diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultException.java b/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultException.java deleted file mode 100644 index af106bb58..000000000 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.hashicorpvault; - -import org.eclipse.dataspaceconnector.spi.EdcException; - -public class HashicorpVaultException extends EdcException { - - public HashicorpVaultException(String message) { - super(message); - } - - public HashicorpVaultException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultGetEntryResponsePayload.java b/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultGetEntryResponsePayload.java deleted file mode 100644 index 712c92421..000000000 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultGetEntryResponsePayload.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.hashicorpvault; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import java.util.Map; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Data -@JsonIgnoreProperties(ignoreUnknown = true) -class HashicorpVaultGetEntryResponsePayload { - - @JsonProperty("data") - private GetVaultEntryData data; - - @Builder - @NoArgsConstructor - @AllArgsConstructor - @Data - @JsonIgnoreProperties(ignoreUnknown = true) - static class GetVaultEntryData { - - @JsonProperty("data") - private Map data; - - @JsonProperty("metadata") - private HashicorpVaultEntryMetadata metadata; - } -} diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/AbstractHashicorpVaultExtension.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/AbstractHashicorpVaultExtension.java similarity index 75% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/AbstractHashicorpVaultExtension.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/AbstractHashicorpVaultExtension.java index 4512e8512..dae92725f 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/AbstractHashicorpVaultExtension.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/AbstractHashicorpVaultExtension.java @@ -1,23 +1,28 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Add vault health check + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.time.Duration; import okhttp3.OkHttpClient; -import org.eclipse.dataspaceconnector.spi.EdcSetting; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.ServiceExtensionContext; /** * Temporary solution as long as the Vault components needs to be loaded as dedicated vault @@ -25,29 +30,23 @@ */ public class AbstractHashicorpVaultExtension { - @EdcSetting(required = true) public static final String VAULT_URL = "edc.vault.hashicorp.url"; - @EdcSetting(required = true) public static final String VAULT_TOKEN = "edc.vault.hashicorp.token"; - @EdcSetting public static final String VAULT_API_SECRET_PATH = "edc.vault.hashicorp.api.secret.path"; public static final String VAULT_API_SECRET_PATH_DEFAULT = "/v1/secret"; - @EdcSetting public static final String VAULT_API_HEALTH_PATH = "edc.vault.hashicorp.api.health.check.path"; public static final String VAULT_API_HEALTH_PATH_DEFAULT = "/v1/sys/health"; - @EdcSetting public static final String VAULT_HEALTH_CHECK_STANDBY_OK = "edc.vault.hashicorp.health.check.standby.ok"; public static final boolean VAULT_HEALTH_CHECK_STANDBY_OK_DEFAULT = false; - @EdcSetting private static final String VAULT_TIMEOUT_SECONDS = "edc.vault.hashicorp.timeout.seconds"; protected OkHttpClient createOkHttpClient(HashicorpVaultClientConfig config) { diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolver.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolver.java similarity index 54% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolver.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolver.java index f067aec92..ed807cbb8 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolver.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolver.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -21,10 +27,10 @@ import java.security.cert.X509Certificate; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.EdcException; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.security.CertificateResolver; -import org.eclipse.dataspaceconnector.spi.security.Vault; +import org.eclipse.edc.spi.EdcException; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.security.CertificateResolver; +import org.eclipse.edc.spi.security.Vault; /** Resolves an X.509 certificate in Hashicorp vault. */ @RequiredArgsConstructor diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVault.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVault.java similarity index 52% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVault.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVault.java index 6fe484081..e8a59937a 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVault.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVault.java @@ -1,24 +1,30 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.result.Result; -import org.eclipse.dataspaceconnector.spi.security.Vault; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.security.Vault; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultClient.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClient.java similarity index 86% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultClient.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClient.java index 754ac5928..850c33243 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultClient.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClient.java @@ -1,19 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * Mercedes-Benz Tech Innovation GmbH - Make secret data & metadata paths configurable - * Mercedes-Benz Tech Innovation GmbH - Add vault health check + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; @@ -32,7 +37,7 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; -import org.eclipse.dataspaceconnector.spi.result.Result; +import org.eclipse.edc.spi.result.Result; import org.jetbrains.annotations.NotNull; @RequiredArgsConstructor @@ -95,7 +100,8 @@ public HashicorpVaultHealthResponse getHealth() throws IOException { objectMapper.readValue(responseBody, HashicorpVaultHealthResponsePayload.class); healthResponseBuilder.payload(responsePayload); } catch (JsonMappingException e) { - // ignore. status code not checked, so it may be possible that no payload was provided + // ignore. status code not checked, so it may be possible that no payload was + // provided } } @@ -156,13 +162,16 @@ private Headers getHeaders() { private HttpUrl getSecretUrl(String key, String entryType) { key = URLEncoder.encode(key, StandardCharsets.UTF_8); + // restore '/' characters to allow sub-directories + key = key.replace("%2F", "/"); + final String vaultApiPath = config.getVaultApiSecretPath(); return Objects.requireNonNull(HttpUrl.parse(config.getVaultUrl())) .newBuilder() .addPathSegments(PathUtil.trimLeadingOrEndingSlash(vaultApiPath)) .addPathSegment(entryType) - .addPathSegment(key) + .addPathSegments(key) .build(); } @@ -170,7 +179,8 @@ private HttpUrl getHealthUrl() { final String vaultHealthPath = config.getVaultApiHealthPath(); final boolean isVaultHealthStandbyOk = config.isVaultApiHealthStandbyOk(); - // by setting 'standbyok' and/or 'perfstandbyok' the vault will return an active status + // by setting 'standbyok' and/or 'perfstandbyok' the vault will return an active + // status // code instead of the standby status codes return Objects.requireNonNull(HttpUrl.parse(config.getVaultUrl())) diff --git a/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClientConfig.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClientConfig.java new file mode 100644 index 000000000..495d6937c --- /dev/null +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClientConfig.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.hashicorpvault; + +import java.time.Duration; +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +@Builder +@Getter +@RequiredArgsConstructor +class HashicorpVaultClientConfig { + @NonNull private final String vaultUrl; + @NonNull private final String vaultToken; + @NonNull private final String vaultApiSecretPath; + @NonNull private final String vaultApiHealthPath; + @NonNull private final Duration timeout; + + private final boolean isVaultApiHealthStandbyOk; +} diff --git a/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultCreateEntryRequestPayload.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultCreateEntryRequestPayload.java new file mode 100644 index 000000000..fa31d7149 --- /dev/null +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultCreateEntryRequestPayload.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.hashicorpvault; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +class HashicorpVaultCreateEntryRequestPayload { + + @JsonProperty("options") + private Options options; + + @JsonProperty("data") + private Map data; + + @Builder + @NoArgsConstructor + @AllArgsConstructor + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + static class Options { + @JsonProperty("cas") + private Integer cas; + } +} diff --git a/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultCreateEntryResponsePayload.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultCreateEntryResponsePayload.java new file mode 100644 index 000000000..77ab76772 --- /dev/null +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultCreateEntryResponsePayload.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.hashicorpvault; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +class HashicorpVaultCreateEntryResponsePayload { + + @JsonProperty("data") + private HashicorpVaultEntryMetadata data; +} diff --git a/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultEntryMetadata.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultEntryMetadata.java new file mode 100644 index 000000000..bd59309c9 --- /dev/null +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultEntryMetadata.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.hashicorpvault; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +class HashicorpVaultEntryMetadata { + + @JsonProperty("custom_metadata") + private Map customMetadata; + + @JsonProperty("destroyed") + private Boolean destroyed; + + @JsonProperty("version") + private Integer version; +} diff --git a/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultException.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultException.java new file mode 100644 index 000000000..bd3c60549 --- /dev/null +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.hashicorpvault; + +import org.eclipse.edc.spi.EdcException; + +public class HashicorpVaultException extends EdcException { + + public HashicorpVaultException(String message) { + super(message); + } + + public HashicorpVaultException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultGetEntryResponsePayload.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultGetEntryResponsePayload.java new file mode 100644 index 000000000..175c73d47 --- /dev/null +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultGetEntryResponsePayload.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.hashicorpvault; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +class HashicorpVaultGetEntryResponsePayload { + + @JsonProperty("data") + private GetVaultEntryData data; + + @Builder + @NoArgsConstructor + @AllArgsConstructor + @Data + @JsonIgnoreProperties(ignoreUnknown = true) + static class GetVaultEntryData { + + @JsonProperty("data") + private Map data; + + @JsonProperty("metadata") + private HashicorpVaultEntryMetadata metadata; + } +} diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheck.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheck.java similarity index 89% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheck.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheck.java index e2177d157..9834b0d03 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheck.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheck.java @@ -12,15 +12,15 @@ * */ -package net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.io.IOException; import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.system.health.HealthCheckResult; -import org.eclipse.dataspaceconnector.spi.system.health.LivenessProvider; -import org.eclipse.dataspaceconnector.spi.system.health.ReadinessProvider; -import org.eclipse.dataspaceconnector.spi.system.health.StartupStatusProvider; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.health.HealthCheckResult; +import org.eclipse.edc.spi.system.health.LivenessProvider; +import org.eclipse.edc.spi.system.health.ReadinessProvider; +import org.eclipse.edc.spi.system.health.StartupStatusProvider; @RequiredArgsConstructor public class HashicorpVaultHealthCheck diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthExtension.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthExtension.java similarity index 60% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthExtension.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthExtension.java index 9e904a2c7..5b7cca1a3 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthExtension.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthExtension.java @@ -1,31 +1,35 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Add vault health check + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import okhttp3.OkHttpClient; -import org.eclipse.dataspaceconnector.spi.EdcSetting; -import org.eclipse.dataspaceconnector.spi.system.Requires; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtension; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.spi.system.health.HealthCheckService; +import org.eclipse.edc.runtime.metamodel.annotation.Requires; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.health.HealthCheckService; @Requires(HealthCheckService.class) public class HashicorpVaultHealthExtension extends AbstractHashicorpVaultExtension implements ServiceExtension { - @EdcSetting public static final String VAULT_HEALTH_CHECK = "edc.vault.hashicorp.health.check.enabled"; public static final boolean VAULT_HEALTH_CHECK_DEFAULT = true; diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthResponse.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthResponse.java similarity index 97% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthResponse.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthResponse.java index b987c7041..bbf991684 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthResponse.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthResponse.java @@ -12,7 +12,7 @@ * */ -package net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import lombok.Builder; import lombok.Getter; diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthResponsePayload.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthResponsePayload.java similarity index 96% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthResponsePayload.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthResponsePayload.java index d63b71408..67ef6533c 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthResponsePayload.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthResponsePayload.java @@ -12,7 +12,7 @@ * */ -package net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultVaultExtension.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultVaultExtension.java similarity index 51% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultVaultExtension.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultVaultExtension.java index f6afafb07..d8b41b2c1 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultVaultExtension.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultVaultExtension.java @@ -1,29 +1,33 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * Mercedes-Benz Tech Innovation GmbH - Make secret data & metadata paths configurable - * Mercedes-Benz Tech Innovation GmbH - Add vault health check + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import okhttp3.OkHttpClient; -import org.eclipse.dataspaceconnector.spi.security.CertificateResolver; -import org.eclipse.dataspaceconnector.spi.security.PrivateKeyResolver; -import org.eclipse.dataspaceconnector.spi.security.Vault; -import org.eclipse.dataspaceconnector.spi.security.VaultPrivateKeyResolver; -import org.eclipse.dataspaceconnector.spi.system.Provides; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtension; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; +import org.eclipse.edc.runtime.metamodel.annotation.Provides; +import org.eclipse.edc.spi.security.CertificateResolver; +import org.eclipse.edc.spi.security.PrivateKeyResolver; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.security.VaultPrivateKeyResolver; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; @Provides({Vault.class, CertificateResolver.class, PrivateKeyResolver.class}) public class HashicorpVaultVaultExtension extends AbstractHashicorpVaultExtension diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/PathUtil.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/PathUtil.java similarity index 93% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/PathUtil.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/PathUtil.java index fe5bb69fa..f22895355 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/PathUtil.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/PathUtil.java @@ -12,7 +12,7 @@ * */ -package net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; final class PathUtil { diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/PemUtil.java b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/PemUtil.java similarity index 63% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/PemUtil.java rename to edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/PemUtil.java index 8e72fdfb1..6596d781b 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/PemUtil.java +++ b/edc-extensions/hashicorp-vault/src/main/java/org/eclipse/tractusx/edc/hashicorpvault/PemUtil.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.io.IOException; import java.io.InputStream; diff --git a/edc-extensions/hashicorp-vault/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension b/edc-extensions/hashicorp-vault/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension deleted file mode 100644 index 11f7b3617..000000000 --- a/edc-extensions/hashicorp-vault/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: -# Mercedes-Benz Tech Innovation GmbH - Initial ServiceExtension file -# -net.catenax.edc.hashicorpvault.HashicorpVaultHealthExtension -net.catenax.edc.hashicorpvault.HashicorpVaultVaultExtension diff --git a/edc-extensions/hashicorp-vault/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/hashicorp-vault/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..b8d59a5b0 --- /dev/null +++ b/edc-extensions/hashicorp-vault/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,24 @@ +# +# Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2022 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 +# +# Contributors: +# Mercedes-Benz Tech Innovation GmbH - Initial ServiceExtension file +# +org.eclipse.tractusx.edc.hashicorpvault.HashicorpVaultHealthExtension +org.eclipse.tractusx.edc.hashicorpvault.HashicorpVaultVaultExtension diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/AbstractHashicorpIT.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/AbstractHashicorpIT.java similarity index 70% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/AbstractHashicorpIT.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/AbstractHashicorpIT.java index 57b2b584e..e196cd27d 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/AbstractHashicorpIT.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/AbstractHashicorpIT.java @@ -1,22 +1,28 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; -import static net.catenax.edc.hashicorpvault.HashicorpVaultClient.VAULT_DATA_ENTRY_NAME; -import static net.catenax.edc.hashicorpvault.HashicorpVaultVaultExtension.VAULT_TOKEN; -import static net.catenax.edc.hashicorpvault.HashicorpVaultVaultExtension.VAULT_URL; +import static org.eclipse.tractusx.edc.hashicorpvault.HashicorpVaultClient.VAULT_DATA_ENTRY_NAME; +import static org.eclipse.tractusx.edc.hashicorpvault.HashicorpVaultVaultExtension.VAULT_TOKEN; +import static org.eclipse.tractusx.edc.hashicorpvault.HashicorpVaultVaultExtension.VAULT_URL; import java.util.ArrayList; import java.util.HashMap; @@ -25,17 +31,17 @@ import java.util.UUID; import java.util.stream.Collectors; import lombok.Getter; -import org.eclipse.dataspaceconnector.junit.extensions.EdcExtension; -import org.eclipse.dataspaceconnector.spi.security.CertificateResolver; -import org.eclipse.dataspaceconnector.spi.security.Vault; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtension; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.spi.system.health.HealthCheckResult; -import org.eclipse.dataspaceconnector.spi.system.health.HealthCheckService; -import org.eclipse.dataspaceconnector.spi.system.health.HealthStatus; -import org.eclipse.dataspaceconnector.spi.system.health.LivenessProvider; -import org.eclipse.dataspaceconnector.spi.system.health.ReadinessProvider; -import org.eclipse.dataspaceconnector.spi.system.health.StartupStatusProvider; +import org.eclipse.edc.junit.extensions.EdcExtension; +import org.eclipse.edc.spi.security.CertificateResolver; +import org.eclipse.edc.spi.security.Vault; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.health.HealthCheckResult; +import org.eclipse.edc.spi.system.health.HealthCheckService; +import org.eclipse.edc.spi.system.health.HealthStatus; +import org.eclipse.edc.spi.system.health.LivenessProvider; +import org.eclipse.edc.spi.system.health.ReadinessProvider; +import org.eclipse.edc.spi.system.health.StartupStatusProvider; import org.junit.ClassRule; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolverIT.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolverIT.java similarity index 56% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolverIT.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolverIT.java index 77d26e6df..48fc06eca 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolverIT.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolverIT.java @@ -1,24 +1,30 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.security.cert.X509Certificate; import java.util.UUID; import lombok.SneakyThrows; -import org.eclipse.dataspaceconnector.spi.security.CertificateResolver; -import org.eclipse.dataspaceconnector.spi.security.Vault; +import org.eclipse.edc.spi.security.CertificateResolver; +import org.eclipse.edc.spi.security.Vault; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolverTest.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolverTest.java similarity index 61% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolverTest.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolverTest.java index 4a485cf4b..754bdda28 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpCertificateResolverTest.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpCertificateResolverTest.java @@ -1,22 +1,28 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.security.cert.X509Certificate; import lombok.SneakyThrows; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; +import org.eclipse.edc.spi.monitor.Monitor; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultClientTest.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClientTest.java similarity index 91% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultClientTest.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClientTest.java index 525881619..2bddac46e 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultClientTest.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultClientTest.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import com.fasterxml.jackson.databind.ObjectMapper; import java.time.Duration; @@ -23,7 +29,7 @@ import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; -import org.eclipse.dataspaceconnector.spi.result.Result; +import org.eclipse.edc.spi.result.Result; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.Mockito; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultExtensionTest.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultExtensionTest.java similarity index 71% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultExtensionTest.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultExtensionTest.java index 212477ced..dfba9fe1c 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultExtensionTest.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultExtensionTest.java @@ -1,23 +1,29 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.spi.system.health.HealthCheckService; -import org.eclipse.dataspaceconnector.spi.types.TypeManager; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.health.HealthCheckService; +import org.eclipse.edc.spi.types.TypeManager; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheckExtensionTest.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheckExtensionTest.java similarity index 78% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheckExtensionTest.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheckExtensionTest.java index 71605bd3e..5991f8c1e 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheckExtensionTest.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheckExtensionTest.java @@ -1,23 +1,29 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.spi.system.health.HealthCheckService; -import org.eclipse.dataspaceconnector.spi.types.TypeManager; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.health.HealthCheckService; +import org.eclipse.edc.spi.types.TypeManager; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheckTest.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheckTest.java similarity index 62% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheckTest.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheckTest.java index da198ba84..3abf95289 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultHealthCheckTest.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultHealthCheckTest.java @@ -1,22 +1,28 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.io.IOException; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.system.health.HealthCheckResult; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.health.HealthCheckResult; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultIT.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultIT.java similarity index 54% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultIT.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultIT.java index e23c5a9f0..f6cb202b8 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultIT.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultIT.java @@ -1,24 +1,32 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.util.UUID; -import org.eclipse.dataspaceconnector.spi.security.Vault; +import org.eclipse.edc.spi.security.Vault; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; class HashicorpVaultIT extends AbstractHashicorpIT { @@ -30,6 +38,30 @@ void testResolveSecret_exists() { Assertions.assertEquals(VAULT_ENTRY_VALUE, secretValue); } + @Test + @DisplayName("Resolve a secret from a sub directory") + void testResolveSecret_inASubDirectory() { + Vault vault = getVault(); + String key = "sub/" + VAULT_ENTRY_KEY; + String value = key + "value"; + + vault.storeSecret(key, value); + String secretValue = vault.resolveSecret(key); + Assertions.assertEquals(value, secretValue); + } + + @ParameterizedTest + @ValueSource(strings = {"foo!bar", "foo.bar", "foo[bar]", "sub/foo{bar}"}) + @DisplayName("Resolve a secret with url encoded characters") + void testResolveSecret_withUrlEncodedCharacters(String key) { + Vault vault = getVault(); + String value = key + "value"; + + vault.storeSecret(key, value); + String secretValue = vault.resolveSecret(key); + Assertions.assertEquals(value, secretValue); + } + @Test @DisplayName("Resolve a secret that does not exist") void testResolveSecret_doesNotExist() { diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultTest.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultTest.java similarity index 81% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultTest.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultTest.java index 5b98c4f6e..03512f2a6 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/HashicorpVaultTest.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/HashicorpVaultTest.java @@ -1,23 +1,29 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Test + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.util.UUID; import lombok.SneakyThrows; -import org.eclipse.dataspaceconnector.spi.monitor.Monitor; -import org.eclipse.dataspaceconnector.spi.result.Result; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.result.Result; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/PathUtilTest.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/PathUtilTest.java similarity index 96% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/PathUtilTest.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/PathUtilTest.java index 01fb0f40a..a5d9821dd 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/PathUtilTest.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/PathUtilTest.java @@ -12,7 +12,7 @@ * */ -package net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; diff --git a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/X509CertificateTestUtil.java b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/X509CertificateTestUtil.java similarity index 86% rename from edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/X509CertificateTestUtil.java rename to edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/X509CertificateTestUtil.java index 210928a88..051fe00eb 100644 --- a/edc-extensions/hashicorp-vault/src/test/java/net/catenax/edc/hashicorpvault/X509CertificateTestUtil.java +++ b/edc-extensions/hashicorp-vault/src/test/java/org/eclipse/tractusx/edc/hashicorpvault/X509CertificateTestUtil.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.hashicorpvault; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/edc-extensions/hashicorp-vault/src/test/resources/logback.xml b/edc-extensions/hashicorp-vault/src/test/resources/logback.xml index 3347fcbae..fcc51d48d 100644 --- a/edc-extensions/hashicorp-vault/src/test/resources/logback.xml +++ b/edc-extensions/hashicorp-vault/src/test/resources/logback.xml @@ -1,13 +1,22 @@ diff --git a/edc-extensions/pom.xml b/edc-extensions/pom.xml deleted file mode 100644 index c688c97a1..000000000 --- a/edc-extensions/pom.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - net.catenax.edc - product-edc-parent - 0.1.6 - - 4.0.0 - - net.catenax.edc.extensions - edc-extensions - pom - - - ${project.groupId}_${project.artifactId} - - - - business-partner-validation - postgresql-migration - hashicorp-vault - dataplane-selector-configuration - data-encryption - cx-oauth2 - - - diff --git a/edc-extensions/postgresql-migration/build.gradle.kts b/edc-extensions/postgresql-migration/build.gradle.kts new file mode 100644 index 000000000..8d7b1fa05 --- /dev/null +++ b/edc-extensions/postgresql-migration/build.gradle.kts @@ -0,0 +1,15 @@ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + implementation(edc.spi.core) + implementation(edc.junit) + implementation(edc.spi.transaction.datasource) + implementation(edc.sql.assetindex) + implementation(edc.sql.core) + + implementation("org.flywaydb:flyway-core:9.15.2") +} diff --git a/edc-extensions/postgresql-migration/pom.xml b/edc-extensions/postgresql-migration/pom.xml deleted file mode 100644 index 7532d0fee..000000000 --- a/edc-extensions/postgresql-migration/pom.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - - edc-extensions - net.catenax.edc.extensions - 0.1.6 - - 4.0.0 - - postgresql-migration - jar - - - ${project.groupId}_${project.artifactId} - - - - - - src/main/resources - - **/* - - - - ../../ - META-INF - - NOTICE.md - LICENSE - - - - - - - - org.eclipse.dataspaceconnector - transaction-datasource-spi - - - org.eclipse.dataspaceconnector - transaction-spi - - - - - org.eclipse.dataspaceconnector - asset-index-sql - compile - - - - - org.eclipse.dataspaceconnector - common-sql - - - - - org.flywaydb - flyway-core - - - \ No newline at end of file diff --git a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/AssetPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/AssetPostgresqlMigrationExtension.java deleted file mode 100644 index 9876d17ea..000000000 --- a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/AssetPostgresqlMigrationExtension.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial implementation - * - */ - -package net.catenax.edc.postgresql.migration; - -import org.eclipse.dataspaceconnector.sql.assetindex.ConfigurationKeys; - -public class AssetPostgresqlMigrationExtension extends AbstractPostgresqlMigrationExtension { - private static final String NAME_SUBSYSTEM = "asset"; - - protected String getDataSourceNameConfigurationKey() { - return ConfigurationKeys.DATASOURCE_SETTING_NAME; - } - - protected String getSubsystemName() { - return NAME_SUBSYSTEM; - } -} diff --git a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/ContractDefinitionPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/ContractDefinitionPostgresqlMigrationExtension.java deleted file mode 100644 index 1834cde8f..000000000 --- a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/ContractDefinitionPostgresqlMigrationExtension.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial implementation - * - */ - -package net.catenax.edc.postgresql.migration; - -import org.eclipse.dataspaceconnector.spi.EdcSetting; - -public class ContractDefinitionPostgresqlMigrationExtension - extends AbstractPostgresqlMigrationExtension { - private static final String NAME_SUBSYSTEM = "contractdefinition"; - - @EdcSetting - private static final String DATASOURCE_SETTING_NAME = "edc.datasource.contractdefinition.name"; - - protected String getDataSourceNameConfigurationKey() { - return DATASOURCE_SETTING_NAME; - } - - protected String getSubsystemName() { - return NAME_SUBSYSTEM; - } -} diff --git a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/ContractNegotiationPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/ContractNegotiationPostgresqlMigrationExtension.java deleted file mode 100644 index 8c732742f..000000000 --- a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/ContractNegotiationPostgresqlMigrationExtension.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial implementation - * - */ - -package net.catenax.edc.postgresql.migration; - -import org.eclipse.dataspaceconnector.spi.EdcSetting; - -public class ContractNegotiationPostgresqlMigrationExtension - extends AbstractPostgresqlMigrationExtension { - private static final String NAME_SUBSYSTEM = "contractnegotiation"; - - @EdcSetting - private static final String DATASOURCE_SETTING_NAME = "edc.datasource.contractnegotiation.name"; - - protected String getDataSourceNameConfigurationKey() { - return DATASOURCE_SETTING_NAME; - } - - protected String getSubsystemName() { - return NAME_SUBSYSTEM; - } -} diff --git a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/DriverManagerConnectionFactory.java b/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/DriverManagerConnectionFactory.java deleted file mode 100644 index 4e7c96220..000000000 --- a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/DriverManagerConnectionFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial implementation - * - */ - -package net.catenax.edc.postgresql.migration; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.util.Objects; -import java.util.Properties; -import org.eclipse.dataspaceconnector.spi.persistence.EdcPersistenceException; -import org.eclipse.dataspaceconnector.sql.ConnectionFactory; - -class DriverManagerConnectionFactory implements ConnectionFactory { - private final String jdbcUrl; - private final Properties properties; - - public DriverManagerConnectionFactory(final String jdbcUrl, final Properties properties) { - this.jdbcUrl = Objects.requireNonNull(jdbcUrl); - this.properties = Objects.requireNonNull(properties); - } - - @Override - public Connection create() { - try { - return DriverManager.getConnection(jdbcUrl, properties); - } catch (Exception exception) { - throw new EdcPersistenceException(exception.getMessage(), exception); - } - } -} diff --git a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/PolicyPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/PolicyPostgresqlMigrationExtension.java deleted file mode 100644 index 9e3b64ff9..000000000 --- a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/PolicyPostgresqlMigrationExtension.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial implementation - * - */ - -package net.catenax.edc.postgresql.migration; - -import org.eclipse.dataspaceconnector.spi.EdcSetting; - -public class PolicyPostgresqlMigrationExtension extends AbstractPostgresqlMigrationExtension { - private static final String NAME_SUBSYSTEM = "policy"; - - @EdcSetting private static final String DATASOURCE_SETTING_NAME = "edc.datasource.policy.name"; - - protected String getDataSourceNameConfigurationKey() { - return DATASOURCE_SETTING_NAME; - } - - protected String getSubsystemName() { - return NAME_SUBSYSTEM; - } -} diff --git a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/TransferProcessPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/TransferProcessPostgresqlMigrationExtension.java deleted file mode 100644 index 4ef0d97f4..000000000 --- a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/TransferProcessPostgresqlMigrationExtension.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial implementation - * - */ - -package net.catenax.edc.postgresql.migration; - -import org.eclipse.dataspaceconnector.spi.EdcSetting; - -public class TransferProcessPostgresqlMigrationExtension - extends AbstractPostgresqlMigrationExtension { - private static final String NAME_SUBSYSTEM = "transferprocess"; - - @EdcSetting - private static final String DATASOURCE_SETTING_NAME = "edc.datasource.transferprocess.name"; - - protected String getDataSourceNameConfigurationKey() { - return DATASOURCE_SETTING_NAME; - } - - protected String getSubsystemName() { - return NAME_SUBSYSTEM; - } -} diff --git a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java similarity index 68% rename from edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java rename to edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java index dbb17465a..ab0efc62d 100644 --- a/edc-extensions/postgresql-migration/src/main/java/net/catenax/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java +++ b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AbstractPostgresqlMigrationExtension.java @@ -1,26 +1,32 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.postgresql.migration; +package org.eclipse.tractusx.edc.postgresql.migration; import java.util.Objects; import java.util.Properties; -import org.eclipse.dataspaceconnector.spi.persistence.EdcPersistenceException; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtension; -import org.eclipse.dataspaceconnector.spi.system.ServiceExtensionContext; -import org.eclipse.dataspaceconnector.spi.system.configuration.Config; -import org.eclipse.dataspaceconnector.sql.datasource.ConnectionFactoryDataSource; +import org.eclipse.edc.spi.persistence.EdcPersistenceException; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.configuration.Config; +import org.eclipse.edc.sql.datasource.ConnectionFactoryDataSource; import org.flywaydb.core.Flyway; import org.flywaydb.core.api.MigrationVersion; import org.flywaydb.core.api.output.MigrateResult; @@ -34,7 +40,7 @@ abstract class AbstractPostgresqlMigrationExtension implements ServiceExtension private static final String MIGRATION_LOCATION_BASE = String.format( "classpath:%s", - AbstractPostgresqlMigrationExtension.class.getPackageName().replaceAll("\\.", "/")); + AbstractPostgresqlMigrationExtension.class.getPackageName().replace(".", "/")); @Override public void initialize(final ServiceExtensionContext context) { @@ -50,7 +56,8 @@ public void initialize(final ServiceExtensionContext context) { context .getConfig() .getBoolean( - String.format("net.catenax.edc.postgresql.migration.%s.enabled", subSystemName), + String.format( + "org.eclipse.tractusx.edc.postgresql.migration.%s.enabled", subSystemName), true); if (!enabled) { diff --git a/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AssetPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AssetPostgresqlMigrationExtension.java new file mode 100644 index 000000000..d44663e2b --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/AssetPostgresqlMigrationExtension.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.postgresql.migration; + +import org.eclipse.edc.connector.store.sql.assetindex.ConfigurationKeys; + +public class AssetPostgresqlMigrationExtension extends AbstractPostgresqlMigrationExtension { + private static final String NAME_SUBSYSTEM = "asset"; + + protected String getDataSourceNameConfigurationKey() { + return ConfigurationKeys.DATASOURCE_SETTING_NAME; + } + + protected String getSubsystemName() { + return NAME_SUBSYSTEM; + } +} diff --git a/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/ContractDefinitionPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/ContractDefinitionPostgresqlMigrationExtension.java new file mode 100644 index 000000000..a5b65aafa --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/ContractDefinitionPostgresqlMigrationExtension.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.postgresql.migration; + +public class ContractDefinitionPostgresqlMigrationExtension + extends AbstractPostgresqlMigrationExtension { + private static final String NAME_SUBSYSTEM = "contractdefinition"; + + private static final String DATASOURCE_SETTING_NAME = "edc.datasource.contractdefinition.name"; + + protected String getDataSourceNameConfigurationKey() { + return DATASOURCE_SETTING_NAME; + } + + protected String getSubsystemName() { + return NAME_SUBSYSTEM; + } +} diff --git a/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/ContractNegotiationPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/ContractNegotiationPostgresqlMigrationExtension.java new file mode 100644 index 000000000..c2da93732 --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/ContractNegotiationPostgresqlMigrationExtension.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.postgresql.migration; + +public class ContractNegotiationPostgresqlMigrationExtension + extends AbstractPostgresqlMigrationExtension { + private static final String NAME_SUBSYSTEM = "contractnegotiation"; + + private static final String DATASOURCE_SETTING_NAME = "edc.datasource.contractnegotiation.name"; + + protected String getDataSourceNameConfigurationKey() { + return DATASOURCE_SETTING_NAME; + } + + protected String getSubsystemName() { + return NAME_SUBSYSTEM; + } +} diff --git a/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/CpAdapterPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/CpAdapterPostgresqlMigrationExtension.java new file mode 100644 index 000000000..63e43c1e7 --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/CpAdapterPostgresqlMigrationExtension.java @@ -0,0 +1,16 @@ +package org.eclipse.tractusx.edc.postgresql.migration; + +public class CpAdapterPostgresqlMigrationExtension extends AbstractPostgresqlMigrationExtension { + private static final String NAME_SUBSYSTEM = "cpadapter"; + private static final String DATASOURCE_SETTING_NAME = "edc.datasource.cpadapter.name"; + + @Override + protected String getDataSourceNameConfigurationKey() { + return DATASOURCE_SETTING_NAME; + } + + @Override + protected String getSubsystemName() { + return NAME_SUBSYSTEM; + } +} diff --git a/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/DriverManagerConnectionFactory.java b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/DriverManagerConnectionFactory.java new file mode 100644 index 000000000..621bc8774 --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/DriverManagerConnectionFactory.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.postgresql.migration; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.Objects; +import java.util.Properties; +import org.eclipse.edc.spi.persistence.EdcPersistenceException; +import org.eclipse.edc.sql.ConnectionFactory; + +class DriverManagerConnectionFactory implements ConnectionFactory { + private final String jdbcUrl; + private final Properties properties; + + public DriverManagerConnectionFactory(final String jdbcUrl, final Properties properties) { + this.jdbcUrl = Objects.requireNonNull(jdbcUrl); + this.properties = Objects.requireNonNull(properties); + } + + @Override + public Connection create() { + try { + return DriverManager.getConnection(jdbcUrl, properties); + } catch (Exception exception) { + throw new EdcPersistenceException(exception.getMessage(), exception); + } + } +} diff --git a/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/PolicyPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/PolicyPostgresqlMigrationExtension.java new file mode 100644 index 000000000..88f47d858 --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/PolicyPostgresqlMigrationExtension.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.postgresql.migration; + +public class PolicyPostgresqlMigrationExtension extends AbstractPostgresqlMigrationExtension { + private static final String NAME_SUBSYSTEM = "policy"; + + private static final String DATASOURCE_SETTING_NAME = "edc.datasource.policy.name"; + + protected String getDataSourceNameConfigurationKey() { + return DATASOURCE_SETTING_NAME; + } + + protected String getSubsystemName() { + return NAME_SUBSYSTEM; + } +} diff --git a/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/TransferProcessPostgresqlMigrationExtension.java b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/TransferProcessPostgresqlMigrationExtension.java new file mode 100644 index 000000000..1379391e7 --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/java/org/eclipse/tractusx/edc/postgresql/migration/TransferProcessPostgresqlMigrationExtension.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.postgresql.migration; + +public class TransferProcessPostgresqlMigrationExtension + extends AbstractPostgresqlMigrationExtension { + private static final String NAME_SUBSYSTEM = "transferprocess"; + + private static final String DATASOURCE_SETTING_NAME = "edc.datasource.transferprocess.name"; + + protected String getDataSourceNameConfigurationKey() { + return DATASOURCE_SETTING_NAME; + } + + protected String getSubsystemName() { + return NAME_SUBSYSTEM; + } +} diff --git a/edc-extensions/postgresql-migration/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension b/edc-extensions/postgresql-migration/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension deleted file mode 100644 index fc52160ad..000000000 --- a/edc-extensions/postgresql-migration/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: -# Mercedes-Benz Tech Innovation GmbH - Initial ServiceExtension file -# -# -net.catenax.edc.postgresql.migration.AssetPostgresqlMigrationExtension -net.catenax.edc.postgresql.migration.ContractDefinitionPostgresqlMigrationExtension -net.catenax.edc.postgresql.migration.ContractNegotiationPostgresqlMigrationExtension -net.catenax.edc.postgresql.migration.PolicyPostgresqlMigrationExtension -net.catenax.edc.postgresql.migration.TransferProcessPostgresqlMigrationExtension diff --git a/edc-extensions/postgresql-migration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/postgresql-migration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..b34529d7e --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,25 @@ +# +# Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH +# Copyright (c) 2021,2022 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# +org.eclipse.tractusx.edc.postgresql.migration.AssetPostgresqlMigrationExtension +org.eclipse.tractusx.edc.postgresql.migration.ContractDefinitionPostgresqlMigrationExtension +org.eclipse.tractusx.edc.postgresql.migration.ContractNegotiationPostgresqlMigrationExtension +org.eclipse.tractusx.edc.postgresql.migration.PolicyPostgresqlMigrationExtension +org.eclipse.tractusx.edc.postgresql.migration.TransferProcessPostgresqlMigrationExtension +org.eclipse.tractusx.edc.postgresql.migration.CpAdapterPostgresqlMigrationExtension diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/asset/V0_0_1__Init_Asset_Database_Schema.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/asset/V0_0_1__Init_Asset_Database_Schema.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/asset/V0_0_1__Init_Asset_Database_Schema.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/asset/V0_0_1__Init_Asset_Database_Schema.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/asset/V0_0_2__Milestone5_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/asset/V0_0_2__Milestone5_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/asset/V0_0_2__Milestone5_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/asset/V0_0_2__Milestone5_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/asset/V0_0_3__Snapshot_20220815_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/asset/V0_0_3__Snapshot_20220815_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/asset/V0_0_3__Snapshot_20220815_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/asset/V0_0_3__Snapshot_20220815_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractdefinition/V0_0_1__Init_ContractDefinition_Database_Schema.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_1__Init_ContractDefinition_Database_Schema.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractdefinition/V0_0_1__Init_ContractDefinition_Database_Schema.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_1__Init_ContractDefinition_Database_Schema.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractdefinition/V0_0_2__Alter_ContractDefinition_Access_Contract_Policy_Id_Schema.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_2__Alter_ContractDefinition_Access_Contract_Policy_Id_Schema.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractdefinition/V0_0_2__Alter_ContractDefinition_Access_Contract_Policy_Id_Schema.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_2__Alter_ContractDefinition_Access_Contract_Policy_Id_Schema.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractdefinition/V0_0_3__Snapshot_20220815_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_3__Snapshot_20220815_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractdefinition/V0_0_3__Snapshot_20220815_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_3__Snapshot_20220815_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_4__Snapshot_20221201_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_4__Snapshot_20221201_Update.sql new file mode 100644 index 000000000..d6f0c1bd8 --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractdefinition/V0_0_4__Snapshot_20221201_Update.sql @@ -0,0 +1,18 @@ +-- +-- Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: +-- Mercedes-Benz Tech Innovation GmbH - EDC Snapshot 20221201 Update +-- + +-- add columns +ALTER TABLE edc_contract_definitions ADD COLUMN validity BIGINT; +-- set to 60×60×24×365, to let existing contracts expire after one year +UPDATE edc_contract_definitions SET validity=31536000; +ALTER TABLE edc_contract_definitions ALTER COLUMN validity SET NOT NULL; diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractnegotiation/V0_0_1__Init_ContractNegotiation_Database_Schema.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractnegotiation/V0_0_1__Init_ContractNegotiation_Database_Schema.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractnegotiation/V0_0_1__Init_ContractNegotiation_Database_Schema.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractnegotiation/V0_0_1__Init_ContractNegotiation_Database_Schema.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractnegotiation/V0_0_2__Alter_ContractNegotation_Contract_Agreement_Id_Schema.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractnegotiation/V0_0_2__Alter_ContractNegotation_Contract_Agreement_Id_Schema.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractnegotiation/V0_0_2__Alter_ContractNegotation_Contract_Agreement_Id_Schema.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractnegotiation/V0_0_2__Alter_ContractNegotation_Contract_Agreement_Id_Schema.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractnegotiation/V0_0_3__Milestone5_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractnegotiation/V0_0_3__Milestone5_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractnegotiation/V0_0_3__Milestone5_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractnegotiation/V0_0_3__Milestone5_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractnegotiation/V0_0_4__Snapshot_20220815_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractnegotiation/V0_0_4__Snapshot_20220815_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/contractnegotiation/V0_0_4__Snapshot_20220815_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/contractnegotiation/V0_0_4__Snapshot_20220815_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/cpadapter/V0_0_7__Init_CpAdapter_Database_Schema.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/cpadapter/V0_0_7__Init_CpAdapter_Database_Schema.sql new file mode 100644 index 000000000..3e64d3c45 --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/cpadapter/V0_0_7__Init_CpAdapter_Database_Schema.sql @@ -0,0 +1,54 @@ +-- +-- Copyright (c) 2022 ZF Friedrichshafen AG +-- +-- This program and the accompanying materials are made available under the +-- terms of the Apache License, Version 2.0 which is available at +-- https://www.apache.org/licenses/LICENSE-2.0 +-- +-- SPDX-License-Identifier: Apache-2.0 +-- +-- Contributors: +-- ZF Friedrichshafen AG - Initial SQL Query +-- + +-- Statements are designed for and tested with Postgres only! + + +CREATE TABLE IF NOT EXISTS edc_lease +( + leased_by VARCHAR NOT NULL, + leased_at BIGINT, + lease_duration INTEGER NOT NULL, + lease_id VARCHAR NOT NULL + CONSTRAINT lease_pk + PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS edc_cpadapter_queue +( + id VARCHAR NOT NULL, + created_at BIGINT NOT NULL, + channel VARCHAR, + message JSON, + invoke_after BIGINT NOT NULL, + lease_id VARCHAR + CONSTRAINT cpadapter_queue_lease_lease_id_fk + REFERENCES edc_lease + ON DELETE SET NULL, + PRIMARY KEY (id) +); + +CREATE UNIQUE INDEX IF NOT EXISTS edc_cpadapter_queue_id_uindex + ON edc_cpadapter_queue (id); + +CREATE TABLE IF NOT EXISTS edc_cpadapter_object_store +( + id VARCHAR NOT NULL, + created_at BIGINT NOT NULL, + type VARCHAR, + object JSON, + PRIMARY KEY (id) +); + + + diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/policy/V0_0_1__Init_Policy_Database_Schema.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/policy/V0_0_1__Init_Policy_Database_Schema.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/policy/V0_0_1__Init_Policy_Database_Schema.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/policy/V0_0_1__Init_Policy_Database_Schema.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/policy/V0_0_2__Milestone5_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/policy/V0_0_2__Milestone5_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/policy/V0_0_2__Milestone5_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/policy/V0_0_2__Milestone5_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/policy/V0_0_3__Snapshot_20220815_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/policy/V0_0_3__Snapshot_20220815_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/policy/V0_0_3__Snapshot_20220815_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/policy/V0_0_3__Snapshot_20220815_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_1__Init_TransferProcess_Database_Schema.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_1__Init_TransferProcess_Database_Schema.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_1__Init_TransferProcess_Database_Schema.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_1__Init_TransferProcess_Database_Schema.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_2__Alter_TransferProcess_Add_DataAddress.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_2__Alter_TransferProcess_Add_DataAddress.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_2__Alter_TransferProcess_Add_DataAddress.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_2__Alter_TransferProcess_Add_DataAddress.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_3__Alter_Rename_Id.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_3__Alter_Rename_Id.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_3__Alter_Rename_Id.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_3__Alter_Rename_Id.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_4__Milestone5_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_4__Milestone5_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_4__Milestone5_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_4__Milestone5_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_5__Snapshot_20220815_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_5__Snapshot_20220815_Update.sql similarity index 100% rename from edc-extensions/postgresql-migration/src/main/resources/net/catenax/edc/postgresql/migration/transferprocess/V0_0_5__Snapshot_20220815_Update.sql rename to edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_5__Snapshot_20220815_Update.sql diff --git a/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_6__Snapshot_20230109_Update.sql b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_6__Snapshot_20230109_Update.sql new file mode 100644 index 000000000..7e6ec836a --- /dev/null +++ b/edc-extensions/postgresql-migration/src/main/resources/org/eclipse/tractusx/edc/postgresql/migration/transferprocess/V0_0_6__Snapshot_20230109_Update.sql @@ -0,0 +1,15 @@ +-- +-- Copyright (c) 2022 ZF Friedrichshafen AG +-- +-- This program and the accompanying materials are made available under the +-- terms of the Apache License, Version 2.0 which is available at +-- https://www.apache.org/licenses/LICENSE-2.0 +-- +-- SPDX-License-Identifier: Apache-2.0 +-- +-- Contributors: +-- ZF Friedrichshafen AG - Add column for the dynamically HTTP Receiver callback endpoints +-- + +-- add column +ALTER TABLE edc_transfer_process ADD COLUMN transferprocess_properties TEXT; diff --git a/edc-extensions/provision-additional-headers/README.md b/edc-extensions/provision-additional-headers/README.md new file mode 100644 index 000000000..3d68602fa --- /dev/null +++ b/edc-extensions/provision-additional-headers/README.md @@ -0,0 +1,9 @@ +# Provision: additional headers + +The goal of this extension is to provide additional headers to the request to the backend service done by the provider +in order to retrieve the data that will be given to the consumer. + +This gives for example the provider backend service the possibility to audit the data requests. + +The following headers are added to the `HttpDataAddress`: +- `Edc-Contract-Agreement-Id`: the id of the contract agreement diff --git a/edc-extensions/provision-additional-headers/build.gradle.kts b/edc-extensions/provision-additional-headers/build.gradle.kts new file mode 100644 index 000000000..191ada758 --- /dev/null +++ b/edc-extensions/provision-additional-headers/build.gradle.kts @@ -0,0 +1,16 @@ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + implementation(edc.spi.core) + implementation(edc.spi.transfer) + + testImplementation(libs.awaitility) + testImplementation(edc.junit) + + testImplementation(edc.core.controlplane) + testImplementation(libs.mockito.inline) +} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResource.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResource.java new file mode 100644 index 000000000..b0d3534ea --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResource.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionedContentResource; + +@JsonDeserialize(builder = AdditionalHeadersProvisionedResource.Builder.class) +class AdditionalHeadersProvisionedResource extends ProvisionedContentResource { + + @JsonPOJOBuilder(withPrefix = "") + public static class Builder + extends ProvisionedContentResource.Builder { + + private Builder() { + super(new AdditionalHeadersProvisionedResource()); + } + + @JsonCreator + public static Builder newInstance() { + return new Builder(); + } + } +} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java new file mode 100644 index 000000000..b5b4085e5 --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisioner.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import org.eclipse.edc.connector.transfer.spi.provision.Provisioner; +import org.eclipse.edc.connector.transfer.spi.types.DeprovisionedResource; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionResponse; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionedResource; +import org.eclipse.edc.connector.transfer.spi.types.ResourceDefinition; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.edc.spi.types.domain.HttpDataAddress; + +public class AdditionalHeadersProvisioner + implements Provisioner< + AdditionalHeadersResourceDefinition, AdditionalHeadersProvisionedResource> { + + @Override + public boolean canProvision(ResourceDefinition resourceDefinition) { + return resourceDefinition instanceof AdditionalHeadersResourceDefinition; + } + + @Override + public boolean canDeprovision(ProvisionedResource provisionedResource) { + return false; // nothing to deprovision + } + + @Override + public CompletableFuture> provision( + AdditionalHeadersResourceDefinition resourceDefinition, Policy policy) { + + var address = + HttpDataAddress.Builder.newInstance() + .copyFrom(resourceDefinition.getDataAddress()) + .addAdditionalHeader("Edc-Contract-Agreement-Id", resourceDefinition.getContractId()) + .build(); + + var provisioned = + AdditionalHeadersProvisionedResource.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .resourceDefinitionId(resourceDefinition.getId()) + .transferProcessId(resourceDefinition.getTransferProcessId()) + .dataAddress(address) + .resourceName(UUID.randomUUID().toString()) + .hasToken(false) + .build(); + + var response = ProvisionResponse.Builder.newInstance().resource(provisioned).build(); + var result = StatusResult.success(response); + return CompletableFuture.completedFuture(result); + } + + @Override + public CompletableFuture> deprovision( + AdditionalHeadersProvisionedResource additionalHeadersProvisionedResource, Policy policy) { + return null; // nothing to deprovision + } +} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinition.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinition.java new file mode 100644 index 000000000..e609922be --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinition.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; +import org.eclipse.edc.connector.transfer.spi.types.ResourceDefinition; +import org.eclipse.edc.spi.types.domain.DataAddress; + +@JsonDeserialize(builder = AdditionalHeadersResourceDefinition.Builder.class) +@JsonTypeName("dataspaceconnector:additionalheadersresourcedefinition") +class AdditionalHeadersResourceDefinition extends ResourceDefinition { + + private String contractId; + private DataAddress dataAddress; + + @Override + public Builder toBuilder() { + return initializeBuilder(new Builder()); + } + + public DataAddress getDataAddress() { + return dataAddress; + } + + public String getContractId() { + return contractId; + } + + @JsonPOJOBuilder(withPrefix = "") + public static class Builder + extends ResourceDefinition.Builder { + + protected Builder() { + super(new AdditionalHeadersResourceDefinition()); + } + + @JsonCreator + public static Builder newInstance() { + return new Builder(); + } + + public Builder contractId(String contractId) { + this.resourceDefinition.contractId = contractId; + return this; + } + + public Builder dataAddress(DataAddress dataAddress) { + this.resourceDefinition.dataAddress = dataAddress; + return this; + } + } +} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java new file mode 100644 index 000000000..1d85bdd94 --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGenerator.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import java.util.UUID; +import org.eclipse.edc.connector.transfer.spi.provision.ProviderResourceDefinitionGenerator; +import org.eclipse.edc.connector.transfer.spi.types.DataRequest; +import org.eclipse.edc.connector.transfer.spi.types.ResourceDefinition; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.jetbrains.annotations.Nullable; + +class AdditionalHeadersResourceDefinitionGenerator implements ProviderResourceDefinitionGenerator { + + @Override + public boolean canGenerate(DataRequest dataRequest, DataAddress dataAddress, Policy policy) { + return "HttpData".equals(dataAddress.getType()); + } + + @Override + public @Nullable ResourceDefinition generate( + DataRequest dataRequest, DataAddress dataAddress, Policy policy) { + return AdditionalHeadersResourceDefinition.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .dataAddress(dataAddress) + .contractId(dataRequest.getContractId()) + .build(); + } +} diff --git a/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java new file mode 100644 index 000000000..ef58cd4a2 --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/main/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtension.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import org.eclipse.edc.connector.transfer.spi.provision.ProvisionManager; +import org.eclipse.edc.connector.transfer.spi.provision.ResourceManifestGenerator; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.types.TypeManager; + +public class ProvisionAdditionalHeadersExtension implements ServiceExtension { + + @Inject private ResourceManifestGenerator resourceManifestGenerator; + + @Inject private ProvisionManager provisionManager; + + @Inject private TypeManager typeManager; + + @Override + public void initialize(ServiceExtensionContext context) { + typeManager.registerTypes( + AdditionalHeadersResourceDefinition.class, AdditionalHeadersProvisionedResource.class); + resourceManifestGenerator.registerGenerator(new AdditionalHeadersResourceDefinitionGenerator()); + provisionManager.register(new AdditionalHeadersProvisioner()); + } +} diff --git a/edc-extensions/provision-additional-headers/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/edc-extensions/provision-additional-headers/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..df3714fd4 --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,20 @@ +# +# Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (c) 2021-2023 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# +org.eclipse.tractusx.edc.provision.additionalheaders.ProvisionAdditionalHeadersExtension diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResourceTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResourceTest.java new file mode 100644 index 000000000..dc133d060 --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionedResourceTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.util.UUID; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.junit.jupiter.api.Test; + +class AdditionalHeadersProvisionedResourceTest { + + @Test + void serdes() { + var typeManager = new TypeManager(); + var resource = + AdditionalHeadersProvisionedResource.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .resourceDefinitionId(UUID.randomUUID().toString()) + .transferProcessId(UUID.randomUUID().toString()) + .hasToken(false) + .resourceName("name") + .dataAddress(DataAddress.Builder.newInstance().type("type").build()) + .build(); + + var json = typeManager.writeValueAsString(resource); + var deserialized = typeManager.readValue(json, AdditionalHeadersProvisionedResource.class); + + assertThat(deserialized).usingRecursiveComparison().isEqualTo(resource); + } +} diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java new file mode 100644 index 000000000..45769a935 --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersProvisionerTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.InstanceOfAssertFactories.map; +import static org.assertj.core.api.InstanceOfAssertFactories.type; +import static org.mockito.Mockito.mock; + +import java.util.UUID; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionResponse; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionedDataAddressResource; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionedResource; +import org.eclipse.edc.connector.transfer.spi.types.ResourceDefinition; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.edc.spi.types.domain.HttpDataAddress; +import org.junit.jupiter.api.Test; + +class AdditionalHeadersProvisionerTest { + + private final AdditionalHeadersProvisioner provisioner = new AdditionalHeadersProvisioner(); + + @Test + void canProvisionAdditionalHeadersResourceDefinition() { + assertThat(provisioner.canProvision(mock(AdditionalHeadersResourceDefinition.class))).isTrue(); + assertThat(provisioner.canProvision(mock(ResourceDefinition.class))).isFalse(); + } + + @Test + void cannotDeprovisionAdditionalHeadersResourceDefinition() { + assertThat(provisioner.canDeprovision(mock(AdditionalHeadersProvisionedResource.class))) + .isFalse(); + assertThat(provisioner.canDeprovision(mock(ProvisionedResource.class))).isFalse(); + } + + @Test + void shouldAddContractIdAdditionalHeader() { + var address = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); + var resourceDefinition = + AdditionalHeadersResourceDefinition.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .transferProcessId(UUID.randomUUID().toString()) + .contractId("contractId") + .dataAddress(address) + .build(); + + var result = provisioner.provision(resourceDefinition, Policy.Builder.newInstance().build()); + + assertThat(result) + .succeedsWithin(5, SECONDS) + .matches(StatusResult::succeeded) + .extracting(StatusResult::getContent) + .extracting(ProvisionResponse::getResource) + .asInstanceOf(type(AdditionalHeadersProvisionedResource.class)) + .extracting(ProvisionedDataAddressResource::getDataAddress) + .extracting(a -> HttpDataAddress.Builder.newInstance().copyFrom(a).build()) + .extracting(HttpDataAddress::getAdditionalHeaders) + .asInstanceOf(map(String.class, String.class)) + .containsEntry("Edc-Contract-Agreement-Id", "contractId"); + } +} diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java new file mode 100644 index 000000000..12b9a61e6 --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionGeneratorTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.InstanceOfAssertFactories.type; + +import java.util.UUID; +import org.eclipse.edc.connector.transfer.spi.types.DataRequest; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.spi.types.domain.HttpDataAddress; +import org.junit.jupiter.api.Test; + +class AdditionalHeadersResourceDefinitionGeneratorTest { + + private final AdditionalHeadersResourceDefinitionGenerator generator = + new AdditionalHeadersResourceDefinitionGenerator(); + + @Test + void canGenerate_shouldReturnFalseForNotHttpDataAddresses() { + var dataAddress = DataAddress.Builder.newInstance().type("any").build(); + var dataRequest = + DataRequest.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .dataDestination(dataAddress) + .build(); + var build = Policy.Builder.newInstance().build(); + + var result = generator.canGenerate(dataRequest, dataAddress, build); + + assertThat(result).isFalse(); + } + + @Test + void canGenerate_shouldReturnTrueForHttpDataAddresses() { + var dataAddress = DataAddress.Builder.newInstance().type("HttpData").build(); + var dataRequest = + DataRequest.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .dataDestination(dataAddress) + .build(); + var build = Policy.Builder.newInstance().build(); + + var result = generator.canGenerate(dataRequest, dataAddress, build); + + assertThat(result).isTrue(); + } + + @Test + void shouldCreateResourceDefinitionWithDataAddress() { + var dataAddress = HttpDataAddress.Builder.newInstance().baseUrl("http://any").build(); + var dataRequest = + DataRequest.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .dataDestination(dataAddress) + .build(); + var build = Policy.Builder.newInstance().build(); + + var result = generator.generate(dataRequest, dataAddress, build); + + assertThat(result) + .asInstanceOf(type(AdditionalHeadersResourceDefinition.class)) + .extracting(AdditionalHeadersResourceDefinition::getDataAddress) + .extracting(address -> HttpDataAddress.Builder.newInstance().copyFrom(address).build()) + .extracting(HttpDataAddress::getBaseUrl) + .isEqualTo("http://any"); + } +} diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionTest.java new file mode 100644 index 000000000..4c69e297d --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/AdditionalHeadersResourceDefinitionTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.util.UUID; +import org.eclipse.edc.spi.types.TypeManager; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.junit.jupiter.api.Test; + +class AdditionalHeadersResourceDefinitionTest { + + @Test + void serdes() { + var typeManager = new TypeManager(); + var definition = + AdditionalHeadersResourceDefinition.Builder.newInstance() + .id(UUID.randomUUID().toString()) + .transferProcessId(UUID.randomUUID().toString()) + .dataAddress(DataAddress.Builder.newInstance().type("type").build()) + .contractId(UUID.randomUUID().toString()) + .build(); + + var json = typeManager.writeValueAsString(definition); + var deserialized = typeManager.readValue(json, AdditionalHeadersResourceDefinition.class); + + assertThat(deserialized).usingRecursiveComparison().isEqualTo(definition); + } +} diff --git a/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java new file mode 100644 index 000000000..205b3c75c --- /dev/null +++ b/edc-extensions/provision-additional-headers/src/test/java/org/eclipse/tractusx/edc/provision/additionalheaders/ProvisionAdditionalHeadersExtensionTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * Copyright (c) 2021-2023 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.provision.additionalheaders; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.awaitility.Awaitility.await; +import static org.mockito.Mockito.*; + +import org.eclipse.edc.connector.transfer.spi.TransferProcessManager; +import org.eclipse.edc.connector.transfer.spi.flow.DataFlowController; +import org.eclipse.edc.connector.transfer.spi.flow.DataFlowManager; +import org.eclipse.edc.connector.transfer.spi.types.DataRequest; +import org.eclipse.edc.junit.extensions.EdcExtension; +import org.eclipse.edc.spi.asset.AssetIndex; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.spi.types.domain.asset.Asset; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(EdcExtension.class) +class ProvisionAdditionalHeadersExtensionTest { + + private final DataFlowController dataFlowController = mock(DataFlowController.class); + + @BeforeEach + void setUp() { + when(dataFlowController.canHandle(any(), any())).thenReturn(true); + when(dataFlowController.initiateFlow(any(), any(), any())).thenReturn(StatusResult.success()); + } + + @Test + void shouldPutContractIdAsHeaderInDataAddress( + TransferProcessManager transferProcessManager, + AssetIndex assetIndex, + DataFlowManager dataFlowManager) { + dataFlowManager.register(dataFlowController); + var asset = Asset.Builder.newInstance().id("assetId").build(); + var dataAddress = DataAddress.Builder.newInstance().type("HttpData").build(); + assetIndex.accept(asset, dataAddress); + + var dataRequest = + DataRequest.Builder.newInstance() + .contractId("aContractId") + .assetId("assetId") + .destinationType("HttpProxy") + .build(); + + var result = transferProcessManager.initiateProviderRequest(dataRequest); + + assertThat(result).matches(StatusResult::succeeded); + + await() + .untilAsserted( + () -> { + verify(dataFlowController) + .initiateFlow( + any(), + argThat( + it -> + "aContractId" + .equals(it.getProperty("header:Edc-Contract-Agreement-Id"))), + any()); + }); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/build.gradle.kts b/edc-extensions/transferprocess-sftp-client/build.gradle.kts new file mode 100644 index 000000000..550ed105a --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/build.gradle.kts @@ -0,0 +1,26 @@ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + implementation(project(":edc-extensions:transferprocess-sftp-common")) + implementation(edc.spi.core) + implementation(edc.spi.transfer) + implementation(edc.spi.policy) + implementation(edc.spi.dataplane.dataplane) + implementation(edc.dpf.util) + implementation(edc.dpf.core) + implementation(edc.policy.engine) + implementation(libs.bouncyCastle.bcpkix) + + implementation(libs.apache.sshd.core) + implementation(libs.apache.sshd.sftp) + + testImplementation(libs.awaitility) + testImplementation(edc.junit) + + testImplementation(libs.mockito.inline) + testImplementation(libs.testcontainers.junit) +} diff --git a/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientConfig.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientConfig.java new file mode 100644 index 000000000..bf5da3a2f --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientConfig.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.List; +import lombok.Builder; +import lombok.Getter; +import org.apache.sshd.sftp.client.SftpClient; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; + +@Builder +@Getter +public class SftpClientConfig { + private SftpUser sftpUser; + private SftpLocation sftpLocation; + @Builder.Default private int bufferSize = 4096; + @Builder.Default private boolean hostVerification = true; + + @Builder.Default + private Path knownHostFile = Paths.get(System.getenv("HOME"), ".ssh/known_hosts"); + + @Builder.Default private int connectionTimeoutSeconds = 10; + + @Builder.Default + private Collection writeOpenModes = + List.of(SftpClient.OpenMode.Create, SftpClient.OpenMode.Write); + + @Builder.Default + private Collection readOpenModes = List.of(SftpClient.OpenMode.Read); +} diff --git a/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientExtension.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientExtension.java new file mode 100644 index 000000000..9143b3583 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientExtension.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import org.eclipse.edc.connector.dataplane.spi.pipeline.PipelineService; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.runtime.metamodel.annotation.Provides; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; + +@Provides(SftpClientWrapper.class) +public class SftpClientExtension implements ServiceExtension { + + @Inject PipelineService pipelineService; + + @Override + public void initialize(ServiceExtensionContext context) { + SftpDataSinkFactory sftpDataSinkFactory = new SftpDataSinkFactory(); + SftpDataSourceFactory sftpDataSourceFactory = new SftpDataSourceFactory(); + SftpClientWrapperFactory sftpClientWrapperFactory = new SftpClientWrapperFactoryImpl(); + + pipelineService.registerFactory(sftpDataSinkFactory); + pipelineService.registerFactory(sftpDataSourceFactory); + context.registerService(SftpClientWrapperFactory.class, sftpClientWrapperFactory); + } +} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractDefinition.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapper.java similarity index 60% rename from edc-tests/src/test/java/net/catenax/edc/tests/data/ContractDefinition.java rename to edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapper.java index dc2054a97..c082106f2 100644 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractDefinition.java +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapper.java @@ -11,19 +11,14 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.tests.data; -import java.util.List; -import lombok.NonNull; -import lombok.Value; +package org.eclipse.tractusx.edc.transferprocess.sftp.client; -@Value -public class ContractDefinition { +import java.io.IOException; +import java.io.InputStream; - @NonNull String id; +public interface SftpClientWrapper { + void uploadFile(InputStream inputStream) throws IOException; - @NonNull String contractPolicyId; - @NonNull String acccessPolicyId; - - List assetIds; + InputStream downloadFile() throws IOException; } diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKeyFactory.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperFactory.java similarity index 70% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKeyFactory.java rename to edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperFactory.java index b3eadcd50..ba60d9c04 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/CryptoKeyFactory.java +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperFactory.java @@ -11,10 +11,9 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.data.encryption.key; -public interface CryptoKeyFactory { - AesKey fromBase64(String base64); +package org.eclipse.tractusx.edc.transferprocess.sftp.client; - AesKey fromBytes(byte[] key); +public interface SftpClientWrapperFactory { + SftpClientWrapper getSftpClientWrapper(SftpClientConfig config); } diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/PublicKeyReader.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperFactoryImpl.java similarity index 59% rename from edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/PublicKeyReader.java rename to edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperFactoryImpl.java index de73e6e3b..a300ea4d0 100644 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/PublicKeyReader.java +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperFactoryImpl.java @@ -11,12 +11,13 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.oauth2.jwk; -import java.util.Optional; +package org.eclipse.tractusx.edc.transferprocess.sftp.client; -public interface PublicKeyReader { - boolean canRead(JsonWebKey jsonWebKey); +public class SftpClientWrapperFactoryImpl implements SftpClientWrapperFactory { - Optional read(JsonWebKey jsonWebKey); + @Override + public SftpClientWrapper getSftpClientWrapper(SftpClientConfig config) { + return new SftpClientWrapperImpl(config); + } } diff --git a/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperImpl.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperImpl.java new file mode 100644 index 000000000..cad0ea6e5 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperImpl.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.time.Duration; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.apache.sshd.client.ClientBuilder; +import org.apache.sshd.client.SshClient; +import org.apache.sshd.client.auth.password.PasswordIdentityProvider; +import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier; +import org.apache.sshd.client.keyverifier.RejectAllServerKeyVerifier; +import org.apache.sshd.client.keyverifier.ServerKeyVerifier; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; +import org.apache.sshd.sftp.client.SftpClient; +import org.apache.sshd.sftp.client.SftpClientFactory; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.EdcSftpException; +import org.jetbrains.annotations.NotNull; + +public class SftpClientWrapperImpl implements SftpClientWrapper { + @Getter private final SftpClientConfig config; + private final SftpClient sftpClient; + + public SftpClientWrapperImpl(SftpClientConfig config) { + this.config = config; + try { + this.sftpClient = getSftpClient(config); + } catch (IOException e) { + throw new EdcSftpException("Unable to create SftpClient.", e); + } + } + + public SftpClientWrapperImpl(SftpClientConfig config, SftpClient sftpClient) { + this.config = config; + this.sftpClient = sftpClient; + } + + @Override + public void uploadFile(@NonNull final InputStream inputStream) throws IOException { + try (final OutputStream outputStream = + sftpClient.write( + config.getSftpLocation().getPath(), + config.getBufferSize(), + config.getWriteOpenModes())) { + inputStream.transferTo(outputStream); + } + } + + @Override + public InputStream downloadFile() throws IOException { + final InputStream delegateInputStream; + try { + delegateInputStream = + sftpClient.read( + config.getSftpLocation().getPath(), + config.getBufferSize(), + config.getReadOpenModes()); + } catch (final IOException e) { + sftpClient.close(); + throw new EdcSftpException( + String.format("Unable to download file at %s", config.getSftpLocation().toString()), e); + } + + return new SftpInputStreamWrapper(sftpClient, delegateInputStream); + } + + static SftpClient getSftpClient(SftpClientConfig config) throws IOException { + final ClientSession session = getSshClientSession(config); + final SftpClientFactory factory = SftpClientFactory.instance(); + final SftpClient sftpClient = factory.createSftpClient(session); + return sftpClient.singleSessionInstance(); + } + + private static ClientSession getSshClientSession(SftpClientConfig config) throws IOException { + final SshClient sshClient = getSshClient(config); + sshClient.start(); + final ClientSession session = + sshClient + .connect( + config.getSftpUser().getName(), + config.getSftpLocation().getHost(), + config.getSftpLocation().getPort()) + .verify() + .getSession(); + session.auth().await(Duration.ofSeconds(config.getConnectionTimeoutSeconds())); + + return session; + } + + private static SshClient getSshClient(SftpClientConfig config) { + final SshClient sshClient = ClientBuilder.builder().build(); + + if (config.getSftpUser().getKeyPair() != null) { + sshClient.setKeyIdentityProvider( + KeyIdentityProvider.wrapKeyPairs(config.getSftpUser().getKeyPair())); + } else if (config.getSftpUser().getPassword() != null) { + sshClient.setPasswordIdentityProvider( + PasswordIdentityProvider.wrapPasswords(config.getSftpUser().getPassword())); + } else { + sshClient.setPasswordIdentityProvider(PasswordIdentityProvider.EMPTY_PASSWORDS_PROVIDER); + } + + if (config.isHostVerification()) { + final ServerKeyVerifier keyVerifier = + new KnownHostsServerKeyVerifier( + RejectAllServerKeyVerifier.INSTANCE, config.getKnownHostFile()); + sshClient.setServerKeyVerifier(keyVerifier); + } + + return sshClient; + } + + @RequiredArgsConstructor + private static class SftpInputStreamWrapper extends InputStream { + @NonNull private final SftpClient sftpClient; + @NonNull private final InputStream delegateInputStream; + + @Override + public int read() throws IOException { + return delegateInputStream.read(); + } + + @Override + public int read(byte @NotNull [] b, int off, int len) throws IOException { + return delegateInputStream.read(b, off, len); + } + + @Override + public void close() { + try { + delegateInputStream.close(); + } catch (IOException ignored) { + // Ignored. The exception should only be thrown of the stream is already closed. + } + + try { + sftpClient.close(); + } catch (IOException ignored) { + // Ignored. The exception should only be thrown of the client is already closed. + } + } + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSink.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSink.java new file mode 100644 index 000000000..e819229f0 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSink.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial Test + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import java.io.IOException; +import java.util.List; +import lombok.Builder; +import lombok.NonNull; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSource; +import org.eclipse.edc.connector.dataplane.util.sink.ParallelSink; +import org.eclipse.edc.spi.response.ResponseStatus; +import org.eclipse.edc.spi.response.StatusResult; + +@Builder +public class SftpDataSink extends ParallelSink { + @NonNull private final SftpClientWrapper sftpClientWrapper; + + @Override + protected StatusResult transferParts(List parts) { + for (DataSource.Part part : parts) { + try { + sftpClientWrapper.uploadFile(part.openStream()); + } catch (IOException e) { + return StatusResult.failure(ResponseStatus.FATAL_ERROR, e.getMessage()); + } + } + return StatusResult.success(); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkFactory.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkFactory.java new file mode 100644 index 000000000..4edcb9dec --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkFactory.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial Test + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.apache.sshd.sftp.client.SftpClient; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSink; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSinkFactory; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.types.domain.transfer.DataFlowRequest; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.EdcSftpException; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +import org.jetbrains.annotations.NotNull; + +@RequiredArgsConstructor +public class SftpDataSinkFactory implements DataSinkFactory { + @Override + public boolean canHandle(DataFlowRequest request) { + try { + SftpDataAddress.fromDataAddress(request.getDestinationDataAddress()); + return true; + } catch (EdcSftpException e) { + return false; + } + } + + @Override + public @NotNull Result validate(DataFlowRequest request) { + if (!canHandle(request)) { + return Result.failure(String.format("Invalid DataFlowRequest: %s", request.getId())); + } + + return VALID; + } + + @Override + public DataSink createSink(DataFlowRequest request) { + if (!canHandle(request)) { + return null; + } + + SftpDataAddress destination = + SftpDataAddress.fromDataAddress(request.getDestinationDataAddress()); + + SftpClientConfig sftpClientConfig = + SftpClientConfig.builder() + .writeOpenModes(List.of(SftpClient.OpenMode.Create, SftpClient.OpenMode.Append)) + .sftpUser(destination.getSftpUser()) + .sftpLocation(destination.getSftpLocation()) + .build(); + + SftpClientWrapper sftpClientWrapper = new SftpClientWrapperImpl(sftpClientConfig); + + return new SftpDataSink(sftpClientWrapper); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSource.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSource.java new file mode 100644 index 000000000..334538fea --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSource.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial Test + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import java.util.stream.Stream; +import lombok.Builder; +import lombok.NonNull; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSource; + +@Builder +public class SftpDataSource implements DataSource { + @NonNull private final SftpClientWrapper sftpClientWrapper; + + @Override + public Stream openPartStream() { + Part sftpPart = new SftpPart(sftpClientWrapper); + return Stream.of(sftpPart); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceFactory.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceFactory.java new file mode 100644 index 000000000..076afc72d --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceFactory.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial Test + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSource; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSourceFactory; +import org.eclipse.edc.spi.result.Result; +import org.eclipse.edc.spi.types.domain.transfer.DataFlowRequest; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.EdcSftpException; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +import org.jetbrains.annotations.NotNull; + +@RequiredArgsConstructor +public class SftpDataSourceFactory implements DataSourceFactory { + @Override + public boolean canHandle(DataFlowRequest request) { + try { + SftpDataAddress.fromDataAddress(request.getSourceDataAddress()); + return true; + } catch (EdcSftpException e) { + return false; + } + } + + @Override + public @NotNull Result validate(DataFlowRequest request) { + if (!canHandle(request)) { + return Result.failure(String.format("Invalid DataFlowRequest: %s", request.getId())); + } + + return VALID; + } + + @Override + public DataSource createSource(DataFlowRequest request) { + if (!canHandle(request)) { + return null; + } + + SftpDataAddress source = SftpDataAddress.fromDataAddress(request.getSourceDataAddress()); + + SftpClientConfig sftpClientConfig = + SftpClientConfig.builder() + .sftpUser(source.getSftpUser()) + .sftpLocation(source.getSftpLocation()) + .build(); + + SftpClientWrapper sftpClientWrapper = new SftpClientWrapperImpl(sftpClientConfig); + return new SftpDataSource(sftpClientWrapper); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpPart.java b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpPart.java new file mode 100644 index 000000000..2b4e9e7e3 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpPart.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import java.io.InputStream; +import lombok.Builder; +import lombok.NonNull; +import lombok.SneakyThrows; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSource; + +@Builder +public class SftpPart implements DataSource.Part { + @NonNull private final SftpClientWrapper sftpClientWrapper; + + @Override + public String name() { + return ((SftpClientWrapperImpl) sftpClientWrapper).getConfig().getSftpLocation().getPath(); + } + + @Override + @SneakyThrows + public InputStream openStream() { + return sftpClientWrapper.downloadFile(); + } +} diff --git a/edc-extensions/data-encryption/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension b/edc-extensions/transferprocess-sftp-client/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension similarity index 84% rename from edc-extensions/data-encryption/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension rename to edc-extensions/transferprocess-sftp-client/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension index 8a09148c9..bfdbb7ac1 100644 --- a/edc-extensions/data-encryption/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension +++ b/edc-extensions/transferprocess-sftp-client/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension @@ -10,5 +10,4 @@ # Contributors: # Mercedes-Benz Tech Innovation GmbH - Initial ServiceExtension file # -# -net.catenax.edc.data.encryption.DataEncryptionExtension +org.eclipse.tractusx.edc.transferprocess.sftp.client.SftpClientExtension diff --git a/edc-extensions/transferprocess-sftp-client/src/main/resources/logback.xml b/edc-extensions/transferprocess-sftp-client/src/main/resources/logback.xml new file mode 100644 index 000000000..3347fcbae --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/main/resources/logback.xml @@ -0,0 +1,23 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] sdfsfs %-5level %logger{36} - %msg%n + + + + + + diff --git a/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/AbstractSftpClientWrapperIT.java b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/AbstractSftpClientWrapperIT.java new file mode 100644 index 000000000..757319606 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/AbstractSftpClientWrapperIT.java @@ -0,0 +1,230 @@ +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.testcontainers.shaded.org.awaitility.Awaitility.await; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.PosixFilePermission; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.interfaces.RSAPublicKey; +import java.util.Base64; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; +import lombok.NoArgsConstructor; +import lombok.SneakyThrows; +import org.bouncycastle.crypto.params.RSAKeyParameters; +import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.ClassRule; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.shaded.org.apache.commons.io.IOUtils; +import org.testcontainers.shaded.org.apache.commons.lang3.RandomUtils; +import org.testcontainers.utility.DockerImageName; + +abstract class AbstractSftpClientWrapperIT { + static final String DOCKER_IMAGE_NAME = "atmoz/sftp:alpine-3.6"; + static final String sftpPathPrefix = "transfer"; + static final Map DOCKER_ENV = + Map.of("SFTP_USERS", String.format("user:password:::%s", sftpPathPrefix)); + static final Path dockerVolumeDirectory; + static final Path remotePasswordUploadDirectory; + static final Path remotePasswordDownloadDirectory; + static final Path remoteKeypairUploadDirectory; + static final Path remoteKeypairDownloadDirectory; + static final Path localUploadAndGeneratorDirectory; + static final Path keyDirectory; + static final Path publicKeyPath; + static final KeyPair keyPair; + @Container @ClassRule private static final GenericContainer sftpContainer; + + static { + keyPair = generateKeyPair(); + + try { + Set fullPermission = new HashSet(); + fullPermission.add(PosixFilePermission.OWNER_EXECUTE); + fullPermission.add(PosixFilePermission.OWNER_READ); + fullPermission.add(PosixFilePermission.OWNER_WRITE); + fullPermission.add(PosixFilePermission.GROUP_EXECUTE); + fullPermission.add(PosixFilePermission.GROUP_READ); + fullPermission.add(PosixFilePermission.GROUP_WRITE); + fullPermission.add(PosixFilePermission.OTHERS_EXECUTE); + fullPermission.add(PosixFilePermission.OTHERS_READ); + fullPermission.add(PosixFilePermission.OTHERS_WRITE); + + dockerVolumeDirectory = Files.createTempDirectory(SftpClientWrapperIT.class.getName()); + localUploadAndGeneratorDirectory = + Files.createTempDirectory(SftpClientWrapperIT.class.getName()); + remotePasswordUploadDirectory = + Files.createDirectory(dockerVolumeDirectory.resolve("passwordUpload")); + remotePasswordDownloadDirectory = + Files.createDirectory(dockerVolumeDirectory.resolve("passwordDownload")); + remoteKeypairUploadDirectory = + Files.createDirectory(dockerVolumeDirectory.resolve("keypairUpload")); + remoteKeypairDownloadDirectory = + Files.createDirectory(dockerVolumeDirectory.resolve("keypairDownload")); + keyDirectory = Files.createTempDirectory(SftpClientWrapperIT.class.getName()); + publicKeyPath = keyDirectory.resolve("public"); + + try (final OutputStreamWriter fileWriter = + new OutputStreamWriter(new FileOutputStream(publicKeyPath.toString()))) { + final RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + final RSAKeyParameters publicKeyParameters = + new RSAKeyParameters(false, publicKey.getModulus(), publicKey.getPublicExponent()); + byte[] encodedKey = OpenSSHPublicKeyUtil.encodePublicKey(publicKeyParameters); + String keyString = Base64.getEncoder().encodeToString(encodedKey); + String authKeysEntry = String.format("ssh-rsa %s", keyString); + fileWriter.write(authKeysEntry); + } + + Files.setPosixFilePermissions(dockerVolumeDirectory, fullPermission); + Files.setPosixFilePermissions(remotePasswordUploadDirectory, fullPermission); + Files.setPosixFilePermissions(remotePasswordDownloadDirectory, fullPermission); + Files.setPosixFilePermissions(remoteKeypairUploadDirectory, fullPermission); + Files.setPosixFilePermissions(remoteKeypairDownloadDirectory, fullPermission); + Files.setPosixFilePermissions(keyDirectory, fullPermission); + } catch (IOException e) { + throw new RuntimeException(); + } + + sftpContainer = + new GenericContainer<>(DockerImageName.parse(DOCKER_IMAGE_NAME)) + .withEnv(DOCKER_ENV) + .withExposedPorts(22) + .waitingFor(Wait.forListeningPort()) + .withFileSystemBind( + dockerVolumeDirectory.toAbsolutePath().toString(), + String.format("/home/user/%s", sftpPathPrefix)) + .withFileSystemBind(keyDirectory.toAbsolutePath().toString(), "/home/user/keys"); + sftpContainer.start(); + + await().atMost(10, SECONDS).until(sftpContainer::isRunning); + + try { + sftpContainer.execInContainer("mkdir", "-p", "/home/user/.ssh"); + sftpContainer.execInContainer("chmod", "700", "/home/user/.ssh"); + sftpContainer.execInContainer("chown", "user", "/home/user/.ssh/"); + sftpContainer.execInContainer( + "cp", "-f", "/home/user/keys/public", "/home/user/.ssh/authorized_keys"); + sftpContainer.execInContainer("chown", "user", "/home/user/.ssh/authorized_keys"); + sftpContainer.execInContainer("chmod", "600", "/home/user/.ssh/authorized_keys"); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(); + } + } + + @AfterAll + @SneakyThrows + static void tearDown() { + if (Files.exists(dockerVolumeDirectory)) { + Files.walk(dockerVolumeDirectory) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + if (Files.exists(localUploadAndGeneratorDirectory)) { + Files.walk(localUploadAndGeneratorDirectory) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + if (Files.exists(keyDirectory)) { + Files.walk(keyDirectory) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::delete); + } + } + + protected SftpUser getPasswordUser() { + return SftpUser.builder().name("user").password("password").build(); + } + + protected SftpUser getKeyPairUser() { + return SftpUser.builder().name("user").keyPair(keyPair).build(); + } + + protected SftpLocation getSftpLocation(String path) { + return SftpLocation.builder() + .host("127.0.0.1") + .port(sftpContainer.getFirstMappedPort()) + .path(path) + .build(); + } + + protected SftpClientWrapper getSftpClient(SftpLocation location, SftpUser sftpUser) { + SftpClientConfig config = + SftpClientConfig.builder() + .sftpLocation(location) + .sftpUser(sftpUser) + .hostVerification(false) + .build(); + return new SftpClientWrapperImpl(config); + } + + @NoArgsConstructor + protected static class FilesProvider implements ArgumentsProvider { + @Override + public Stream provideArguments(ExtensionContext context) { + return Stream.of( + Arguments.of(get1KBFile()), Arguments.of(get1MBFile()), Arguments.of(get2MBFile())); + } + + private static final int BUFFER_SIZE = 4 * 1024 * 1024; + + public File get1KBFile() { + return generateFile(1 * 1024); + } + + public File get1MBFile() { + return generateFile(1 * 1024 * 1024); + } + + public File get2MBFile() { + return generateFile(2 * 1024 * 1024); + } + + @SneakyThrows + private File generateFile(final int byteSize) { + Path path = localUploadAndGeneratorDirectory.resolve(String.format("%s.bin", byteSize)); + if (!Files.exists(path)) { + Files.createFile(path); + try (final OutputStream outputStream = Files.newOutputStream(path)) { + int bufferSize; + int remaining = byteSize; + do { + bufferSize = Math.min(remaining, BUFFER_SIZE); + byte[] chunk = RandomUtils.nextBytes(bufferSize); + IOUtils.write(chunk, outputStream); + remaining = remaining - bufferSize; + } while (remaining > 0); + } + } + return path.toFile(); + } + } + + @SneakyThrows + private static KeyPair generateKeyPair() { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + return keyPairGenerator.generateKeyPair(); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperIT.java b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperIT.java new file mode 100644 index 000000000..368db5bf8 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperIT.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial Test + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.client; + +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import lombok.Cleanup; +import lombok.SneakyThrows; +import org.eclipse.edc.junit.extensions.EdcExtension; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.shaded.org.apache.commons.io.IOUtils; + +@Disabled("Does not work") +@Testcontainers +@ExtendWith(EdcExtension.class) +class SftpClientWrapperIT extends AbstractSftpClientWrapperIT { + + @ParameterizedTest + @SneakyThrows + @ArgumentsSource(FilesProvider.class) + void uploadFileWithPassword(File file) { + final SftpUser sftpUser = getPasswordUser(); + final SftpLocation sftpLocation = + getSftpLocation( + String.format( + "%s/%s/%s", + sftpPathPrefix, + remotePasswordUploadDirectory.getFileName().toString(), + file.getName())); + + @Cleanup final InputStream fileStream = Files.newInputStream(file.toPath()); + + getSftpClient(sftpLocation, sftpUser).uploadFile(fileStream); + + final Path uploadedFilePath = remotePasswordUploadDirectory.resolve(file.getName()); + Assertions.assertTrue(Files.exists(uploadedFilePath)); + + @Cleanup final InputStream source = Files.newInputStream(file.toPath()); + @Cleanup final InputStream target = Files.newInputStream(uploadedFilePath); + + Assertions.assertTrue( + IOUtils.contentEquals(source, target), + String.format( + "File %s should have same content as file %s", file.toPath(), uploadedFilePath)); + } + + @ParameterizedTest + @SneakyThrows + @ArgumentsSource(FilesProvider.class) + void uploadFileWithKeyPair(File file) { + final SftpUser sftpUser = getKeyPairUser(); + final SftpLocation sftpLocation = + getSftpLocation( + String.format( + "%s/%s/%s", + sftpPathPrefix, + remoteKeypairUploadDirectory.getFileName().toString(), + file.getName())); + + @Cleanup final InputStream fileStream = Files.newInputStream(file.toPath()); + + getSftpClient(sftpLocation, sftpUser).uploadFile(fileStream); + + final Path uploadedFilePath = remoteKeypairUploadDirectory.resolve(file.getName()); + Assertions.assertTrue(Files.exists(uploadedFilePath)); + + @Cleanup final InputStream source = Files.newInputStream(file.toPath()); + @Cleanup final InputStream target = Files.newInputStream(uploadedFilePath); + + Assertions.assertTrue( + IOUtils.contentEquals(source, target), + String.format( + "File %s should have same content as file %s", file.toPath(), uploadedFilePath)); + } + + @ParameterizedTest + @SneakyThrows + @ArgumentsSource(FilesProvider.class) + void downloadFileWithPassword(File file) { + final SftpUser sftpUser = getPasswordUser(); + final SftpLocation sftpLocation = + getSftpLocation( + String.format( + "%s/%s/%s", + sftpPathPrefix, + remotePasswordDownloadDirectory.getFileName().toString(), + file.getName())); + + @Cleanup final InputStream fileToUpload = Files.newInputStream(file.toPath()); + Files.copy( + fileToUpload, + remotePasswordDownloadDirectory.resolve(file.getName()), + StandardCopyOption.REPLACE_EXISTING); + + @Cleanup final InputStream source = Files.newInputStream(file.toPath()); + @Cleanup final InputStream target = getSftpClient(sftpLocation, sftpUser).downloadFile(); + + Assertions.assertTrue( + IOUtils.contentEquals(source, target), + String.format( + "File %s should have same content as file %s", file.toPath(), sftpLocation.getPath())); + } + + @ParameterizedTest + @SneakyThrows + @ArgumentsSource(FilesProvider.class) + void downloadFileWithKeyPair(File file) { + final SftpUser sftpUser = getKeyPairUser(); + final SftpLocation sftpLocation = + getSftpLocation( + String.format( + "%s/%s/%s", + sftpPathPrefix, + remoteKeypairDownloadDirectory.getFileName().toString(), + file.getName())); + + @Cleanup final InputStream fileToUpload = Files.newInputStream(file.toPath()); + Files.copy( + fileToUpload, + remoteKeypairDownloadDirectory.resolve(file.getName()), + StandardCopyOption.REPLACE_EXISTING); + + @Cleanup final InputStream source = Files.newInputStream(file.toPath()); + @Cleanup final InputStream target = getSftpClient(sftpLocation, sftpUser).downloadFile(); + + Assertions.assertTrue( + IOUtils.contentEquals(source, target), + String.format( + "File %s should have same content as file %s", file.toPath(), sftpLocation.getPath())); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperTest.java b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperTest.java new file mode 100644 index 000000000..7fcb0196c --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpClientWrapperTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.client; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.List; +import lombok.SneakyThrows; +import org.apache.sshd.sftp.client.SftpClient; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class SftpClientWrapperTest { + @Test + @SneakyThrows + void uploadFile() { + SftpUser userMock = Mockito.mock(SftpUser.class); + SftpLocation locationMock = Mockito.mock(SftpLocation.class); + SftpClientConfig sftpClientConfig = + SftpClientConfig.builder().sftpUser(userMock).sftpLocation(locationMock).build(); + SftpClient sftpClientMock = Mockito.mock(SftpClient.class); + SftpClientWrapperImpl sftpClientWrapper = + Mockito.spy(new SftpClientWrapperImpl(sftpClientConfig, sftpClientMock)); + byte[] content = new byte[] {0, 1, 2}; + InputStream inputStream = new ByteArrayInputStream(content); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + Mockito.when(locationMock.getPath()).thenReturn("path"); + Mockito.when( + sftpClientMock.write(Mockito.anyString(), Mockito.anyInt(), Mockito.anyCollection())) + .thenReturn(outputStream); + sftpClientWrapper.uploadFile(inputStream); + + Assertions.assertArrayEquals(content, outputStream.toByteArray()); + Mockito.verify(sftpClientMock, Mockito.times(1)) + .write("path", 4096, List.of(SftpClient.OpenMode.Create, SftpClient.OpenMode.Write)); + } + + @Test + @SneakyThrows + void downloadFile() { + SftpUser userMock = Mockito.mock(SftpUser.class); + SftpLocation locationMock = Mockito.mock(SftpLocation.class); + SftpClientConfig sftpClientConfig = + SftpClientConfig.builder().sftpUser(userMock).sftpLocation(locationMock).build(); + SftpClient sftpClientMock = Mockito.mock(SftpClient.class); + SftpClientWrapperImpl sftpClientWrapper = + Mockito.spy(new SftpClientWrapperImpl(sftpClientConfig, sftpClientMock)); + byte[] content = new byte[] {0, 1, 2}; + InputStream inputStream = new ByteArrayInputStream(content); + + Mockito.when(locationMock.getPath()).thenReturn("path"); + Mockito.when( + sftpClientMock.read(Mockito.anyString(), Mockito.anyInt(), Mockito.anyCollection())) + .thenReturn(inputStream); + + try (InputStream resultStream = sftpClientWrapper.downloadFile()) { + Assertions.assertArrayEquals(content, resultStream.readAllBytes()); + Mockito.verify(sftpClientMock, Mockito.times(1)) + .read("path", 4096, List.of(SftpClient.OpenMode.Read)); + } + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkFactoryTest.java b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkFactoryTest.java new file mode 100644 index 000000000..835c764cc --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkFactoryTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.client; + +import java.util.List; +import java.util.Map; +import lombok.SneakyThrows; +import org.apache.sshd.sftp.client.SftpClient; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.spi.types.domain.transfer.DataFlowRequest; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +class SftpDataSinkFactoryTest { + + @Test + void validate__valid() { + SftpDataSinkFactory dataSinkFactory = new SftpDataSinkFactory(); + SftpUser sftpUser = SftpUser.builder().name("name").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + + SftpDataAddress sftpDataAddress = + SftpDataAddress.builder().sftpUser(sftpUser).sftpLocation(sftpLocation).build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getDestinationDataAddress()).thenReturn(sftpDataAddress); + + Assertions.assertTrue(dataSinkFactory.validate(request).succeeded()); + } + + @Test + void validate__invalidDataAddressType() { + SftpDataSinkFactory dataSinkFactory = new SftpDataSinkFactory(); + DataAddress dataAddress = DataAddress.Builder.newInstance().type("wrong").build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getDestinationDataAddress()).thenReturn(dataAddress); + + Assertions.assertTrue(dataSinkFactory.validate(request).failed()); + } + + @Test + void validate__invalidDataAddressParameters() { + SftpDataSinkFactory dataSinkFactory = new SftpDataSinkFactory(); + final Map properties = + Map.of( + "type", "sftp", + "locationHost", "localhost", + "locationPort", "notANumber", + "locationPath", "path", + "userName", "name", + "userPassword", "password"); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getDestinationDataAddress()).thenReturn(dataAddress); + + Assertions.assertTrue(dataSinkFactory.validate(request).failed()); + } + + @Test + @SneakyThrows + void createSink__successful() { + SftpDataSinkFactory dataSinkFactory = new SftpDataSinkFactory(); + SftpUser sftpUser = SftpUser.builder().name("name").build(); + SftpLocation sftpLocation = + SftpLocation.builder().host("127.0.0.1").port(22).path("path").build(); + SftpClientConfig sftpClientConfig = + SftpClientConfig.builder() + .writeOpenModes(List.of(SftpClient.OpenMode.Create, SftpClient.OpenMode.Append)) + .sftpUser(sftpUser) + .sftpLocation(sftpLocation) + .build(); + + SftpDataAddress sftpDataAddress = + SftpDataAddress.builder().sftpUser(sftpUser).sftpLocation(sftpLocation).build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getDestinationDataAddress()).thenReturn(sftpDataAddress); + + try (MockedStatic staticWrapper = + Mockito.mockStatic(SftpClientWrapperImpl.class)) { + staticWrapper + .when(() -> SftpClientWrapperImpl.getSftpClient(sftpClientConfig)) + .thenReturn(Mockito.mock(SftpClient.class)); + Assertions.assertNotNull(dataSinkFactory.createSink(request)); + + staticWrapper.verify( + () -> SftpClientWrapperImpl.getSftpClient(Mockito.any()), Mockito.times(1)); + } + } + + @Test + @SneakyThrows + void createSink__invalidDataAddressType() { + SftpDataSinkFactory dataSinkFactory = new SftpDataSinkFactory(); + DataAddress dataAddress = DataAddress.Builder.newInstance().type("wrong").build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getDestinationDataAddress()).thenReturn(dataAddress); + + Assertions.assertNull(dataSinkFactory.createSink(request)); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkTest.java b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkTest.java new file mode 100644 index 000000000..7af9eea1f --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSinkTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.client; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.SneakyThrows; +import org.apache.sshd.sftp.client.SftpClient; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSource; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class SftpDataSinkTest { + @Test + @SneakyThrows + void transferParts() { + final SftpUser userMock = Mockito.mock(SftpUser.class); + final SftpLocation locationMock = Mockito.mock(SftpLocation.class); + final SftpClientConfig sftpClientConfig = + SftpClientConfig.builder() + .sftpUser(userMock) + .sftpLocation(locationMock) + .writeOpenModes(List.of(SftpClient.OpenMode.Create, SftpClient.OpenMode.Append)) + .build(); + final SftpClient sftpClientMock = Mockito.mock(SftpClient.class); + final SftpClientWrapperImpl sftpClientWrapper = + Mockito.spy(new SftpClientWrapperImpl(sftpClientConfig, sftpClientMock)); + final SftpDataSink sftpDataSink = Mockito.spy(new SftpDataSink(sftpClientWrapper)); + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + Mockito.when(sftpClientMock.write(Mockito.any(), Mockito.anyInt(), Mockito.anyCollection())) + .thenReturn(outputStream); + Mockito.when(locationMock.getPath()).thenReturn("path"); + + List parts = + Arrays.asList(new SftpTestPart(new byte[] {0, 1}), new SftpTestPart(new byte[] {2, 3})); + byte[] expected = {0, 1, 2, 3}; + + sftpDataSink.transferParts(parts); + + Assertions.assertArrayEquals(expected, outputStream.toByteArray()); + Mockito.verify(sftpClientMock, Mockito.times(2)) + .write("path", 4096, List.of(SftpClient.OpenMode.Create, SftpClient.OpenMode.Append)); + } + + @AllArgsConstructor + private static class SftpTestPart implements DataSource.Part { + + final byte[] content; + + @Override + public String name() { + return null; + } + + @Override + public InputStream openStream() { + return new ByteArrayInputStream(content); + } + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceFactoryTest.java b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceFactoryTest.java new file mode 100644 index 000000000..5c8a63f4f --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceFactoryTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.client; + +import java.util.Map; +import lombok.SneakyThrows; +import org.apache.sshd.sftp.client.SftpClient; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.edc.spi.types.domain.transfer.DataFlowRequest; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +class SftpDataSourceFactoryTest { + + @Test + void validate__valid() { + SftpDataSourceFactory dataSourceFactory = new SftpDataSourceFactory(); + SftpUser sftpUser = SftpUser.builder().name("name").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + + SftpDataAddress sftpDataAddress = + SftpDataAddress.builder().sftpUser(sftpUser).sftpLocation(sftpLocation).build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getSourceDataAddress()).thenReturn(sftpDataAddress); + + Assertions.assertTrue(dataSourceFactory.validate(request).succeeded()); + } + + @Test + void validate__invalidDataAddressType() { + SftpDataSourceFactory dataSourceFactory = new SftpDataSourceFactory(); + DataAddress dataAddress = DataAddress.Builder.newInstance().type("wrong").build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getSourceDataAddress()).thenReturn(dataAddress); + + Assertions.assertTrue(dataSourceFactory.validate(request).failed()); + } + + @Test + void validate__invalidDataAddressParameters() { + SftpDataSourceFactory dataSourceFactory = new SftpDataSourceFactory(); + final Map properties = + Map.of( + "type", "sftp", + "locationHost", "localhost", + "locationPort", "notANumber", + "locationPath", "path", + "userName", "name", + "userPassword", "password"); + + DataAddress dataAddress = DataAddress.Builder.newInstance().properties(properties).build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getSourceDataAddress()).thenReturn(dataAddress); + + Assertions.assertTrue(dataSourceFactory.validate(request).failed()); + } + + @Test + @SneakyThrows + void createSink__successful() { + SftpDataSourceFactory dataSourceFactory = new SftpDataSourceFactory(); + SftpUser sftpUser = SftpUser.builder().name("name").build(); + SftpLocation sftpLocation = + SftpLocation.builder().host("127.0.0.1").port(22).path("path").build(); + SftpClientConfig sftpClientConfig = + SftpClientConfig.builder().sftpUser(sftpUser).sftpLocation(sftpLocation).build(); + + SftpDataAddress sftpDataAddress = + SftpDataAddress.builder().sftpUser(sftpUser).sftpLocation(sftpLocation).build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getSourceDataAddress()).thenReturn(sftpDataAddress); + + try (MockedStatic staticWrapper = + Mockito.mockStatic(SftpClientWrapperImpl.class)) { + staticWrapper + .when(() -> SftpClientWrapperImpl.getSftpClient(sftpClientConfig)) + .thenReturn(Mockito.mock(SftpClient.class)); + Assertions.assertNotNull(dataSourceFactory.createSource(request)); + + staticWrapper.verify( + () -> SftpClientWrapperImpl.getSftpClient(Mockito.any()), Mockito.times(1)); + } + } + + @Test + @SneakyThrows + void createSink__invalidDataAddressType() { + SftpDataSourceFactory dataSourceFactory = new SftpDataSourceFactory(); + DataAddress dataAddress = DataAddress.Builder.newInstance().type("wrong").build(); + DataFlowRequest request = Mockito.mock(DataFlowRequest.class); + Mockito.when(request.getSourceDataAddress()).thenReturn(dataAddress); + + Assertions.assertNull(dataSourceFactory.createSource(request)); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceTest.java b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceTest.java new file mode 100644 index 000000000..7288c6442 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/client/SftpDataSourceTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.client; + +import java.io.ByteArrayInputStream; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.SneakyThrows; +import org.apache.sshd.sftp.client.SftpClient; +import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSource; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class SftpDataSourceTest { + @Test + @SneakyThrows + void openPartStream() { + final SftpUser userMock = Mockito.mock(SftpUser.class); + final SftpLocation locationMock = Mockito.mock(SftpLocation.class); + final SftpClientConfig sftpClientConfig = + SftpClientConfig.builder().sftpUser(userMock).sftpLocation(locationMock).build(); + final SftpClient sftpClientMock = Mockito.mock(SftpClient.class); + final SftpClientWrapperImpl sftpClientWrapper = + Mockito.spy(new SftpClientWrapperImpl(sftpClientConfig, sftpClientMock)); + SftpDataSource sftpDataSource = Mockito.spy(new SftpDataSource(sftpClientWrapper)); + byte[] expected = new byte[] {0, 1, 2, 3}; + ByteArrayInputStream outputStream = new ByteArrayInputStream(expected); + + Mockito.when(locationMock.getPath()).thenReturn("path"); + Mockito.when( + sftpClientMock.read(Mockito.anyString(), Mockito.anyInt(), Mockito.anyCollection())) + .thenReturn(outputStream); + + Stream partStream = sftpDataSource.openPartStream(); + DataSource.Part part = partStream.collect(Collectors.toList()).get(0); + + Assertions.assertArrayEquals(expected, part.openStream().readAllBytes()); + Mockito.verify(sftpClientMock, Mockito.times(1)) + .read("path", 4096, List.of(SftpClient.OpenMode.Read)); + } +} diff --git a/edc-extensions/transferprocess-sftp-client/src/test/resources/logback.xml b/edc-extensions/transferprocess-sftp-client/src/test/resources/logback.xml new file mode 100644 index 000000000..3347fcbae --- /dev/null +++ b/edc-extensions/transferprocess-sftp-client/src/test/resources/logback.xml @@ -0,0 +1,23 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] sdfsfs %-5level %logger{36} - %msg%n + + + + + + diff --git a/edc-extensions/transferprocess-sftp-common/build.gradle.kts b/edc-extensions/transferprocess-sftp-common/build.gradle.kts new file mode 100644 index 000000000..1226ccce1 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-common/build.gradle.kts @@ -0,0 +1,12 @@ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + implementation(edc.spi.core) + testImplementation(edc.junit) + + testImplementation(libs.mockito.inline) + testImplementation(libs.testcontainers.junit)} diff --git a/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/EdcSftpException.java b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/EdcSftpException.java new file mode 100644 index 000000000..aa6151eec --- /dev/null +++ b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/EdcSftpException.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.common; + +import org.eclipse.edc.spi.EdcException; + +public class EdcSftpException extends EdcException { + public EdcSftpException(String message) { + super(message); + } + + public EdcSftpException(String message, Throwable cause) { + super(message, cause); + } + + public EdcSftpException(Throwable cause) { + super(cause); + } + + public EdcSftpException( + String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpDataAddress.java b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpDataAddress.java new file mode 100644 index 000000000..0a9b8ef03 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpDataAddress.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.common; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import org.eclipse.edc.spi.types.domain.DataAddress; + +@AllArgsConstructor +@Builder +@Getter +public class SftpDataAddress extends DataAddress { + private static final String LOCATION_HOST = "locationHost"; + private static final String LOCATION_PORT = "locationPort"; + private static final String LOCATION_PATH = "locationPath"; + private static final String USER_NAME = "userName"; + private static final String USER_PASSWORD = "userPassword"; + private static final String USER_PRIVATE_KEY = "userPrivateKey"; + + @Getter private static final String CONNECTION_TYPE = "sftp"; + @NonNull private final SftpUser sftpUser; + @NonNull private final SftpLocation sftpLocation; + + public static SftpDataAddress fromDataAddress(DataAddress dataAddress) throws EdcSftpException { + if (dataAddress instanceof SftpDataAddress) { + return (SftpDataAddress) dataAddress; + } + + if (!dataAddress.getType().equalsIgnoreCase("sftp")) { + throw new EdcSftpException( + String.format( + "Invalid DataAddress type: %s. Expected %s.", + dataAddress.getType(), CONNECTION_TYPE)); + } + + try { + SftpUser sftpUser = + SftpUser.builder() + .name(dataAddress.getProperty(USER_NAME)) + .password(dataAddress.getProperty(USER_PASSWORD)) + .keyPair( + SftpUserKeyPairGenerator.getKeyPairFromPrivateKey( + dataAddress.getProperty(USER_PRIVATE_KEY), + dataAddress.getProperty(USER_NAME))) + .build(); + + SftpLocation sftpLocation = + SftpLocation.builder() + .host(dataAddress.getProperty(LOCATION_HOST)) + .port(Integer.valueOf(dataAddress.getProperty(LOCATION_PORT, "22"))) + .path(dataAddress.getProperty(LOCATION_PATH)) + .build(); + + return SftpDataAddress.builder().sftpUser(sftpUser).sftpLocation(sftpLocation).build(); + } catch (NullPointerException e) { + throw new EdcSftpException(e.getMessage(), e); + } catch (NumberFormatException e) { + throw new EdcSftpException( + String.format( + "Port for SftpLocation %s/%s not a number", + dataAddress.getProperty(LOCATION_HOST), dataAddress.getProperty(LOCATION_PATH)), + e); + } + } +} diff --git a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultClientConfig.java b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpLocation.java similarity index 52% rename from edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultClientConfig.java rename to edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpLocation.java index a9f0ee2a0..b9af1aecb 100644 --- a/edc-extensions/hashicorp-vault/src/main/java/net/catenax/edc/hashicorpvault/HashicorpVaultClientConfig.java +++ b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpLocation.java @@ -12,23 +12,23 @@ * */ -package net.catenax.edc.hashicorpvault; +package org.eclipse.tractusx.edc.transferprocess.sftp.common; -import java.time.Duration; import lombok.Builder; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; -import lombok.RequiredArgsConstructor; @Builder @Getter -@RequiredArgsConstructor -class HashicorpVaultClientConfig { - @NonNull private final String vaultUrl; - @NonNull private final String vaultToken; - @NonNull private final String vaultApiSecretPath; - @NonNull private final String vaultApiHealthPath; - @NonNull private final Duration timeout; +@EqualsAndHashCode +public class SftpLocation { + @NonNull private final String host; + @NonNull private final Integer port; + @NonNull private final String path; - private final boolean isVaultApiHealthStandbyOk; + @Override + public String toString() { + return String.format("%s:%d/%s", host, port, path); + } } diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoData.java b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpLocationFactory.java similarity index 68% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoData.java rename to edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpLocationFactory.java index 697a22ede..8c229d39f 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/data/CryptoData.java +++ b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpLocationFactory.java @@ -11,10 +11,9 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.data.encryption.data; -public interface CryptoData { - byte[] getBytes(); +package org.eclipse.tractusx.edc.transferprocess.sftp.common; - String getBase64(); +public interface SftpLocationFactory { + SftpLocation createSftpLocation(String sftpHost, Integer sftpPort, String sftpPath); } diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/KeyProvider.java b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpProvider.java similarity index 61% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/KeyProvider.java rename to edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpProvider.java index 8e9c8006c..4ddd29396 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/provider/KeyProvider.java +++ b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpProvider.java @@ -11,13 +11,15 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.data.encryption.provider; -import java.util.stream.Stream; -import net.catenax.edc.data.encryption.key.CryptoKey; +package org.eclipse.tractusx.edc.transferprocess.sftp.common; -public interface KeyProvider { - T getEncryptionKey(); +public interface SftpProvider { + void createUser(SftpUser user); - Stream getDecryptionKeySet(); + void deleteUser(SftpUser user); + + void createLocation(SftpLocation location); + + void deleteLocation(SftpLocation location); } diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/PublicKeyHolder.java b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUser.java similarity index 57% rename from edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/PublicKeyHolder.java rename to edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUser.java index 72edfb19f..b66dfc3e0 100644 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwk/PublicKeyHolder.java +++ b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUser.java @@ -11,15 +11,22 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.oauth2.jwk; -import java.security.PublicKey; +package org.eclipse.tractusx.edc.transferprocess.sftp.common; + +import java.security.KeyPair; import lombok.Builder; +import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.NonNull; +import lombok.ToString; -@Getter @Builder -public class PublicKeyHolder { - private final String keyId; - private final PublicKey publicKey; +@Getter +@ToString(of = "name") +@EqualsAndHashCode +public class SftpUser { + @NonNull private final String name; + private final String password; + private final KeyPair keyPair; } diff --git a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/AesKey.java b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUserFactory.java similarity index 67% rename from edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/AesKey.java rename to edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUserFactory.java index 136f0e360..ea04a125e 100644 --- a/edc-extensions/data-encryption/src/main/java/net/catenax/edc/data/encryption/key/AesKey.java +++ b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUserFactory.java @@ -11,10 +11,9 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.data.encryption.key; -public interface AesKey extends CryptoKey { - byte[] getBytes(); +package org.eclipse.tractusx.edc.transferprocess.sftp.common; - String getBase64(); +public interface SftpUserFactory { + SftpUser createSftpUser(String sftpUserName, String sftpUserPassword, byte[] sftpUserKeypair); } diff --git a/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUserKeyPairGenerator.java b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUserKeyPairGenerator.java new file mode 100644 index 000000000..55d2984ce --- /dev/null +++ b/edc-extensions/transferprocess-sftp-common/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpUserKeyPairGenerator.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.common; + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.util.Base64; +import lombok.AllArgsConstructor; +import lombok.NonNull; + +@AllArgsConstructor +public class SftpUserKeyPairGenerator { + public static KeyPair getKeyPairFromPrivateKey( + byte[] privateKeyBytes, @NonNull String sftpUserName) { + if (privateKeyBytes == null) { + return null; + } + + try { + final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + final PrivateKey privateKey = + keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes)); + + final RSAPrivateCrtKey privateKeySpec = (RSAPrivateCrtKey) privateKey; + + final PublicKey publicKey = + keyFactory.generatePublic( + new RSAPublicKeySpec( + privateKeySpec.getModulus(), privateKeySpec.getPublicExponent())); + return new KeyPair(publicKey, privateKey); + + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new EdcSftpException( + String.format("Unable to parse provided keypair for Sftp user %s", sftpUserName), e); + } + } + + public static KeyPair getKeyPairFromPrivateKey(String privateKey, @NonNull String sftpUserName) { + if (privateKey == null) { + return null; + } + + byte[] publicBytes; + try { + publicBytes = Base64.getDecoder().decode(privateKey); + } catch (IllegalArgumentException e) { + throw new EdcSftpException( + String.format("Cannot decode base64 private key for user %s", sftpUserName), e); + } + + return getKeyPairFromPrivateKey(publicBytes, sftpUserName); + } +} diff --git a/edc-extensions/transferprocess-sftp-common/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpDataAddressTest.java b/edc-extensions/transferprocess-sftp-common/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpDataAddressTest.java new file mode 100644 index 000000000..d29cdcd0e --- /dev/null +++ b/edc-extensions/transferprocess-sftp-common/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/common/SftpDataAddressTest.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.common; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.util.Base64; +import java.util.Map; +import lombok.SneakyThrows; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class SftpDataAddressTest { + + @Test + void fromDataAddress__password() { + final Map properties = + Map.of( + "type", "sftp", + "locationHost", "localhost", + "locationPort", "22", + "locationPath", "path", + "userName", "name", + "userPassword", "password"); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + + final SftpDataAddress sftpDataAddress = SftpDataAddress.fromDataAddress(dataAddress); + + Assertions.assertEquals("localhost", sftpDataAddress.getSftpLocation().getHost()); + Assertions.assertEquals(22, sftpDataAddress.getSftpLocation().getPort()); + Assertions.assertEquals("path", sftpDataAddress.getSftpLocation().getPath()); + Assertions.assertEquals("name", sftpDataAddress.getSftpUser().getName()); + Assertions.assertEquals("password", sftpDataAddress.getSftpUser().getPassword()); + Assertions.assertNull(sftpDataAddress.getSftpUser().getKeyPair()); + } + + @Test + @SneakyThrows + void fromDataAddress__keyPair() { + final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + final KeyPair keyPair = keyPairGenerator.generateKeyPair(); + final byte[] privateKeyBytes = keyPair.getPrivate().getEncoded(); + + final Map properties = + Map.of( + "type", "sftp", + "locationHost", "localhost", + "locationPort", "22", + "locationPath", "path", + "userName", "name", + "userPrivateKey", Base64.getEncoder().encodeToString(privateKeyBytes)); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + + final SftpDataAddress sftpDataAddress = SftpDataAddress.fromDataAddress(dataAddress); + + Assertions.assertEquals("localhost", sftpDataAddress.getSftpLocation().getHost()); + Assertions.assertEquals(22, sftpDataAddress.getSftpLocation().getPort()); + Assertions.assertEquals("path", sftpDataAddress.getSftpLocation().getPath()); + Assertions.assertEquals("name", sftpDataAddress.getSftpUser().getName()); + Assertions.assertArrayEquals( + privateKeyBytes, sftpDataAddress.getSftpUser().getKeyPair().getPrivate().getEncoded()); + Assertions.assertNull(sftpDataAddress.getSftpUser().getPassword()); + } + + @Test + @SneakyThrows + void fromDataAddress__noAuth() { + final Map properties = + Map.of( + "type", "sftp", + "locationHost", "localhost", + "locationPort", "22", + "locationPath", "path", + "userName", "name"); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + + final SftpDataAddress sftpDataAddress = SftpDataAddress.fromDataAddress(dataAddress); + + Assertions.assertEquals("localhost", sftpDataAddress.getSftpLocation().getHost()); + Assertions.assertEquals(22, sftpDataAddress.getSftpLocation().getPort()); + Assertions.assertEquals("path", sftpDataAddress.getSftpLocation().getPath()); + Assertions.assertEquals("name", sftpDataAddress.getSftpUser().getName()); + Assertions.assertNull(sftpDataAddress.getSftpUser().getPassword()); + } + + @Test + @SneakyThrows + void fromDataAddress__invalidKeyPairBrokenBase64() { + final Map properties = + Map.of( + "type", "sftp", + "locationHost", "localhost", + "locationPort", "22", + "locationPath", "path", + "userName", "name", + "userPrivateKey", "clearlyNotAPrivateKey"); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + + EdcSftpException edcSftpException = + Assertions.assertThrows( + EdcSftpException.class, () -> SftpDataAddress.fromDataAddress(dataAddress)); + Assertions.assertEquals( + "Cannot decode base64 private key for user name", edcSftpException.getMessage()); + } + + @Test + @SneakyThrows + void fromDataAddress__invalidKeyPairButCorrectBase64() { + final Map properties = + Map.of( + "type", "sftp", + "locationHost", "localhost", + "locationPort", "22", + "locationPath", "path", + "userName", "name", + "userPrivateKey", "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu"); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + + EdcSftpException edcSftpException = + Assertions.assertThrows( + EdcSftpException.class, () -> SftpDataAddress.fromDataAddress(dataAddress)); + Assertions.assertEquals( + "Unable to parse provided keypair for Sftp user name", edcSftpException.getMessage()); + } + + @Test + void fromDataAddress__portNaN() { + final Map properties = + Map.of( + "type", "sftp", + "locationHost", "localhost", + "locationPort", "notANumber", + "locationPath", "path", + "userName", "name", + "userPassword", "password"); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + + EdcSftpException edcSftpException = + Assertions.assertThrows( + EdcSftpException.class, () -> SftpDataAddress.fromDataAddress(dataAddress)); + Assertions.assertEquals( + "Port for SftpLocation localhost/path not a number", edcSftpException.getMessage()); + } + + @Test + void fromDataAddress__missingParameter() { + final Map properties = + Map.of( + "type", "sftp", + "locationPort", "22", + "locationPath", "path", + "userName", "name", + "userPassword", "password"); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + + EdcSftpException edcSftpException = + Assertions.assertThrows( + EdcSftpException.class, () -> SftpDataAddress.fromDataAddress(dataAddress)); + Assertions.assertEquals("host is marked non-null but is null", edcSftpException.getMessage()); + } + + @Test + void fromDataAddress__notSftp() { + final Map properties = + Map.of( + "type", "somethingOtherThanSftp", + "locationHost", "localhost", + "locationPort", "22", + "locationPath", "path", + "userName", "name", + "userPassword", "password"); + + final DataAddress dataAddress = + DataAddress.Builder.newInstance().properties(properties).build(); + + EdcSftpException edcSftpException = + Assertions.assertThrows( + EdcSftpException.class, () -> SftpDataAddress.fromDataAddress(dataAddress)); + Assertions.assertEquals( + "Invalid DataAddress type: somethingOtherThanSftp. Expected sftp.", + edcSftpException.getMessage()); + } +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/build.gradle.kts b/edc-extensions/transferprocess-sftp-provisioner/build.gradle.kts new file mode 100644 index 000000000..243af81d9 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/build.gradle.kts @@ -0,0 +1,17 @@ + +plugins { + `maven-publish` + `java-library` +} + +dependencies { + implementation(project(":edc-extensions:transferprocess-sftp-common")) + + implementation(edc.spi.core) + implementation(edc.policy.engine) + implementation(edc.spi.transfer) + + testImplementation(edc.junit) + testImplementation(libs.mockito.inline) + testImplementation(libs.testcontainers.junit) +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvider.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvider.java new file mode 100644 index 000000000..d12015d7d --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvider.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpProvider; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; + +public class NoOpSftpProvider implements SftpProvider { + + /** + * This provisioner does not create cloud resources. The assumption is that users and locations + * already exist cloud-side. Thus, this method has no functionality. + * + * @param user The user whose credentials should be deployed. + */ + @Override + public void createUser(SftpUser user) { + // do nothing + } + + /** + * This provisioner does not create cloud resources. The assumption is that users and locations + * already exist cloud-side. Thus, this method has no functionality. + * + * @param user The user whose credentials should be deleted. + */ + @Override + public void deleteUser(SftpUser user) { + // do nothing + } + + /** + * This provisioner does not create cloud resources. The assumption is that users and locations + * already exist cloud-side. Thus, this method has no functionality. + * + * @param location The location of the cloud resource that should be made available. + */ + @Override + public void createLocation(SftpLocation location) { + // do nothing + } + + /** + * This provisioner does not create cloud resources. The assumption is that users and locations + * already exist cloud-side. Thus, this method has no functionality. + * + * @param location The location of the cloud resource that should be made unavailable. + */ + @Override + public void deleteLocation(SftpLocation location) { + // do nothing + } +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvisioner.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvisioner.java new file mode 100644 index 000000000..978f4bc94 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvisioner.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + +import java.util.concurrent.CompletableFuture; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.transfer.spi.provision.Provisioner; +import org.eclipse.edc.connector.transfer.spi.types.DeprovisionedResource; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionResponse; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionedResource; +import org.eclipse.edc.connector.transfer.spi.types.ResourceDefinition; +import org.eclipse.edc.policy.engine.spi.PolicyEngine; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.response.ResponseStatus; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.EdcSftpException; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; + +@RequiredArgsConstructor +public class NoOpSftpProvisioner + implements Provisioner { + static final String DATA_ADDRESS_TYPE = "sftp"; + static final String PROVIDER_TYPE = "NoOp"; + + @NonNull private final String policyScope; + @NonNull private final PolicyEngine policyEngine; + @NonNull private final NoOpSftpProvider sftpProvider; + + @Override + public boolean canProvision(@NonNull ResourceDefinition resourceDefinition) { + if (!(resourceDefinition instanceof SftpProviderResourceDefinition)) { + return false; + } + if (!(((SftpProviderResourceDefinition) resourceDefinition) + .getProviderType() + .equals(PROVIDER_TYPE))) { + return false; + } + try { + SftpDataAddress.fromDataAddress( + ((SftpProviderResourceDefinition) resourceDefinition).getSftpDataAddress()); + } catch (EdcSftpException e) { + return false; + } + return true; + } + + @Override + public boolean canDeprovision(@NonNull ProvisionedResource provisionedResource) { + if (!(provisionedResource instanceof SftpProvisionedContentResource)) { + return false; + } + + if (!(((SftpProvisionedContentResource) provisionedResource) + .getProviderType() + .equals(PROVIDER_TYPE))) { + return false; + } + + try { + SftpDataAddress.fromDataAddress( + ((SftpProvisionedContentResource) provisionedResource).getSftpDataAddress()); + } catch (EdcSftpException e) { + return false; + } + return true; + } + + @Override + public CompletableFuture> provision( + SftpProviderResourceDefinition sftpProviderResourceDefinition, Policy policy) { + + return CompletableFuture.supplyAsync( + () -> { + if (!this.canProvision(sftpProviderResourceDefinition)) { + return StatusResult.failure(ResponseStatus.FATAL_ERROR); + } + // As of the time of writing, policies don't actually do anything in this context. + // They are included here in case EDC wants to use them eventually. + Policy scopedPolicy; + scopedPolicy = policyEngine.filter(policy, policyScope); + sftpProvider.createLocation( + sftpProviderResourceDefinition.getSftpDataAddress().getSftpLocation()); + sftpProvider.createUser( + sftpProviderResourceDefinition.getSftpDataAddress().getSftpUser()); + + SftpProvisionedContentResource sftpProvisionedContentResource = + SftpProvisionedContentResource.builder() + .sftpDataAddress(sftpProviderResourceDefinition.getSftpDataAddress()) + .providerType(PROVIDER_TYPE) + .scopedPolicy(scopedPolicy) + .provisionedResourceId( + generateResourceId( + sftpProviderResourceDefinition.getSftpDataAddress().getSftpUser(), + sftpProviderResourceDefinition.getSftpDataAddress().getSftpLocation())) + .build(); + + return StatusResult.success( + ProvisionResponse.Builder.newInstance() + .resource(sftpProvisionedContentResource) + .build()); + }); + } + + @Override + public CompletableFuture> deprovision( + SftpProvisionedContentResource sftpProvisionedContentResource, Policy policy) { + return CompletableFuture.supplyAsync( + () -> { + if (!this.canDeprovision(sftpProvisionedContentResource)) { + return StatusResult.failure(ResponseStatus.FATAL_ERROR); + } + // As of the time of writing, policies don't actually do anything in this context. + // They are included here in case EDC wants to use them eventually. + sftpProvider.deleteLocation( + sftpProvisionedContentResource.getSftpDataAddress().getSftpLocation()); + sftpProvider.deleteUser( + sftpProvisionedContentResource.getSftpDataAddress().getSftpUser()); + + DeprovisionedResource deprovisionedResource = + DeprovisionedResource.Builder.newInstance() + .provisionedResourceId(sftpProvisionedContentResource.getProvisionedResourceId()) + .inProcess(true) + .build(); + + return StatusResult.success(deprovisionedResource); + }); + } + + private String generateResourceId(SftpUser sftpUser, SftpLocation sftpLocation) { + return String.format( + "%s@%s:%d/%s", + sftpUser.getName(), sftpLocation.getHost(), sftpLocation.getPort(), sftpLocation.getPath()); + } +} diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/SubJwtDecorator.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpLocationFactoryImpl.java similarity index 50% rename from edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/SubJwtDecorator.java rename to edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpLocationFactoryImpl.java index 951fd8791..413c98335 100644 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/SubJwtDecorator.java +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpLocationFactoryImpl.java @@ -11,24 +11,17 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.oauth2.jwt.decorator; -import java.util.Map; -import lombok.NonNull; +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocationFactory; @RequiredArgsConstructor -public class SubJwtDecorator implements JwtDecorator { - @NonNull private final String subject; - - @Override - public Map claims() { - return Map.of(JWTClaimNames.SUBJECT, subject); - } - +public class SftpLocationFactoryImpl implements SftpLocationFactory { @Override - public Map headers() { - return Map.of(); + public SftpLocation createSftpLocation(String sftpHost, Integer sftpPort, String sftpPath) { + return SftpLocation.builder().host(sftpHost).port(sftpPort).path(sftpPath).build(); } } diff --git a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IatJwtDecorator.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinition.java similarity index 50% rename from edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IatJwtDecorator.java rename to edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinition.java index d8d34d7bb..a15c97cca 100644 --- a/edc-extensions/cx-oauth2/src/main/java/net/catenax/edc/oauth2/jwt/decorator/IatJwtDecorator.java +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinition.java @@ -11,27 +11,23 @@ * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation * */ -package net.catenax.edc.oauth2.jwt.decorator; -import java.time.Clock; -import java.util.Date; -import java.util.Map; +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + +import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import org.eclipse.dataspaceconnector.spi.jwt.JwtDecorator; +import org.eclipse.edc.connector.transfer.spi.types.ResourceDefinition; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +@Getter @RequiredArgsConstructor -public class IatJwtDecorator implements JwtDecorator { - - @NonNull private final Clock clock; - - @Override - public Map claims() { - return Map.of(JWTClaimNames.ISSUED_AT, Date.from(clock.instant())); - } +public class SftpProviderResourceDefinition extends ResourceDefinition { + @NonNull private String providerType; + @NonNull private SftpDataAddress sftpDataAddress; @Override - public Map headers() { - return Map.of(); + public > B toBuilder() { + return null; } } diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinitionGenerator.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinitionGenerator.java new file mode 100644 index 000000000..ed9c137e5 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinitionGenerator.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + +import static org.eclipse.tractusx.edc.transferprocess.sftp.provisioner.NoOpSftpProvisioner.PROVIDER_TYPE; + +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.transfer.spi.provision.ProviderResourceDefinitionGenerator; +import org.eclipse.edc.connector.transfer.spi.types.DataRequest; +import org.eclipse.edc.connector.transfer.spi.types.ResourceDefinition; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.EdcSftpException; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +import org.jetbrains.annotations.Nullable; + +@RequiredArgsConstructor +public class SftpProviderResourceDefinitionGenerator + implements ProviderResourceDefinitionGenerator { + + @Override + public @Nullable ResourceDefinition generate( + DataRequest dataRequest, DataAddress assetAddress, Policy policy) { + SftpDataAddress sftpDataAddress; + try { + sftpDataAddress = SftpDataAddress.fromDataAddress(assetAddress); + } catch (EdcSftpException e) { + return null; + } + return new SftpProviderResourceDefinition(PROVIDER_TYPE, sftpDataAddress); + } + + @Override + public boolean canGenerate(DataRequest dataRequest, DataAddress dataAddress, Policy policy) { + try { + SftpDataAddress.fromDataAddress(dataAddress); + } catch (EdcSftpException e) { + return false; + } + return true; + } +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionedContentResource.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionedContentResource.java new file mode 100644 index 000000000..5f7f364ab --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionedContentResource.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionedContentResource; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; + +@Getter +@RequiredArgsConstructor +@Builder +public class SftpProvisionedContentResource extends ProvisionedContentResource { + @NonNull private String providerType; + @NonNull private Policy scopedPolicy; + @NonNull private SftpDataAddress sftpDataAddress; + @NonNull private String provisionedResourceId; +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionerConfiguration.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionerConfiguration.java new file mode 100644 index 000000000..acf67ac29 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionerConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Microsoft Corporation + * + * 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: + * Microsoft Corporation - initial API and implementation + * Mercedes Benz Tech Innovation - adapt to SFTP + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + +import java.net.URL; +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; + +/** Configuration to create a resource definition and provisioner pair for sftp data transfer. */ +@Getter +@Builder +public class SftpProvisionerConfiguration { + + @NonNull private final String name; + + @NonNull @Builder.Default + private final ProvisionerType provisionerType = ProvisionerType.PROVIDER; + + @NonNull private final String dataAddressType; + @NonNull private final String policyScope; + @NonNull private final URL endpoint; + + public enum ProvisionerType { + CONSUMER, + PROVIDER + } +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionerExtension.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionerExtension.java new file mode 100644 index 000000000..eb3e3f80f --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProvisionerExtension.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + +import org.eclipse.edc.connector.transfer.spi.provision.ProviderResourceDefinitionGenerator; +import org.eclipse.edc.connector.transfer.spi.provision.ProvisionManager; +import org.eclipse.edc.policy.engine.spi.PolicyEngine; +import org.eclipse.edc.runtime.metamodel.annotation.Inject; +import org.eclipse.edc.runtime.metamodel.annotation.Provides; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; + +@Provides(NoOpSftpProvisioner.class) +public class SftpProvisionerExtension implements ServiceExtension { + + @Inject ProvisionManager provisionManager; + @Inject Monitor monitor; + @Inject PolicyEngine policyEngine; + + private static final String POLICY_SCOPE_CONFIG_PATH = "provisioner.sftp.policy.scope"; + private static final String DEFAULT_POLICY_SCOPE = "sftp.provisioner"; + + @Override + public String name() { + return "Sftp Provisioner"; + } + + @Override + public void initialize(ServiceExtensionContext context) { + final String policyScope = + context.getConfig().getString(POLICY_SCOPE_CONFIG_PATH, DEFAULT_POLICY_SCOPE); + + final NoOpSftpProvider sftpProvider = new NoOpSftpProvider(); + final NoOpSftpProvisioner noOpSftpProvisioner = + new NoOpSftpProvisioner(policyScope, policyEngine, sftpProvider); + final SftpProviderResourceDefinitionGenerator generator = + new SftpProviderResourceDefinitionGenerator(); + provisionManager.register(noOpSftpProvisioner); + context.registerService(ProviderResourceDefinitionGenerator.class, generator); + + monitor.info("SftpProvisionerExtension: authentication/initialization complete."); + } +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpUserFactoryImpl.java b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpUserFactoryImpl.java new file mode 100644 index 000000000..2bb921fdf --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpUserFactoryImpl.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: + * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * + */ + +package org.eclipse.tractusx.edc.transferprocess.sftp.provisioner; + +import java.security.KeyPair; +import lombok.Builder; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUserFactory; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUserKeyPairGenerator; + +@Builder +public class SftpUserFactoryImpl implements SftpUserFactory { + + @Override + public SftpUser createSftpUser( + String sftpUserName, String sftpUserPassword, byte[] sftpUserPrivateKey) { + KeyPair sftpUserKeyPair = + SftpUserKeyPairGenerator.getKeyPairFromPrivateKey(sftpUserPrivateKey, sftpUserName); + + return SftpUser.builder() + .name(sftpUserName) + .password(sftpUserPassword) + .keyPair(sftpUserKeyPair) + .build(); + } +} diff --git a/edc-extensions/business-partner-validation/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension b/edc-extensions/transferprocess-sftp-provisioner/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension similarity index 82% rename from edc-extensions/business-partner-validation/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension rename to edc-extensions/transferprocess-sftp-provisioner/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension index 226b41ab3..8656b38dd 100644 --- a/edc-extensions/business-partner-validation/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension +++ b/edc-extensions/transferprocess-sftp-provisioner/src/main/resources/META-INF/services/org.eclipse.dataspaceconnector.spi.system.ServiceExtension @@ -10,5 +10,4 @@ # Contributors: # Mercedes-Benz Tech Innovation GmbH - Initial ServiceExtension file # -# -net.catenax.edc.validation.businesspartner.BusinessPartnerValidationExtension + org.eclipse.tractusx.edc.transferprocess.sftp.provisioner.SftpProvisionerExtension diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvisionerTest.java b/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvisionerTest.java new file mode 100644 index 000000000..c5657191f --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/NoOpSftpProvisionerTest.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.provisioner; + +import java.util.concurrent.CompletableFuture; +import lombok.NoArgsConstructor; +import lombok.SneakyThrows; +import org.eclipse.edc.connector.transfer.spi.types.DeprovisionedResource; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionResponse; +import org.eclipse.edc.connector.transfer.spi.types.ProvisionedContentResource; +import org.eclipse.edc.connector.transfer.spi.types.ResourceDefinition; +import org.eclipse.edc.policy.engine.spi.PolicyEngine; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.response.StatusResult; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +class NoOpSftpProvisionerTest { + private final String policyScope = "scope"; + private final PolicyEngine policyEngine = Mockito.mock(PolicyEngine.class); + private final NoOpSftpProvider sftpProvider = new NoOpSftpProvider(); + + private final NoOpSftpProvisioner provisioner = + new NoOpSftpProvisioner(policyScope, policyEngine, sftpProvider); + + @Test + void canProvision__true() { + String provisionType = "NoOp"; + SftpUser sftpUser = SftpUser.builder().name("name").password("password").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + SftpDataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + SftpProviderResourceDefinition resourceDefinition = + new SftpProviderResourceDefinition(provisionType, dataAddress); + + Assertions.assertTrue(provisioner.canProvision(resourceDefinition)); + } + + @Test + void canProvision__falseProvisionType() { + String provisionType = "AmazonS3"; + SftpUser sftpUser = SftpUser.builder().name("name").password("password").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + SftpDataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + SftpProviderResourceDefinition resourceDefinition = + new SftpProviderResourceDefinition(provisionType, dataAddress); + + Assertions.assertFalse(provisioner.canProvision(resourceDefinition)); + } + + @Test + void canProvision__falseDefinitionType() { + ResourceDefinition resourceDefinition = new WrongResourceDefinition(); + + Assertions.assertFalse(provisioner.canProvision(resourceDefinition)); + } + + @Test + void canDeprovision__true() { + String provisionType = "NoOp"; + SftpUser sftpUser = SftpUser.builder().name("name").password("password").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + Policy scopedPolicy = Mockito.mock(Policy.class); + SftpDataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + String provisionedResourceID = "resource"; + SftpProvisionedContentResource provisionedContentResource = + new SftpProvisionedContentResource( + provisionType, scopedPolicy, dataAddress, provisionedResourceID); + + Assertions.assertTrue(provisioner.canDeprovision(provisionedContentResource)); + } + + @Test + void canDeprovision__falseProvisionType() { + String provisionType = "AmazonS3"; + SftpUser sftpUser = SftpUser.builder().name("name").password("password").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + Policy scopedPolicy = Mockito.mock(Policy.class); + SftpDataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + String provisionedResourceID = "resource"; + SftpProvisionedContentResource provisionedContentResource = + new SftpProvisionedContentResource( + provisionType, scopedPolicy, dataAddress, provisionedResourceID); + + Assertions.assertFalse(provisioner.canDeprovision(provisionedContentResource)); + } + + @Test + void canDeprovision__falseDefinitionType() { + ProvisionedContentResource provisionedContentResource = new WrongProvisionedContentResource(); + + Assertions.assertFalse(provisioner.canDeprovision(provisionedContentResource)); + } + + @Test + @SneakyThrows + void provision__successful() { + String provisionType = "NoOp"; + SftpUser sftpUser = SftpUser.builder().name("name").password("password").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + SftpDataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + SftpProviderResourceDefinition resourceDefinition = + new SftpProviderResourceDefinition(provisionType, dataAddress); + Policy policy = Mockito.mock(Policy.class); + + Mockito.when(policyEngine.filter(policy, policyScope)).thenReturn(policy); + + CompletableFuture> future = + provisioner.provision(resourceDefinition, policy); + StatusResult result = future.get(); + + Assertions.assertTrue(result.succeeded()); + } + + @Test + @SneakyThrows + void provision__failedWrongProvisionType() { + String provisionType = "AmazonS3"; + SftpUser sftpUser = SftpUser.builder().name("name").password("password").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + SftpDataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + SftpProviderResourceDefinition resourceDefinition = + new SftpProviderResourceDefinition(provisionType, dataAddress); + Policy policy = Mockito.mock(Policy.class); + + Mockito.when(policyEngine.filter(policy, policyScope)).thenReturn(policy); + + CompletableFuture> future = + provisioner.provision(resourceDefinition, policy); + StatusResult result = future.get(); + + Assertions.assertTrue(result.failed()); + } + + @Test + @SneakyThrows + void deprovision__successful() { + String provisionType = "NoOp"; + SftpUser sftpUser = SftpUser.builder().name("name").password("password").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + SftpDataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + Policy policy = Mockito.mock(Policy.class); + String provisionedResourceID = "resource"; + SftpProvisionedContentResource provisionedContentResource = + new SftpProvisionedContentResource( + provisionType, policy, dataAddress, provisionedResourceID); + + CompletableFuture> future = + provisioner.deprovision(provisionedContentResource, policy); + StatusResult result = future.get(); + + Assertions.assertTrue(result.succeeded()); + } + + @Test + @SneakyThrows + void deprovision__failedWrongProvisionType() { + String provisionType = "AmazonS3"; + SftpUser sftpUser = SftpUser.builder().name("name").password("password").build(); + SftpLocation sftpLocation = SftpLocation.builder().host("host").port(22).path("path").build(); + SftpDataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + Policy policy = Mockito.mock(Policy.class); + String provisionedResourceID = "resource"; + SftpProvisionedContentResource provisionedContentResource = + new SftpProvisionedContentResource( + provisionType, policy, dataAddress, provisionedResourceID); + + CompletableFuture> future = + provisioner.deprovision(provisionedContentResource, policy); + StatusResult result = future.get(); + + Assertions.assertTrue(result.failed()); + } + + @NoArgsConstructor + private static class WrongResourceDefinition extends ResourceDefinition { + @Override + public > B toBuilder() { + return null; + } + } + + @NoArgsConstructor + private static class WrongProvisionedContentResource extends ProvisionedContentResource {} +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpLocationFactoryImplTest.java b/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpLocationFactoryImplTest.java new file mode 100644 index 000000000..afca5d5ac --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpLocationFactoryImplTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.provisioner; + +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class SftpLocationFactoryImplTest { + private final SftpLocationFactoryImpl sftpLocationFactoryImpl = new SftpLocationFactoryImpl(); + + @Test + void generateSftpLocation() { + final String host = "host"; + final Integer port = 22; + final String path = "path"; + + final SftpLocation location = sftpLocationFactoryImpl.createSftpLocation(host, port, path); + + Assertions.assertEquals(host, location.getHost()); + Assertions.assertEquals(port, location.getPort()); + Assertions.assertEquals(path, location.getPath()); + } +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinitionGeneratorTest.java b/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinitionGeneratorTest.java new file mode 100644 index 000000000..d81252705 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpProviderResourceDefinitionGeneratorTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.provisioner; + +import static org.eclipse.tractusx.edc.transferprocess.sftp.provisioner.NoOpSftpProvisioner.DATA_ADDRESS_TYPE; +import static org.eclipse.tractusx.edc.transferprocess.sftp.provisioner.NoOpSftpProvisioner.PROVIDER_TYPE; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import lombok.SneakyThrows; +import org.eclipse.edc.connector.transfer.spi.types.DataRequest; +import org.eclipse.edc.policy.model.Policy; +import org.eclipse.edc.spi.types.domain.DataAddress; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpDataAddress; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpLocation; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class SftpProviderResourceDefinitionGeneratorTest { + private final SftpProviderResourceDefinitionGenerator generator = + new SftpProviderResourceDefinitionGenerator(); + + @Test + void generate__successful() { + final String name = "name"; + final String password = "password"; + final KeyPair keyPair = generateKeyPair(); + final String host = "host"; + final Integer port = 22; + final String path = "path"; + + final DataRequest dataRequest = + DataRequest.Builder.newInstance().destinationType(DATA_ADDRESS_TYPE).build(); + final SftpUser sftpUser = + SftpUser.builder().name(name).password(password).keyPair(keyPair).build(); + final SftpLocation sftpLocation = + SftpLocation.builder().host(host).port(port).path(path).build(); + final DataAddress dataAddress = new SftpDataAddress(sftpUser, sftpLocation); + final Policy policy = Policy.Builder.newInstance().build(); + + final SftpProviderResourceDefinition resourceDefinition = + (SftpProviderResourceDefinition) generator.generate(dataRequest, dataAddress, policy); + + Assertions.assertNotNull(resourceDefinition); + final SftpDataAddress sftpDataAddress = resourceDefinition.getSftpDataAddress(); + + Assertions.assertEquals(PROVIDER_TYPE, resourceDefinition.getProviderType()); + Assertions.assertEquals(host, sftpDataAddress.getSftpLocation().getHost()); + Assertions.assertEquals(port, sftpDataAddress.getSftpLocation().getPort()); + Assertions.assertEquals(path, sftpDataAddress.getSftpLocation().getPath()); + Assertions.assertEquals(name, sftpDataAddress.getSftpUser().getName()); + Assertions.assertEquals(password, sftpDataAddress.getSftpUser().getPassword()); + Assertions.assertEquals(keyPair, sftpDataAddress.getSftpUser().getKeyPair()); + } + + @Test + void generate__wrongDataAddressType() { + final DataRequest dataRequest = + DataRequest.Builder.newInstance().destinationType(DATA_ADDRESS_TYPE).build(); + final DataAddress dataAddress = DataAddress.Builder.newInstance().type("wrong").build(); + final Policy policy = Policy.Builder.newInstance().build(); + + final SftpProviderResourceDefinition resourceDefinition = + (SftpProviderResourceDefinition) generator.generate(dataRequest, dataAddress, policy); + + Assertions.assertNull(resourceDefinition); + } + + @SneakyThrows + static KeyPair generateKeyPair() { + final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + return keyPairGenerator.generateKeyPair(); + } +} diff --git a/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpUserFactoryImplTest.java b/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpUserFactoryImplTest.java new file mode 100644 index 000000000..29a456176 --- /dev/null +++ b/edc-extensions/transferprocess-sftp-provisioner/src/test/java/org/eclipse/tractusx/edc/transferprocess/sftp/provisioner/SftpUserFactoryImplTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 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.transferprocess.sftp.provisioner; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import lombok.SneakyThrows; +import org.eclipse.tractusx.edc.transferprocess.sftp.common.SftpUser; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class SftpUserFactoryImplTest { + private final SftpUserFactoryImpl sftpUserFactoryImpl = new SftpUserFactoryImpl(); + + @Test + @SneakyThrows + void generateSftpLocation() { + final String name = "name"; + final String password = "password"; + + final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); + final KeyPair keyPair = keyPairGenerator.generateKeyPair(); + final byte[] privateKeyBytes = keyPair.getPrivate().getEncoded(); + + final SftpUser sftpUser = sftpUserFactoryImpl.createSftpUser(name, password, privateKeyBytes); + + Assertions.assertEquals(name, sftpUser.getName()); + Assertions.assertEquals(password, sftpUser.getPassword()); + + Assertions.assertArrayEquals(privateKeyBytes, sftpUser.getKeyPair().getPrivate().getEncoded()); + } +} diff --git a/edc-tests/README.md b/edc-tests/README.md index 1169a1998..afb62c89a 100644 --- a/edc-tests/README.md +++ b/edc-tests/README.md @@ -1,7 +1,7 @@ # Invoke Business-Tests via Maven ```shell -./mvnw -pl edc-tests -Pbusiness-tests -pl edc-tests test -Dtest=net.catenax.edc.tests.features.RunCucumberTest +./gradlew :edc-tests:test -Dcucumber=true ``` # Test locally using Act Tool @@ -10,4 +10,7 @@ ```shell act -j business-test -``` \ No newline at end of file +``` + +# Run and debug Business-Tests local within IDE +Please refer to [run-local documentation in docs](../docs/development/Run-business-tests-local.md) diff --git a/edc-tests/build.gradle.kts b/edc-tests/build.gradle.kts new file mode 100644 index 000000000..b0652d231 --- /dev/null +++ b/edc-tests/build.gradle.kts @@ -0,0 +1,36 @@ +plugins { + `java-library` +} + +dependencies { + implementation(project(":edc-extensions:business-partner-validation")) + implementation(project(":edc-extensions:control-plane-adapter")) + implementation(project(":edc-extensions:cx-oauth2")) + implementation(project(":edc-extensions:data-encryption")) + implementation(project(":edc-extensions:dataplane-selector-configuration")) + implementation(project(":edc-extensions:hashicorp-vault")) + implementation(project(":edc-extensions:postgresql-migration")) + implementation(project(":edc-extensions:provision-additional-headers")) + implementation(project(":edc-extensions:transferprocess-sftp-client")) + implementation(project(":edc-extensions:transferprocess-sftp-common")) + implementation(project(":edc-extensions:transferprocess-sftp-provisioner")) + + + testImplementation("com.google.code.gson:gson:2.10") + testImplementation("org.apache.httpcomponents:httpclient:4.5.14") + testImplementation("org.junit.platform:junit-platform-suite:1.9.2") + testImplementation("io.cucumber:cucumber-java:7.11.1") + testImplementation("io.cucumber:cucumber-junit-platform-engine:7.11.1") + testImplementation("org.slf4j:slf4j-api:2.0.3") + testImplementation(libs.restAssured) + testImplementation(libs.postgres) + testImplementation(libs.awaitility) + testImplementation(libs.aws.s3) + testImplementation(edc.spi.core) +} + +tasks.withType(Test::class) { + onlyIf { + System.getProperty("cucumber") == "true" + } +} diff --git a/edc-tests/pom.xml b/edc-tests/pom.xml deleted file mode 100644 index 514e455d2..000000000 --- a/edc-tests/pom.xml +++ /dev/null @@ -1,206 +0,0 @@ - - - - 4.0.0 - - - net.catenax.edc - product-edc-parent - 0.1.6 - - - net.catenax.edc.tests - edc-tests - jar - - - ${project.groupId}_${project.artifactId} - 2.9.1 - 4.5.13 - 1.4.1 - 1.7.36 - - - - - org.projectlombok - lombok - test - - - com.google.code.gson - gson - ${com.google.code.gson.version} - test - - - org.apache.httpcomponents - httpclient - ${org.apache.httpcomponents.httpclient.version} - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.junit.platform - junit-platform-suite - test - - - io.cucumber - cucumber-java - test - - - io.cucumber - cucumber-junit-platform-engine - test - - - io.rest-assured - rest-assured - test - - - ch.qos.logback - logback-classic - ${ch.qos.logback.version} - test - - - org.slf4j - slf4j-api - ${org.slf4j.api.version} - test - - - org.postgresql - postgresql - ${org.postgresql.version} - test - - - org.awaitility - awaitility - test - - - - - - - default - - true - - - true - - - - business-tests - - false - - - - coverage - - true - - - - - org.jacoco - jacoco-maven-plugin - - - report - - report-aggregate - - verify - - - - - - - - - - net.catenax.edc.extensions - business-partner-validation - - - net.catenax.edc.extensions - dataplane-selector-configuration - - - net.catenax.edc.extensions - hashicorp-vault - - - net.catenax.edc.extensions - postgresql-migration - - - net.catenax.edc.extensions - data-encryption - - - net.catenax.edc.extensions - cx-oauth2 - - - - net.catenax.edc - edc-controlplane-base - - - net.catenax.edc - edc-controlplane-memory - - - net.catenax.edc - edc-controlplane-postgresql - - - net.catenax.edc - edc-controlplane-postgresql-hashicorp-vault - - - - net.catenax.edc - edc-dataplane-base - - - net.catenax.edc - edc-dataplane-azure-vault - - - net.catenax.edc - edc-dataplane-hashicorp-vault - - - - - diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/README.md b/edc-tests/src/main/resources/deployment/helm/all-in-one/README.md deleted file mode 100644 index e639dd387..000000000 --- a/edc-tests/src/main/resources/deployment/helm/all-in-one/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# All-In-One Deployment - -The Product EDC Demo Deployment creates a complete, independent and already configured EDC test environment. - -This deployment may function as - -- reference setup for teams, that want to create their own connector -- standalone test environment to try different things out - -## Setup - -Follow these steps to get a fully functional EDC demo environment out of the box. - -### Requirements - -Install on your machine: - -- Minikube - - Documentation https://minikube.sigs.k8s.io/docs/start/ -- Helm - - Documentation https://helm.sh/docs/intro/install/ - -## Start Demo Environment - -**Update Helm Dependencies** - -```bash -helm dependency update -``` - -**Install Demo Chart** - -```bash -helm install edc-all-in-one --namespace edc-all-in-one --create-namespace . -``` - -This will deploy the following components: - -![Deployed Components](diagrams/deployed_components.png) - -## Stop Demo Environment - -**Uninstall Demo Chart** - -```bash -helm uninstall edc-all-in-one --namespace edc-all-in-one -``` - -## Components - -Overview of the installed components. - -### EDC Control Plane - -The EDC Control Plane does - -- data/contract offering -- contract negotiation -- data transfer coordination - -Two control planes always talk to each other using IDS messages. Therefore, when telling one connector to talk to -another connector, the target endpoint must point to the IDS API (e.g `http://[myTargetConnector].com/api/v1/ids`). - -The connector owner should only talk to the control plane via the Data Management API. The API is not only used for -simple data management, but for initiating inter-connector communication as well. - -### EDC Data Plane - -The EDC Data Plane is used for the actual data transfer. - -At the time of writing the Data Plane may only function as HTTP proxy and does not support any other type of -transfer. Additional transfer capabilities could be added by including new EDC extensions in the Data Plane application. - -### PostgreSQL - -This database is used to persist the state of the Control Plane. - -### HashiCorp Vault - -The Control- and Data Plane will persist confidential in the vault and persist and communicate using only the secret -names. - -### Backend Application - -After a Data Transfer is successfully prepared the control plane will contact the a configurable endpoint with the -information it needs to initiate the data transfer. This transfer flow, where something like a Backend Application is -required, is unique to the HTTP Proxy data transfer flow. - -The Backend Application has an API endpoint, that is configured in the control plane. After it gets called with the data -transfer information, it will do the actual data transfer and store the data on disk. - -### Omejdn DAPS - -Instead of the Catena-X DAPS this demo configures and deploys it's own DAPS instance. diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/diagrams/deployed_components.png b/edc-tests/src/main/resources/deployment/helm/all-in-one/diagrams/deployed_components.png deleted file mode 100644 index b91338ef6..000000000 Binary files a/edc-tests/src/main/resources/deployment/helm/all-in-one/diagrams/deployed_components.png and /dev/null differ diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/diagrams/deployed_components.puml b/edc-tests/src/main/resources/deployment/helm/all-in-one/diagrams/deployed_components.puml deleted file mode 100644 index 9880baf85..000000000 --- a/edc-tests/src/main/resources/deployment/helm/all-in-one/diagrams/deployed_components.puml +++ /dev/null @@ -1,47 +0,0 @@ -@startuml - -!define sokratesColor 66CCFF -!define platoColor CCFF99 -!define dapsColor FFFF99 - -node PlatoSetup as "Plato Connector Setup" { - database PlatoPsql as "PostgreSQL" #platoColor - database PlatoKeyVault as "HashiCorp Vault" #platoColor - component PlatoConnector as "Eclipse Dataspace Connector" { - artifact PlatoControlPlane as "Control Plane" #platoColor - artifact PlatoDataPlane as "Data Plane" #platoColor - } - component PlatoBackendService as "Backend Application" #platoColor -} - -PlatoControlPlane -- PlatoPsql -PlatoControlPlane -- PlatoKeyVault -PlatoDataPlane -- PlatoKeyVault -PlatoDataPlane -left- PlatoControlPlane -PlatoControlPlane -left- PlatoBackendService - -node SokratesSetup as "Sokrates Connector Setup" { - database SokratesPsql as "PostgreSQL" #sokratesColor - database SokratesKeyVault as "HashiCorp Vault" #sokratesColor - component SokratesConnector as "Eclipse Dataspace Connector" { - artifact SokratesControlPlane as "Control Plane" #sokratesColor - artifact SokratesDataPlane as "Data Plane" #sokratesColor - } - component SokratesBackendService as "Backend Application" #sokratesColor -} - -SokratesControlPlane -- SokratesPsql -SokratesControlPlane -- SokratesKeyVault -SokratesDataPlane -- SokratesKeyVault -SokratesDataPlane -left- SokratesControlPlane -SokratesControlPlane -left- SokratesBackendService - - -node IdentityProvider as "Identity Provider" { - component OmejdnDaps as "Omejdn DAPS" #dapsColor -} - -PlatoPsql -[hidden]down- OmejdnDaps -SokratesControlPlane -[hidden]up- OmejdnDaps - -@enduml diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/templates/_helpers.tpl b/edc-tests/src/main/resources/deployment/helm/all-in-one/templates/_helpers.tpl deleted file mode 100644 index 782767de0..000000000 --- a/edc-tests/src/main/resources/deployment/helm/all-in-one/templates/_helpers.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "aio.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "aio.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "aio.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "aio.labels" -}} -helm.sh/chart: {{ include "aio.chart" . }} -{{ include "aio.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "aio.selectorLabels" -}} -app.kubernetes.io/name: {{ include "aio.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "aio.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "aio.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/templates/secret.yaml b/edc-tests/src/main/resources/deployment/helm/all-in-one/templates/secret.yaml deleted file mode 100644 index d4f33792e..000000000 --- a/edc-tests/src/main/resources/deployment/helm/all-in-one/templates/secret.yaml +++ /dev/null @@ -1,91 +0,0 @@ ---- - -# When deploying an EDC, there are various configuration parameters that should not be part of the configuration file. -# To not serve a bad example, this demo will set some settings using secrets as well. In a productive environment this secrets would probably be deployed independently. - -{{- $plato_psql_password := .Values.platopostgresql.auth.password -}} -{{- $plato_api_auth_key := "password" -}} -{{- $plato_vault_token := .Values.platovault.server.dev.devRootToken -}} -{{- $sokrates_psql_password := .Values.sokratespostgresql.auth.password -}} -{{- $sokrates_api_auth_key := "password" -}} -{{- $sokrates_vault_token := .Values.sokratesvault.server.dev.devRootToken -}} - ---- - -apiVersion: v1 -kind: Secret -metadata: - name: aio-plato-control-secret - namespace: {{ .Release.Namespace | default "default" | quote }} - labels: - {{- include "aio.labels" . | nindent 4 }} -type: Opaque -stringData: - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/auth/auth-tokenbased - EDC_API_AUTH_KEY: {{ $plato_api_auth_key | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/asset-index-sql - EDC_DATASOURCE_ASSET_PASSWORD: {{ $plato_psql_password | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/contract-definition-store-sql - EDC_DATASOURCE_CONTRACTDEFINITION_PASSWORD: {{ $plato_psql_password | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/contract-negotiation-store-sql - EDC_DATASOURCE_CONTRACTNEGOTIATION_PASSWORD: {{ $plato_psql_password | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/policy-store-sql - EDC_DATASOURCE_POLICY_PASSWORD: {{ $plato_psql_password | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/transfer-process-store-sql - EDC_DATASOURCE_TRANSFERPROCESS_PASSWORD: {{ $plato_psql_password | toString | quote }} - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/hashicorp-vault - EDC_VAULT_HASHICORP_TOKEN: {{ $plato_vault_token | toString | quote }} - ---- - -apiVersion: v1 -kind: Secret -metadata: - name: aio-plato-data-secret - namespace: {{ .Release.Namespace | default "default" | quote }} - labels: - {{- include "aio.labels" . | nindent 4 }} -type: Opaque -stringData: - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/hashicorp-vault - EDC_VAULT_HASHICORP_TOKEN: {{ $plato_vault_token | toString | quote }} - ---- - -apiVersion: v1 -kind: Secret -metadata: - name: aio-sokrates-control-secret - namespace: {{ .Release.Namespace | default "default" | quote }} - labels: - {{- include "aio.labels" . | nindent 4 }} -type: Opaque -stringData: - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/common/auth/auth-tokenbased - EDC_API_AUTH_KEY: {{ $sokrates_api_auth_key | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/asset-index-sql - EDC_DATASOURCE_ASSET_PASSWORD: {{ $sokrates_psql_password | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/contract-definition-store-sql - EDC_DATASOURCE_CONTRACTDEFINITION_PASSWORD: {{ $sokrates_psql_password | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/contract-negotiation-store-sql - EDC_DATASOURCE_CONTRACTNEGOTIATION_PASSWORD: {{ $sokrates_psql_password | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/policy-store-sql - EDC_DATASOURCE_POLICY_PASSWORD: {{ $sokrates_psql_password | toString | quote }} - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/transfer-process-store-sql - EDC_DATASOURCE_TRANSFERPROCESS_PASSWORD: {{ $sokrates_psql_password | toString | quote }} - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/hashicorp-vault - EDC_VAULT_HASHICORP_TOKEN: {{ $sokrates_vault_token | toString | quote }} - ---- - -apiVersion: v1 -kind: Secret -metadata: - name: aio-sokrates-data-secret - namespace: {{ .Release.Namespace | default "default" | quote }} - labels: - {{- include "aio.labels" . | nindent 4 }} -type: Opaque -stringData: - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/hashicorp-vault - EDC_VAULT_HASHICORP_TOKEN: {{ $sokrates_vault_token | toString | quote }} diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/values.yaml b/edc-tests/src/main/resources/deployment/helm/all-in-one/values.yaml deleted file mode 100644 index 396ead03b..000000000 --- a/edc-tests/src/main/resources/deployment/helm/all-in-one/values.yaml +++ /dev/null @@ -1,565 +0,0 @@ ---- - -# Default values for all-in-one deployment. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -idsdaps: - enabled: true - fullnameOverride: "ids-daps" - connectors: - - id: &sokratesDapsClientId E7:07:2D:74:56:66:31:F0:7B:10:EA:B6:03:06:4C:23:7F:ED:A6:65:keyid:E7:07:2D:74:56:66:31:F0:7B:10:EA:B6:03:06:4C:23:7F:ED:A6:65 - name: sokrates - attributes: - referringConnector: http://sokrates-edc-controlplane/BPNSOKRATES - # Must be the same certificate that is stores in section 'sokrates-vault' - certificate: |- - -----BEGIN CERTIFICATE----- - MIIEAzCCAuugAwIBAgIUXFgjbN7jxGRUDkoUvEwcN3zcew8wDQYJKoZIhvcNAQEL - BQAwgZAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl - cmxpbjEMMAoGA1UECgwDQk1XMSAwHgYDVQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0 - bmVyMTEvMC0GA1UEAwwmc29rcmF0ZXMtZWRjLmRlbW8uY2F0ZW5hLXgubmV0L0JQ - TjEyMzQwHhcNMjIwNTEwMDc1NzMzWhcNMjMwNTEwMDc1NzMzWjCBkDELMAkGA1UE - BhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQK - DANCTVcxIDAeBgNVBAsMF2VkYy1wbGF5Z3JvdW5kLXBhcnRuZXIxMS8wLQYDVQQD - DCZzb2tyYXRlcy1lZGMuZGVtby5jYXRlbmEteC5uZXQvQlBOMTIzNDCCASIwDQYJ - KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK/41S8rumkk+IzBk9pBDETvjlPmlXfw - 78yRrLmbzaed3kGgygJ2GFFPLcR/Lv0WG8F8au4UEssbOxAU4RRjncCVt66ajaCa - llIqMlH8zaJ8rgxNpGeJU5YvmYRxlIo+Gwi0qnF0tqJh8Hry7OqSo0gK2YBBFJyV - grMsEz3EcsS3ENYJufNgUIeg4QsaL49M0gWxSexPdC4pon96Nvju90D8RlvAJB21 - PInqLniMaFlSnRYzCrUaja6HMmzKA+ZPZ1r9lllzsE00RASxRIxlKkwfzTtMb9O6 - ey2i2vM7hKGGlXjNsnYVX9WXEfvK4JrCadHzgX8qdez19RxFKtB+5gECAwEAAaNT - MFEwHQYDVR0OBBYEFOcHLXRWZjHwexDqtgMGTCN/7aZlMB8GA1UdIwQYMBaAFOcH - LXRWZjHwexDqtgMGTCN/7aZlMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL - BQADggEBAD2a5kuIdICNXfYLpSe7AIONwZVucaArYtpXBxHEy5lMJsTEJgjZzypd - iIMU7onEQGVbii6yVNpWfIpJYM4e8ytVdJuk5evclVKZs/lZ2IshLyWFVj+ITh2E - 28X4C/Hnmt4MPBCNowQf71nMp4LEziBgXp54qFV9C+qSTEVdrherRE0PU/zKyX10 - S/P5o42weTHnAO/pBN/8AmL3AymynKVgcPaW46IjjRAuc6kfZWCrYQ0M4+/7Ws5r - uM55Zae/L+C82OTNNaaK324ogsCkORPeQ23OCrRD8rZJmQ9bpoOGglPminfwEOhB - UHtyKgmvqCyOV3G/4G93W/xsLV0kxLA= - -----END CERTIFICATE----- - - id: &platoDapsClientId 99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:23:keyid:99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:23 - name: plato - attributes: - referringConnector: http://plato-edc-controlplane/BPNPLATO - # Must be the same certificate that is stores in section 'plato-vault' - certificate: |- - -----BEGIN CERTIFICATE----- - MIID7TCCAtWgAwIBAgIUJ0bwxUc7n3YK89mOyGXrLx2KO0YwDQYJKoZIhvcNAQEL - BQAwgYUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl - cmxpbjEMMAoGA1UECgwDQk1XMSAwHgYDVQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0 - bmVyMjEkMCIGA1UEAwwbcGxhdG8tZWRjLmRlbW8uY2F0ZW5hLXgubmV0MB4XDTIy - MDQyNTEwMjgwMloXDTIzMDQyNTEwMjgwMlowgYUxCzAJBgNVBAYTAkRFMQ8wDQYD - VQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEMMAoGA1UECgwDQk1XMSAwHgYD - VQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0bmVyMjEkMCIGA1UEAwwbcGxhdG8tZWRj - LmRlbW8uY2F0ZW5hLXgubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC - AQEAm1/UvHXuRU1peEGHULZBP8j8gorXAQvUz8Znb1iVNtldI29GCSXkTHxph66x - TcegdF8aeaoU1mPf3LzMQUU1koZHUq6sRC+50uFcZJ2AjF5IXKQlDPNWR5tPXP56 - RZyqXxjPFHeuTA+YsYyrzEVhzEieOiNaxJDM3uV5pv+FTRHz+xMOgNBonR1QyMh6 - tcwB+EQagoeFl0DjEXAel9WG4hOG/rDiXArTMaVjnTG/ycmF0HeSnbRC+3/+fh/C - hzQJyEbviX67ymyYRJTyynt/Mtrqg5/ssdISexjw3ZmiFNemZIOhIdepoSwnJHFM - 4Jj8B5lq0a1jY5Rc9lDj710RXQIDAQABo1MwUTAdBgNVHQ4EFgQUmYOnF4b/mJPO - oN2h8Tb69g91CiMwHwYDVR0jBBgwFoAUmYOnF4b/mJPOoN2h8Tb69g91CiMwDwYD - VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAKxv/MTIEKNkzReOqrzpt - LM00X6JsDdfxa3rZ0Uq17PjO0R63IPsqzexhfZUML0e/Dwpe97xpvftCOEuICMBA - wOHhQc77MgwyF4dqgRgfJysxw37ACZxU6GI/K2JpKXQLgEhP14oHUIWOzCAbgDhR - jwOx3ZP176Vjxx90pW3hOphRVnq/BRqqEDtFwRzKtGnGvP8ecmC2iY4dXEA3QEp1 - gzg03eglvZSoedEPY5o5y/4n6TplaDmaeoo0QrvAiWik1gY85Lg21aBWVsP45wVS - tFn3m1FCCV8XYIj/EEUAh8VEhphLVEViE6m9Mm4deFDavXcGBb63BCiOQtnjd3eY - zQ== - -----END CERTIFICATE----- - -######### -# PLATO # -######### -platobackendapplication: - enabled: true - fullnameOverride: "plato-backend-application" - service: - type: NodePort - frontend: - port: 80 -platopostgresql: - enabled: true - fullnameOverride: "plato-postgresql" - auth: - password: &psqlPassword "psql_password" - username: &psqlUsername "postgresql_sandbox_user" - database: &psqlDatabase "edc" - persistence: - enabled: false -platovault: - enabled: true - fullnameOverride: "plato-vault" - injector: - enabled: false - server: - dev: - enabled: true - devRootToken: "root" - - # Must be the same certificate that is configured in section 'ids-daps' - postStart: - - "sh" - - "-c" - - | - { - - sleep 5 - - /bin/vault kv put secret/data-encryption-aes-keys content=H7j47H6vVQQOv/hbdAYz+w== - - cat << EOF | /bin/vault kv put secret/my-plato-daps-key content=- - -----BEGIN PRIVATE KEY----- - MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCbX9S8de5FTWl4 - QYdQtkE/yPyCitcBC9TPxmdvWJU22V0jb0YJJeRMfGmHrrFNx6B0Xxp5qhTWY9/c - vMxBRTWShkdSrqxEL7nS4VxknYCMXkhcpCUM81ZHm09c/npFnKpfGM8Ud65MD5ix - jKvMRWHMSJ46I1rEkMze5Xmm/4VNEfP7Ew6A0GidHVDIyHq1zAH4RBqCh4WXQOMR - cB6X1YbiE4b+sOJcCtMxpWOdMb/JyYXQd5KdtEL7f/5+H8KHNAnIRu+JfrvKbJhE - lPLKe38y2uqDn+yx0hJ7GPDdmaIU16Zkg6Eh16mhLCckcUzgmPwHmWrRrWNjlFz2 - UOPvXRFdAgMBAAECggEAN2yd5IRk9I/CucUWUfJRoEE/4glI3PSte1iY+R0uTRyI - nuVIpGbB447VzjLAyLAXSqvKM/A58qg56PHoIrhffd8sfhAVH1WvAcymOrX8bxYK - 1hEvrkj3VB/Q1alpUH+sPrQI2pI+uJ8vptY5SmrNkiOtXavS6x+EFVbiaHHpyS26 - ASaCoRpdBoNTm0SAiDBTK6MqTs4vRpqKseGdC76F+jKimYrTJY19ZctSIAMjrnqd - qzRL+jfob5vMqKC22AjInkZ8BZWll1ZoTnv37bq2NAb9lvdY73REm42Wpm5S7PET - Eixe69gvi/IwaSe27S36+kcrQoYHnxbb31+Xt+0pQQKBgQDJfA2ZnYmcA3yvVQhi - e76I3rq6AEfcG4EDhf+JRO2QHKMMXLwfFAdSR8QflxNUWy1y6q/783EpgLJ1Kv8h - uNkTH6JyV7kFhwfvxWreAWx2jRQRACqnuaLnJ/28vd8Il0kc3/BQsWzbg6YTERrq - 0Au2RW/c9blrKS0MyurtOtZsiQKBgQDFaezSCWUspeNci5lrdvMiHBLOUgR2guQm - Gtf9RdBmzvtBqpdkP8AEMhRW7oSGcKpDldd0Klyml7s/CDYTL7sflHtKRiTQmWuJ - +p3uvyylAxr/Swfw56hj5Y4/Oj2CLIuUlglewo40JnvvM5icT7RGvbyaIIhYzIsR - HTv3t8eRNQKBgA4l8eaJk3IrJIRDWlVgDx8ZVM9e2azxGXwf2rPO7UejWyexE1yz - UVhLxc/aEfdod6aMKFNu4tFhQibMICJEEqovHH8e/dUPiFUj7b8tJmqkuXYAJv6k - IHZO7phkVNcLmIy4hO2Fp/k6I11PZC588XWZJqPDdYO63nj5fsmtygTRAoGBAJ72 - YH/wmMuO+Ll4n51tNvJscKg6WuWjGFumme2T3fArEx8ZYraSruex+7bUcVpgNnod - mlQsGFb9LwXecsyYTrFrOqvgN5zRLUr5x1qMDkMBcSfJHyfZIjruidBX8Vd0zyBi - gEERoLhVlM5UWbrkY2HjPo9NSv1WF1U8mSErl0NRAoGAYC3RxEfGxD9+Qi08nQgg - s/48hLdD2k2q4t3FrDsIGPAIEs52CGp9JWil9RyIQxBXWejETwDz+PgmD6U86Mhh - Qf5css6pcP/w1XF8vsyXfPnecgPSyOE4CgLtnQLxNriMiy5pfALELLyxoBQ+nquz - fMNLPC4K85ps/Uu9uzSatl0= - -----END PRIVATE KEY----- - EOF - - cat << EOF | /bin/vault kv put secret/my-plato-daps-crt content=- - -----BEGIN CERTIFICATE----- - MIID7TCCAtWgAwIBAgIUJ0bwxUc7n3YK89mOyGXrLx2KO0YwDQYJKoZIhvcNAQEL - BQAwgYUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl - cmxpbjEMMAoGA1UECgwDQk1XMSAwHgYDVQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0 - bmVyMjEkMCIGA1UEAwwbcGxhdG8tZWRjLmRlbW8uY2F0ZW5hLXgubmV0MB4XDTIy - MDQyNTEwMjgwMloXDTIzMDQyNTEwMjgwMlowgYUxCzAJBgNVBAYTAkRFMQ8wDQYD - VQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEMMAoGA1UECgwDQk1XMSAwHgYD - VQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0bmVyMjEkMCIGA1UEAwwbcGxhdG8tZWRj - LmRlbW8uY2F0ZW5hLXgubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC - AQEAm1/UvHXuRU1peEGHULZBP8j8gorXAQvUz8Znb1iVNtldI29GCSXkTHxph66x - TcegdF8aeaoU1mPf3LzMQUU1koZHUq6sRC+50uFcZJ2AjF5IXKQlDPNWR5tPXP56 - RZyqXxjPFHeuTA+YsYyrzEVhzEieOiNaxJDM3uV5pv+FTRHz+xMOgNBonR1QyMh6 - tcwB+EQagoeFl0DjEXAel9WG4hOG/rDiXArTMaVjnTG/ycmF0HeSnbRC+3/+fh/C - hzQJyEbviX67ymyYRJTyynt/Mtrqg5/ssdISexjw3ZmiFNemZIOhIdepoSwnJHFM - 4Jj8B5lq0a1jY5Rc9lDj710RXQIDAQABo1MwUTAdBgNVHQ4EFgQUmYOnF4b/mJPO - oN2h8Tb69g91CiMwHwYDVR0jBBgwFoAUmYOnF4b/mJPOoN2h8Tb69g91CiMwDwYD - VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAKxv/MTIEKNkzReOqrzpt - LM00X6JsDdfxa3rZ0Uq17PjO0R63IPsqzexhfZUML0e/Dwpe97xpvftCOEuICMBA - wOHhQc77MgwyF4dqgRgfJysxw37ACZxU6GI/K2JpKXQLgEhP14oHUIWOzCAbgDhR - jwOx3ZP176Vjxx90pW3hOphRVnq/BRqqEDtFwRzKtGnGvP8ecmC2iY4dXEA3QEp1 - gzg03eglvZSoedEPY5o5y/4n6TplaDmaeoo0QrvAiWik1gY85Lg21aBWVsP45wVS - tFn3m1FCCV8XYIj/EEUAh8VEhphLVEViE6m9Mm4deFDavXcGBb63BCiOQtnjd3eY - zQ== - -----END CERTIFICATE----- - EOF - } - - ui: - enabled: true - externalPort: 8200 - targetPort: 8200 -platoedcdataplane: - enabled: true - fullnameOverride: "plato-edc-dataplane" - image: - repository: &edcDataPlaneImage ghcr.io/eclipse-tractusx/tractusx-edc/edc-dataplane-hashicorp-vault - tag: &edcDataPlaneImageTag develop - pullPolicy: &pullPolicy Always - envSecretName: "aio-plato-data-secret" - edc: - endpoints: - public: - port: 8185 - path: /api/public - opentelemetry: - properties: |- - otel.javaagent.enabled=false - otel.javaagent.debug=false - env: - JAVA_TOOL_OPTIONS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044" - - ############# - ## GENERAL ## - ############# - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/data-plane/data-plane-api - EDC_DATAPLANE_TOKEN_VALIDATION_ENDPOINT: http://plato-edc-controlplane:8182/validation/token - - ############### - ## KEY VAULT ## - ############### - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/hashicorp-vault - EDC_VAULT_HASHICORP_URL: http://plato-vault:8200 -platoedccontrolplane: - enabled: true - fullnameOverride: "plato-edc-controlplane" - service: - type: NodePort - logging: - # -- EDC logging.properties configuring the [java.util.logging subsystem](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.8) - properties: |- - .level=DEBUG - org.eclipse.dataspaceconnector.level=ALL - handlers=java.util.logging.ConsoleHandler - java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter - java.util.logging.ConsoleHandler.level=ALL - java.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n - image: - repository: &edcControlPlaneImage ghcr.io/eclipse-tractusx/tractusx-edc/edc-controlplane-postgresql-hashicorp-vault - tag: &edcControlPlaneImageTag develop - pullPolicy: *pullPolicy - opentelemetry: - properties: |- - otel.javaagent.enabled=false - otel.javaagent.debug=false - envSecretName: "aio-plato-control-secret" - env: - JAVA_TOOL_OPTIONS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044" - - ######################## - ## DAPS CONFIGURATION ## - ######################## - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/cx-oauth2 - EDC_OAUTH_CLIENT_ID: *platoDapsClientId - EDC_OAUTH_PROVIDER_JWKS_URL: &edcControlPlaneOauthJwksUrl "http://ids-daps:4567/jwks.json" - EDC_OAUTH_TOKEN_URL: &edcControlPlaneOauthTokenUrl "http://ids-daps:4567/token" - EDC_OAUTH_PRIVATE_KEY_ALIAS: my-plato-daps-key - EDC_OAUTH_PUBLIC_KEY_ALIAS: my-plato-daps-crt - - ############# - ## GENERAL ## - ############# - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/data-protocols/ids/ids-api-multipart-dispatcher-v1 - IDS_WEBHOOK_ADDRESS: http://plato-edc-controlplane:8282 - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/data-protocols/ids/ids-core - EDC_IDS_ENDPOINT: http://plato-edc-controlplane:8282/api/v1/ids - EDC_IDS_ENDPOINT_AUDIENCE: http://plato-edc-controlplane:8282/api/v1/ids/data - EDC_IDS_DESCRIPTION: "Plato Control Plane" - - ################ - ## POSTGRESQL ## - ################ - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/asset-index-sql - EDC_DATASOURCE_ASSET_NAME: asset - EDC_DATASOURCE_ASSET_USER: *psqlUsername - EDC_DATASOURCE_ASSET_URL: &platoPsqlConStr "jdbc:postgresql://plato-postgresql:5432/edc" - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/contract-definition-store-sql - EDC_DATASOURCE_CONTRACTDEFINITION_NAME: contractdefinition - EDC_DATASOURCE_CONTRACTDEFINITION_USER: *psqlUsername - EDC_DATASOURCE_CONTRACTDEFINITION_URL: *platoPsqlConStr - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/contract-negotiation-store-sql - EDC_DATASOURCE_CONTRACTNEGOTIATION_NAME: contractnegotiation - EDC_DATASOURCE_CONTRACTNEGOTIATION_USER: *psqlUsername - EDC_DATASOURCE_CONTRACTNEGOTIATION_URL: *platoPsqlConStr - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/policy-store-sql - EDC_DATASOURCE_POLICY_NAME: policy - EDC_DATASOURCE_POLICY_USER: *psqlUsername - EDC_DATASOURCE_POLICY_URL: *platoPsqlConStr - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/transfer-process-store-sql - EDC_DATASOURCE_TRANSFERPROCESS_NAME: transferprocess - EDC_DATASOURCE_TRANSFERPROCESS_USER: *psqlUsername - EDC_DATASOURCE_TRANSFERPROCESS_URL: *platoPsqlConStr - - ################ - ## DATA PLANE ## - ################ - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/dataplane-selector-configuration - EDC_DATAPLANE_SELECTOR_PLATOPLANE_URL: http://plato-edc-dataplane:9999/api/dataplane/control - EDC_DATAPLANE_SELECTOR_PLATOPLANE_SOURCETYPES : HttpData - EDC_DATAPLANE_SELECTOR_PLATOPLANE_DESTINATIONTYPES: HttpProxy - EDC_DATAPLANE_SELECTOR_PLATOPLANE_PROPERTIES: >- - { - "publicApiUrl": "http://plato-edc-dataplane:8185/api/public/" - } - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/data-plane-transfer - EDC_TRANSFER_PROXY_ENDPOINT: http://plato-edc-dataplane:8185/api/public/ - EDC_TRANSFER_PROXY_TOKEN_SIGNER_PRIVATEKEY_ALIAS: my-plato-daps-key # for simplicity this example re-uses the DAPS keys. - EDC_TRANSFER_PROXY_TOKEN_VERIFIER_PUBLICKEY_ALIAS: my-plato-daps-crt # for simplicity this example re-uses the DAPS keys. - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/http-receiver - EDC_RECEIVER_HTTP_ENDPOINT: http://plato-backend-application - - ############### - ## KEY VAULT ## - ############### - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/hashicorp-vault - EDC_VAULT_HASHICORP_URL: http://plato-vault:8200 - - ##################### - ## DATA ENCRYPTION ## - ##################### - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/data-encryption - EDC_DATA_ENCRYPTION_KEYS_ALIAS: data-encryption-aes-keys - EDC_DATA_ENCRYPTION_ALGORITHM: AES - -############ -# SOKRATES # -############ -sokratesbackendapplication: - enabled: true - fullnameOverride: "sokrates-backend-application" - service: - type: NodePort - frontend: - port: 80 -sokratespostgresql: - enabled: true - fullnameOverride: "sokrates-postgresql" - auth: - password: *psqlPassword - username: *psqlUsername - database: *psqlDatabase -sokratesvault: - enabled: true - fullnameOverride: "sokrates-vault" - injector: - enabled: false - server: - dev: - enabled: true - devRootToken: &sokratesVaultToken "root" - - # Must be the same certificate that is configured in section 'ids-daps' - postStart: - - "sh" - - "-c" - - | - { - - sleep 5 - - /bin/vault kv put secret/data-encryption-aes-keys content=OcvxzWCK8ETSjt1jmZw3RA== - - cat << EOF | /bin/vault kv put secret/my-sokrates-daps-key content=- - -----BEGIN PRIVATE KEY----- - MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCv+NUvK7ppJPiM - wZPaQQxE745T5pV38O/Mkay5m82nnd5BoMoCdhhRTy3Efy79FhvBfGruFBLLGzsQ - FOEUY53Albeumo2gmpZSKjJR/M2ifK4MTaRniVOWL5mEcZSKPhsItKpxdLaiYfB6 - 8uzqkqNICtmAQRSclYKzLBM9xHLEtxDWCbnzYFCHoOELGi+PTNIFsUnsT3QuKaJ/ - ejb47vdA/EZbwCQdtTyJ6i54jGhZUp0WMwq1Go2uhzJsygPmT2da/ZZZc7BNNEQE - sUSMZSpMH807TG/TunstotrzO4ShhpV4zbJ2FV/VlxH7yuCawmnR84F/KnXs9fUc - RSrQfuYBAgMBAAECggEAO+KjsjTgcG3bhBNQnMLsSP15Y0Yicbn18ZlVvaivGS7Z - d14fwSytY+ZdPfTGaey/L16HCVSdfK9cr0Fbw9OO2P5ajzobnp9dLsMbctlkpbpm - hNtbarzKTF8QkIkSsuUl0BWjt46vpJ1N+Jl5VO7oUFkY4dPEDvG2lAEY3zlekWDm - cQeOC/YgpoW4xfRwPPS6QE0w3Q+H5NfNjfz+mSHeItTlVfTKDRliWQLPWeRZFuXh - FlRFUQnTmEE/9wpIe3Hn7WXJ3fQqcYDzxU7/zwwY9I7bB15SgVHlR0ENDPAD5X8F - MVZ3EcLlqGBy+WvTWALp6pc8YfhW3fiTWyuamXtNrQKBgQDonsIzBKEOOKdKGW0e - uyw79ErmnmzkY5nuMrMxrmTA4WKCfJ/YRRA+4sxiltWsIJ3UkHe3OBCSSCdj79hb - ugb/+UzE70hOdgrct2NUQqbrj3gvsVvU8ZRQgTRMqKpmC0zY7KOMx6NU85z3IvS1 - z5fjszcUv4kLQlldYGSAuqPy+wKBgQDBqIkc8p/wcw7ygo1q/GerNeszfoxiIFp8 - h4RWLVhkwrcXFz30wBlUWuv5/kxU8tmJcmXxe72EmUstd6wvNOAnYwCiile6zQiJ - vsr1axavZnGOtNGUp6DUAsd2iviBl7IZ7kAcqCrQo4ivGhfHmahH3hmg8wuAMjYB - 8f+FSPgaMwKBgQC7W4tMrjDOFIFhJEOIWfcRvvxI7VcFSNelS76aiDzsQVwnfxr7 - hPzFucQmsBgfUBHvMADMWGK4f1cCnh5kGtwidXgIsjVJxLeQ+EAPkLOCzQZfW3l8 - dKshgD9QcxTzpaxal5ZPAEikVqaZQtVYToCmzCTUGETYBbOWitnH+Qut2wKBgQC6 - Y6DcSLUhc0xOotLDxv1sbu/aVxF8nFEbDD+Vxf0Otc4MnmUWPRHj+8KlkVkcZcR0 - IrP1kThd+EDAGS+TG9wmbIY+6tH3S8HM+eJUBWcHGJ1xUZ1p61DC3Y3nDWiTKlLT - 3Fi+fCkBOHSku4Npq/2odh7Kp0JJd4o9oxJg0VNhuwKBgQDSFn7dqFE0Xmwc40Vr - 0wJH8cPWXKGt7KJENpj894buk2DniLD4w2x874dzTjrOFi6fKxEzbBNA9Rq9UPo8 - u9gKvl/IyWmV0c4zFCNMjRwVdnkMEte/lXcJZ67T4FXZByqAZlhrr/v0FD442Z9B - AjWFbUiBCFOo+gpAFcQGrkOQHA== - -----END PRIVATE KEY----- - EOF - - cat << EOF | /bin/vault kv put secret/my-sokrates-daps-crt content=- - -----BEGIN CERTIFICATE----- - MIIEAzCCAuugAwIBAgIUXFgjbN7jxGRUDkoUvEwcN3zcew8wDQYJKoZIhvcNAQEL - BQAwgZAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl - cmxpbjEMMAoGA1UECgwDQk1XMSAwHgYDVQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0 - bmVyMTEvMC0GA1UEAwwmc29rcmF0ZXMtZWRjLmRlbW8uY2F0ZW5hLXgubmV0L0JQ - TjEyMzQwHhcNMjIwNTEwMDc1NzMzWhcNMjMwNTEwMDc1NzMzWjCBkDELMAkGA1UE - BhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQK - DANCTVcxIDAeBgNVBAsMF2VkYy1wbGF5Z3JvdW5kLXBhcnRuZXIxMS8wLQYDVQQD - DCZzb2tyYXRlcy1lZGMuZGVtby5jYXRlbmEteC5uZXQvQlBOMTIzNDCCASIwDQYJ - KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK/41S8rumkk+IzBk9pBDETvjlPmlXfw - 78yRrLmbzaed3kGgygJ2GFFPLcR/Lv0WG8F8au4UEssbOxAU4RRjncCVt66ajaCa - llIqMlH8zaJ8rgxNpGeJU5YvmYRxlIo+Gwi0qnF0tqJh8Hry7OqSo0gK2YBBFJyV - grMsEz3EcsS3ENYJufNgUIeg4QsaL49M0gWxSexPdC4pon96Nvju90D8RlvAJB21 - PInqLniMaFlSnRYzCrUaja6HMmzKA+ZPZ1r9lllzsE00RASxRIxlKkwfzTtMb9O6 - ey2i2vM7hKGGlXjNsnYVX9WXEfvK4JrCadHzgX8qdez19RxFKtB+5gECAwEAAaNT - MFEwHQYDVR0OBBYEFOcHLXRWZjHwexDqtgMGTCN/7aZlMB8GA1UdIwQYMBaAFOcH - LXRWZjHwexDqtgMGTCN/7aZlMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL - BQADggEBAD2a5kuIdICNXfYLpSe7AIONwZVucaArYtpXBxHEy5lMJsTEJgjZzypd - iIMU7onEQGVbii6yVNpWfIpJYM4e8ytVdJuk5evclVKZs/lZ2IshLyWFVj+ITh2E - 28X4C/Hnmt4MPBCNowQf71nMp4LEziBgXp54qFV9C+qSTEVdrherRE0PU/zKyX10 - S/P5o42weTHnAO/pBN/8AmL3AymynKVgcPaW46IjjRAuc6kfZWCrYQ0M4+/7Ws5r - uM55Zae/L+C82OTNNaaK324ogsCkORPeQ23OCrRD8rZJmQ9bpoOGglPminfwEOhB - UHtyKgmvqCyOV3G/4G93W/xsLV0kxLA= - -----END CERTIFICATE----- - EOF - } - - ui: - enabled: true - externalPort: 8200 - targetPort: 8200 -sokratesedcdataplane: - enabled: true - fullnameOverride: "sokrates-edc-dataplane" - image: - repository: *edcDataPlaneImage - tag: *edcDataPlaneImageTag - pullPolicy: *pullPolicy - envSecretName: "aio-plato-data-secret" - edc: - endpoints: - public: - port: 8185 - path: /api/public - opentelemetry: - properties: |- - otel.javaagent.enabled=false - otel.javaagent.debug=false - env: - JAVA_TOOL_OPTIONS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044" - - ############# - ## GENERAL ## - ############# - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/data-plane/data-plane-api - EDC_DATAPLANE_TOKEN_VALIDATION_ENDPOINT: http://sokrates-edc-controlplane:8182/validation/token - - ############### - ## KEY VAULT ## - ############### - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/hashicorp-vault - EDC_VAULT_HASHICORP_URL: http://sokrates-vault:8200 - EDC_VAULT_HASHICORP_TOKEN: *sokratesVaultToken -sokratesedccontrolplane: - enabled: true - fullnameOverride: "sokrates-edc-controlplane" - service: - type: NodePort - logging: - # -- EDC logging.properties configuring the [java.util.logging subsystem](https://docs.oracle.com/javase/7/docs/technotes/guides/logging/overview.html#a1.8) - properties: |- - .level=DEBUG - org.eclipse.dataspaceconnector.level=ALL - handlers=java.util.logging.ConsoleHandler - java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter - java.util.logging.ConsoleHandler.level=ALL - java.util.logging.SimpleFormatter.format=[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS] [%4$-7s] %5$s%6$s%n - envSecretName: "aio-sokrates-control-secret" - image: - repository: *edcControlPlaneImage - tag: *edcControlPlaneImageTag - pullPolicy: *pullPolicy - opentelemetry: - properties: |- - otel.javaagent.enabled=false - otel.javaagent.debug=false - env: - JAVA_TOOL_OPTIONS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044" - - ######################## - ## DAPS CONFIGURATION ## - ######################## - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/iam/oauth2/oauth2-core - EDC_OAUTH_CLIENT_ID: *sokratesDapsClientId - EDC_OAUTH_PROVIDER_JWKS_URL: *edcControlPlaneOauthJwksUrl - EDC_OAUTH_TOKEN_URL: *edcControlPlaneOauthTokenUrl - EDC_OAUTH_PRIVATE_KEY_ALIAS: my-sokrates-daps-key - EDC_OAUTH_PUBLIC_KEY_ALIAS: my-sokrates-daps-crt - - ############# - ## GENERAL ## - ############# - IDS_WEBHOOK_ADDRESS: http://sokrates-edc-controlplane:8282 - EDC_IDS_ENDPOINT: http://sokrates-edc-controlplane:8282/api/v1/ids - EDC_IDS_ENDPOINT_AUDIENCE: http://sokrates-edc-controlplane:8282/api/v1/ids/data - EDC_IDS_DESCRIPTION: "Sokrates Control Plane" - - ################ - ## POSTGRESQL ## - ################ - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/asset-index-sql - EDC_DATASOURCE_ASSET_NAME: asset - EDC_DATASOURCE_ASSET_USER: *psqlUsername - EDC_DATASOURCE_ASSET_URL: &SokratesPsqlConStr "jdbc:postgresql://sokrates-postgresql:5432/edc" - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/contract-definition-store-sql - EDC_DATASOURCE_CONTRACTDEFINITION_NAME: contractdefinition - EDC_DATASOURCE_CONTRACTDEFINITION_USER: *psqlUsername - EDC_DATASOURCE_CONTRACTDEFINITION_URL: *SokratesPsqlConStr - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/contract-negotiation-store-sql - EDC_DATASOURCE_CONTRACTNEGOTIATION_NAME: contractnegotiation - EDC_DATASOURCE_CONTRACTNEGOTIATION_USER: *psqlUsername - EDC_DATASOURCE_CONTRACTNEGOTIATION_URL: *SokratesPsqlConStr - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/policy-store-sql - EDC_DATASOURCE_POLICY_NAME: policy - EDC_DATASOURCE_POLICY_USER: *psqlUsername - EDC_DATASOURCE_POLICY_URL: *SokratesPsqlConStr - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/store/sql/transfer-process-store-sql - EDC_DATASOURCE_TRANSFERPROCESS_NAME: transferprocess - EDC_DATASOURCE_TRANSFERPROCESS_USER: *psqlUsername - EDC_DATASOURCE_TRANSFERPROCESS_URL: *SokratesPsqlConStr - - ################ - ## DATA PLANE ## - ################ - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/dataplane-selector-configuration - EDC_DATAPLANE_SELECTOR_SOKRATESPLANE_URL: http://sokrates-edc-dataplane:9999/api/dataplane/control - EDC_DATAPLANE_SELECTOR_SOKRATESPLANE_SOURCETYPES : HttpData - EDC_DATAPLANE_SELECTOR_SOKRATESPLANE_DESTINATIONTYPES: HttpProxy - EDC_DATAPLANE_SELECTOR_SOKRATESPLANE_PROPERTIES: >- - { - "publicApiUrl": "http://sokrates-edc-dataplane:8185/api/public/" - } - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/data-plane-transfer - EDC_TRANSFER_PROXY_ENDPOINT: http://sokrates-edc-dataplane:8185/api/public/ - EDC_TRANSFER_PROXY_TOKEN_SIGNER_PRIVATEKEY_ALIAS: my-sokrates-daps-key # for simplicity this example re-uses the DAPS keys. - EDC_TRANSFER_PROXY_TOKEN_VERIFIER_PUBLICKEY_ALIAS: my-sokrates-daps-crt # for simplicity this example re-uses the DAPS keys. - - # see extension https://github.com/eclipse-dataspaceconnector/DataSpaceConnector/tree/main/extensions/control-plane/http-receiver - EDC_RECEIVER_HTTP_ENDPOINT: http://sokrates-backend-application - - ############### - ## KEY VAULT ## - ############### - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/hashicorp-vault - EDC_VAULT_HASHICORP_URL: http://sokrates-vault:8200 - - ##################### - ## DATA ENCRYPTION ## - ##################### - - # see extension https://github.com/eclipse-tractusx/tractusx-edc/tree/develop/edc-extensions/data-encryption - EDC_DATA_ENCRYPTION_KEYS_ALIAS: data-encryption-aes-keys - EDC_DATA_ENCRYPTION_ALGORITHM: AES diff --git a/edc-tests/src/main/resources/deployment/helm/omejdn/templates/configmap.yaml b/edc-tests/src/main/resources/deployment/helm/omejdn/templates/configmap.yaml index 597850bd9..3d3e17c1f 100644 --- a/edc-tests/src/main/resources/deployment/helm/omejdn/templates/configmap.yaml +++ b/edc-tests/src/main/resources/deployment/helm/omejdn/templates/configmap.yaml @@ -40,6 +40,13 @@ data: clients.yml: |- --- + - client_id: data-plane-oauth2 + client_secret: supersecret + name: provision oauth2 + grant_types: + - client_credentials + token_endpoint_auth_method: client_secret_post + scope: openid {{- range $i, $val := .Values.connectors }} - client_id: {{ quote $val.id }} name: {{ quote $val.name }} @@ -60,6 +67,7 @@ data: redirect_uri: http://localhost:4200 {{ end -}} + {{- range $i, $val := .Values.connectors }} {{ $val.name }}: {{ quote $val.certificate | toString }} {{ end -}} diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/.gitignore b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/.gitignore similarity index 100% rename from edc-tests/src/main/resources/deployment/helm/all-in-one/.gitignore rename to edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/.gitignore diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/.helmignore b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/.helmignore similarity index 100% rename from edc-tests/src/main/resources/deployment/helm/all-in-one/.helmignore rename to edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/.helmignore diff --git a/edc-tests/src/main/resources/deployment/helm/all-in-one/Chart.yaml b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/Chart.yaml similarity index 51% rename from edc-tests/src/main/resources/deployment/helm/all-in-one/Chart.yaml rename to edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/Chart.yaml index 04b1147b5..d3248326b 100644 --- a/edc-tests/src/main/resources/deployment/helm/all-in-one/Chart.yaml +++ b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/Chart.yaml @@ -25,63 +25,42 @@ version: 0.1.0 appVersion: "1.16.0" dependencies: - # IDS DAPS + # IDS Dynamic Attribute Provisioning Service (IAM) - name: ids-daps version: 0.0.1 repository: "file://../omejdn" alias: idsdaps - condition: idsdaps.enabled + condition: install.daps - # PLATO CONNECTOR - - name: edc-controlplane - version: ">=0.0.1" - repository: "file://../../../../../../../charts/edc-controlplane" - alias: platoedccontrolplane - condition: platoedccontrolplane.enabled - - name: edc-dataplane - version: ">=0.0.1" - repository: "file://../../../../../../../charts/edc-dataplane" - alias: platoedcdataplane - condition: platoedcdataplane.enabled - - name: backend-service - version: "0.0.6" - repository: https://denisneuling.github.io/cx-backend-service - alias: platobackendapplication - condition: platobackendapplication.enabled + # HashiCorp Vault - name: vault + alias: vault version: 0.20.0 repository: https://helm.releases.hashicorp.com - alias: platovault - condition: platovault.enabled + condition: install.vault + + # PostgreSQL - name: postgresql + alias: plato-postgresql version: 12.1.6 repository: https://charts.bitnami.com/bitnami - alias: platopostgresql - condition: platopostgresql.enabled + condition: install.postgresql - # SOKRATES CONNECTOR - - name: edc-controlplane - version: ">=0.0.1" - repository: "file://../../../../../../../charts/edc-controlplane" - alias: sokratesedccontrolplane - condition: sokratesedccontrolplane.enabled - - name: edc-dataplane - version: ">=0.0.1" - repository: "file://../../../../../../../charts/edc-dataplane" - alias: sokratesedcdataplane - condition: sokratesedcdataplane.enabled - - name: backend-service - version: "0.0.6" - repository: https://denisneuling.github.io/cx-backend-service - alias: sokratesbackendapplication - condition: sokratesbackendapplication.enabled - - name: vault - version: 0.20.0 - repository: https://helm.releases.hashicorp.com - alias: sokratesvault - condition: sokratesvault.enabled - name: postgresql + alias: sokrates-postgresql version: 12.1.6 repository: https://charts.bitnami.com/bitnami - alias: sokratespostgresql - condition: sokratespostgresql.enabled + condition: install.postgresql + + - name: backend-service + version: 0.0.6 + repository: https://denisneuling.github.io/cx-backend-service + alias: backend + condition: install.backendservice + + # MinIo + - name: minio + alias: minio + repository: https://charts.min.io + version: 4.1.0 + condition: install.minio diff --git a/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/README.md b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/README.md new file mode 100644 index 000000000..3aae7191a --- /dev/null +++ b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/README.md @@ -0,0 +1,95 @@ +# Supporting Infrastructure Deployment + +The Supporting Infrastructure Deployment creates a complete, independent and already configured EDC test environment. +During the automated business tests, these infrastructure components are deployed together with two connectors (Plato & Sokrates). + +This deployment could also be used as + +- reference setup for teams, that want to create their own connector +- standalone infrastructure to try things out + +This deployment should **never** be used + +- in **any** production or near production environments +- in **any** long living internet facing connector setups + +## Components + +Overview of the installed components. + +![Deployed Components](diagrams/deployed_components.png) + +### Omejdn DAPS + +The Dynamic Attribute Provisioning Service (DAPS) is a component of the IDS Ecosystem. +The Fraunhofer Institute has created a DAPS reference implementation, the Omejdn +DAPS ([link](https://github.com/Fraunhofer-AISEC/omejdn-server)). This deplyoment configures and deployes a instance of +this reference implementation. + +Definition of DAPS from the IDS Reference architecture v3.0 +> The Identity Provider acts as an agent for the International +> Data Spaces Association. It is responsible for issuing technical identities to parties that have been approved to become +> Participants in the International Data Spaces. The Identity +> Provider is instructed to issue identities based on approved +> roles (e.g., App Store or App Provider). Only if equipped with +> such an identity, an entity is allowed to participate in the International Data Spaces + +Also, please note, that the Omejdn DAPS is meant as research sandbox and should not be used in anq +productive environment. + +> **IMPORTANT:** Omejdn is meant to be a research sandbox in which we can (re)implement standard protocols and +> potentially extend and modify functionality under the hood to support research projects. Use at your own +> risk! ([source](https://github.com/Fraunhofer-AISEC/omejdn-server)) + +### HashiCorp Vault + +The Control- and Data Plane persist confidential in the vault and persist and communicate using only the secret +names. Hence, it is not possible to run a connector without an instance of a vault. + +### Backend Application + +After a Data Transfer is successfully prepared the control plane will contact the a configurable endpoint with the +information it needs to initiate the data transfer. This transfer flow, where something like a Backend Application is +required, is unique to the HTTP Proxy data transfer flow. + +The Backend Application has an API endpoint, that is configured in the control plane. After it gets called with the data +transfer information, it will do the actual data transfer and store the data on disk. + +### PostgreSQL + +This database is used to persist the state of the Control Plane. + +## Setup + +Follow these steps to get a fully functional EDC demo environment out of the box. + +### Requirements + +Install on your machine: + +- Minikube + - Documentation https://minikube.sigs.k8s.io/docs/start/ +- Helm + - Documentation https://helm.sh/docs/intro/install/ + +## Start Demo Environment + +**Update Helm Dependencies** + +```bash +helm dependency update +``` + +**Install Demo Chart** + +```bash +helm install tx-infrastructure --namespace tx --create-namespace . +``` + +## Stop Demo Environment + +**Uninstall Demo Chart** + +```bash +helm uninstall tx-infrastructure --namespace tx +``` diff --git a/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/diagrams/deployed_components.png b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/diagrams/deployed_components.png new file mode 100644 index 000000000..443b739f8 Binary files /dev/null and b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/diagrams/deployed_components.png differ diff --git a/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/diagrams/deployed_components.puml b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/diagrams/deployed_components.puml new file mode 100644 index 000000000..9f3dfdd94 --- /dev/null +++ b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/diagrams/deployed_components.puml @@ -0,0 +1,20 @@ +@startuml + +node Infrastructure as "Tractus-X Connector\nSupporting Infrastructure" { + node SokratesSetup as "Persistence / PostgreSQL" { + database SokratesPsql as "Sokrates PSQL" + database PlatoPsql as "Plato PSQL" + } + node SharedComponents as "Additional Components" { + component Vault as "HashiCorp Vault" + component BackendService as "Backend Application" + } + node IdentityProvider as "Identity Provider" { + component OmejdnDaps as "Omejdn DAPS" + } +} + +IdentityProvider -[hidden]down- SharedComponents +IdentityProvider -[hidden]right- SokratesSetup + +@enduml diff --git a/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/values.yaml b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/values.yaml new file mode 100644 index 000000000..57779134b --- /dev/null +++ b/edc-tests/src/main/resources/deployment/helm/supporting-infrastructure/values.yaml @@ -0,0 +1,308 @@ +--- + +########### +# Install # +########### +install: + daps: true + postgresql: true + vault: true + minio: true + backendservice: true + +################### +# Backend Service # +################### +backend: + fullnameOverride: "backend" + service: + type: NodePort + frontend: + port: 8080 + backend: + port: 8081 + + +######## +# DAPS # +######## +idsdaps: + fullnameOverride: "ids-daps" + connectors: + - id: E7:07:2D:74:56:66:31:F0:7B:10:EA:B6:03:06:4C:23:7F:ED:A6:65:keyid:E7:07:2D:74:56:66:31:F0:7B:10:EA:B6:03:06:4C:23:7F:ED:A6:65 + name: sokrates + attributes: + referringConnector: http://sokrates-controlplane/BPNSOKRATES + # Must be the same certificate that is stores in section 'sokrates-vault' + certificate: |- + -----BEGIN CERTIFICATE----- + MIIEAzCCAuugAwIBAgIUXFgjbN7jxGRUDkoUvEwcN3zcew8wDQYJKoZIhvcNAQEL + BQAwgZAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl + cmxpbjEMMAoGA1UECgwDQk1XMSAwHgYDVQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0 + bmVyMTEvMC0GA1UEAwwmc29rcmF0ZXMtZWRjLmRlbW8uY2F0ZW5hLXgubmV0L0JQ + TjEyMzQwHhcNMjIwNTEwMDc1NzMzWhcNMjMwNTEwMDc1NzMzWjCBkDELMAkGA1UE + BhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQK + DANCTVcxIDAeBgNVBAsMF2VkYy1wbGF5Z3JvdW5kLXBhcnRuZXIxMS8wLQYDVQQD + DCZzb2tyYXRlcy1lZGMuZGVtby5jYXRlbmEteC5uZXQvQlBOMTIzNDCCASIwDQYJ + KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK/41S8rumkk+IzBk9pBDETvjlPmlXfw + 78yRrLmbzaed3kGgygJ2GFFPLcR/Lv0WG8F8au4UEssbOxAU4RRjncCVt66ajaCa + llIqMlH8zaJ8rgxNpGeJU5YvmYRxlIo+Gwi0qnF0tqJh8Hry7OqSo0gK2YBBFJyV + grMsEz3EcsS3ENYJufNgUIeg4QsaL49M0gWxSexPdC4pon96Nvju90D8RlvAJB21 + PInqLniMaFlSnRYzCrUaja6HMmzKA+ZPZ1r9lllzsE00RASxRIxlKkwfzTtMb9O6 + ey2i2vM7hKGGlXjNsnYVX9WXEfvK4JrCadHzgX8qdez19RxFKtB+5gECAwEAAaNT + MFEwHQYDVR0OBBYEFOcHLXRWZjHwexDqtgMGTCN/7aZlMB8GA1UdIwQYMBaAFOcH + LXRWZjHwexDqtgMGTCN/7aZlMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL + BQADggEBAD2a5kuIdICNXfYLpSe7AIONwZVucaArYtpXBxHEy5lMJsTEJgjZzypd + iIMU7onEQGVbii6yVNpWfIpJYM4e8ytVdJuk5evclVKZs/lZ2IshLyWFVj+ITh2E + 28X4C/Hnmt4MPBCNowQf71nMp4LEziBgXp54qFV9C+qSTEVdrherRE0PU/zKyX10 + S/P5o42weTHnAO/pBN/8AmL3AymynKVgcPaW46IjjRAuc6kfZWCrYQ0M4+/7Ws5r + uM55Zae/L+C82OTNNaaK324ogsCkORPeQ23OCrRD8rZJmQ9bpoOGglPminfwEOhB + UHtyKgmvqCyOV3G/4G93W/xsLV0kxLA= + -----END CERTIFICATE----- + - id: 99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:23:keyid:99:83:A7:17:86:FF:98:93:CE:A0:DD:A1:F1:36:FA:F6:0F:75:0A:23 + name: plato + attributes: + referringConnector: http://plato-controlplane/BPNPLATO + # Must be the same certificate that is stores in section 'plato-vault' + certificate: |- + -----BEGIN CERTIFICATE----- + MIID7TCCAtWgAwIBAgIUJ0bwxUc7n3YK89mOyGXrLx2KO0YwDQYJKoZIhvcNAQEL + BQAwgYUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl + cmxpbjEMMAoGA1UECgwDQk1XMSAwHgYDVQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0 + bmVyMjEkMCIGA1UEAwwbcGxhdG8tZWRjLmRlbW8uY2F0ZW5hLXgubmV0MB4XDTIy + MDQyNTEwMjgwMloXDTIzMDQyNTEwMjgwMlowgYUxCzAJBgNVBAYTAkRFMQ8wDQYD + VQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEMMAoGA1UECgwDQk1XMSAwHgYD + VQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0bmVyMjEkMCIGA1UEAwwbcGxhdG8tZWRj + LmRlbW8uY2F0ZW5hLXgubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAm1/UvHXuRU1peEGHULZBP8j8gorXAQvUz8Znb1iVNtldI29GCSXkTHxph66x + TcegdF8aeaoU1mPf3LzMQUU1koZHUq6sRC+50uFcZJ2AjF5IXKQlDPNWR5tPXP56 + RZyqXxjPFHeuTA+YsYyrzEVhzEieOiNaxJDM3uV5pv+FTRHz+xMOgNBonR1QyMh6 + tcwB+EQagoeFl0DjEXAel9WG4hOG/rDiXArTMaVjnTG/ycmF0HeSnbRC+3/+fh/C + hzQJyEbviX67ymyYRJTyynt/Mtrqg5/ssdISexjw3ZmiFNemZIOhIdepoSwnJHFM + 4Jj8B5lq0a1jY5Rc9lDj710RXQIDAQABo1MwUTAdBgNVHQ4EFgQUmYOnF4b/mJPO + oN2h8Tb69g91CiMwHwYDVR0jBBgwFoAUmYOnF4b/mJPOoN2h8Tb69g91CiMwDwYD + VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAKxv/MTIEKNkzReOqrzpt + LM00X6JsDdfxa3rZ0Uq17PjO0R63IPsqzexhfZUML0e/Dwpe97xpvftCOEuICMBA + wOHhQc77MgwyF4dqgRgfJysxw37ACZxU6GI/K2JpKXQLgEhP14oHUIWOzCAbgDhR + jwOx3ZP176Vjxx90pW3hOphRVnq/BRqqEDtFwRzKtGnGvP8ecmC2iY4dXEA3QEp1 + gzg03eglvZSoedEPY5o5y/4n6TplaDmaeoo0QrvAiWik1gY85Lg21aBWVsP45wVS + tFn3m1FCCV8XYIj/EEUAh8VEhphLVEViE6m9Mm4deFDavXcGBb63BCiOQtnjd3eY + zQ== + -----END CERTIFICATE----- + +############## +# PostgreSQL # +############## +plato-postgresql: + fullnameOverride: "plato-postgresql" + primary: + persistence: + enabled: false + readReplicas: + persistence: + enabled: false + auth: + database: "edc" + username: "user" + password: "password" +sokrates-postgresql: + fullnameOverride: "sokrates-postgresql" + primary: + persistence: + enabled: false + readReplicas: + persistence: + enabled: false + auth: + database: "edc" + username: "user" + password: "password" + +######### +# MINIO # +######### +minio: + fullnameOverride: minio + replicas: 2 + drivesPerNode: 0 + serviceAccount: + create: false + persistence: + size: 128Mi + resources: + requests: + memory: 128Mi + service: + type: NodePort + control: + port: 9000 + users: + - accessKey: platoqwerty123 + secretKey: platoqwerty123 + policy: customBucketPolicy + - accessKey: sokratesqwerty123 + secretKey: sokratesqwerty123 + policy: customBucketPolicy + buckets: + # in some cases the minio API acts strange if there exists no bucket at all + - name: dummybucket + policy: none + purge: true + policies: + - name: customBucketPolicy + statements: + - resources: + - 'arn:aws:s3:::*' + actions: + - "s3:PutObject" + - "s3:ListBucket" + - "s3:CreateBucket" + - "s3:GetObject" + - "s3:DeleteObject" + - "s3:DeleteBucket" + +######### +# VAULT # +######### +vault: + fullnameOverride: "vault" + injector: + enabled: false + server: + dev: + enabled: true + devRootToken: "root" + # Must be the same certificate that is configured in section 'ids-daps' + postStart: + - "sh" + - "-c" + - | + { + + sleep 5 + + /bin/vault kv put secret/plato/data-encryption-aes-keys content=H7j47H6vVQQOv/hbdAYz+w== + + cat << EOF | /bin/vault kv put secret/plato/daps/my-plato-daps-key content=- + -----BEGIN PRIVATE KEY----- + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCbX9S8de5FTWl4 + QYdQtkE/yPyCitcBC9TPxmdvWJU22V0jb0YJJeRMfGmHrrFNx6B0Xxp5qhTWY9/c + vMxBRTWShkdSrqxEL7nS4VxknYCMXkhcpCUM81ZHm09c/npFnKpfGM8Ud65MD5ix + jKvMRWHMSJ46I1rEkMze5Xmm/4VNEfP7Ew6A0GidHVDIyHq1zAH4RBqCh4WXQOMR + cB6X1YbiE4b+sOJcCtMxpWOdMb/JyYXQd5KdtEL7f/5+H8KHNAnIRu+JfrvKbJhE + lPLKe38y2uqDn+yx0hJ7GPDdmaIU16Zkg6Eh16mhLCckcUzgmPwHmWrRrWNjlFz2 + UOPvXRFdAgMBAAECggEAN2yd5IRk9I/CucUWUfJRoEE/4glI3PSte1iY+R0uTRyI + nuVIpGbB447VzjLAyLAXSqvKM/A58qg56PHoIrhffd8sfhAVH1WvAcymOrX8bxYK + 1hEvrkj3VB/Q1alpUH+sPrQI2pI+uJ8vptY5SmrNkiOtXavS6x+EFVbiaHHpyS26 + ASaCoRpdBoNTm0SAiDBTK6MqTs4vRpqKseGdC76F+jKimYrTJY19ZctSIAMjrnqd + qzRL+jfob5vMqKC22AjInkZ8BZWll1ZoTnv37bq2NAb9lvdY73REm42Wpm5S7PET + Eixe69gvi/IwaSe27S36+kcrQoYHnxbb31+Xt+0pQQKBgQDJfA2ZnYmcA3yvVQhi + e76I3rq6AEfcG4EDhf+JRO2QHKMMXLwfFAdSR8QflxNUWy1y6q/783EpgLJ1Kv8h + uNkTH6JyV7kFhwfvxWreAWx2jRQRACqnuaLnJ/28vd8Il0kc3/BQsWzbg6YTERrq + 0Au2RW/c9blrKS0MyurtOtZsiQKBgQDFaezSCWUspeNci5lrdvMiHBLOUgR2guQm + Gtf9RdBmzvtBqpdkP8AEMhRW7oSGcKpDldd0Klyml7s/CDYTL7sflHtKRiTQmWuJ + +p3uvyylAxr/Swfw56hj5Y4/Oj2CLIuUlglewo40JnvvM5icT7RGvbyaIIhYzIsR + HTv3t8eRNQKBgA4l8eaJk3IrJIRDWlVgDx8ZVM9e2azxGXwf2rPO7UejWyexE1yz + UVhLxc/aEfdod6aMKFNu4tFhQibMICJEEqovHH8e/dUPiFUj7b8tJmqkuXYAJv6k + IHZO7phkVNcLmIy4hO2Fp/k6I11PZC588XWZJqPDdYO63nj5fsmtygTRAoGBAJ72 + YH/wmMuO+Ll4n51tNvJscKg6WuWjGFumme2T3fArEx8ZYraSruex+7bUcVpgNnod + mlQsGFb9LwXecsyYTrFrOqvgN5zRLUr5x1qMDkMBcSfJHyfZIjruidBX8Vd0zyBi + gEERoLhVlM5UWbrkY2HjPo9NSv1WF1U8mSErl0NRAoGAYC3RxEfGxD9+Qi08nQgg + s/48hLdD2k2q4t3FrDsIGPAIEs52CGp9JWil9RyIQxBXWejETwDz+PgmD6U86Mhh + Qf5css6pcP/w1XF8vsyXfPnecgPSyOE4CgLtnQLxNriMiy5pfALELLyxoBQ+nquz + fMNLPC4K85ps/Uu9uzSatl0= + -----END PRIVATE KEY----- + EOF + + cat << EOF | /bin/vault kv put secret/plato/daps/my-plato-daps-crt content=- + -----BEGIN CERTIFICATE----- + MIID7TCCAtWgAwIBAgIUJ0bwxUc7n3YK89mOyGXrLx2KO0YwDQYJKoZIhvcNAQEL + BQAwgYUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl + cmxpbjEMMAoGA1UECgwDQk1XMSAwHgYDVQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0 + bmVyMjEkMCIGA1UEAwwbcGxhdG8tZWRjLmRlbW8uY2F0ZW5hLXgubmV0MB4XDTIy + MDQyNTEwMjgwMloXDTIzMDQyNTEwMjgwMlowgYUxCzAJBgNVBAYTAkRFMQ8wDQYD + VQQIDAZCZXJsaW4xDzANBgNVBAcMBkJlcmxpbjEMMAoGA1UECgwDQk1XMSAwHgYD + VQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0bmVyMjEkMCIGA1UEAwwbcGxhdG8tZWRj + LmRlbW8uY2F0ZW5hLXgubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEAm1/UvHXuRU1peEGHULZBP8j8gorXAQvUz8Znb1iVNtldI29GCSXkTHxph66x + TcegdF8aeaoU1mPf3LzMQUU1koZHUq6sRC+50uFcZJ2AjF5IXKQlDPNWR5tPXP56 + RZyqXxjPFHeuTA+YsYyrzEVhzEieOiNaxJDM3uV5pv+FTRHz+xMOgNBonR1QyMh6 + tcwB+EQagoeFl0DjEXAel9WG4hOG/rDiXArTMaVjnTG/ycmF0HeSnbRC+3/+fh/C + hzQJyEbviX67ymyYRJTyynt/Mtrqg5/ssdISexjw3ZmiFNemZIOhIdepoSwnJHFM + 4Jj8B5lq0a1jY5Rc9lDj710RXQIDAQABo1MwUTAdBgNVHQ4EFgQUmYOnF4b/mJPO + oN2h8Tb69g91CiMwHwYDVR0jBBgwFoAUmYOnF4b/mJPOoN2h8Tb69g91CiMwDwYD + VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAKxv/MTIEKNkzReOqrzpt + LM00X6JsDdfxa3rZ0Uq17PjO0R63IPsqzexhfZUML0e/Dwpe97xpvftCOEuICMBA + wOHhQc77MgwyF4dqgRgfJysxw37ACZxU6GI/K2JpKXQLgEhP14oHUIWOzCAbgDhR + jwOx3ZP176Vjxx90pW3hOphRVnq/BRqqEDtFwRzKtGnGvP8ecmC2iY4dXEA3QEp1 + gzg03eglvZSoedEPY5o5y/4n6TplaDmaeoo0QrvAiWik1gY85Lg21aBWVsP45wVS + tFn3m1FCCV8XYIj/EEUAh8VEhphLVEViE6m9Mm4deFDavXcGBb63BCiOQtnjd3eY + zQ== + -----END CERTIFICATE----- + EOF + + /bin/vault kv put secret/sokrates/data-encryption-aes-keys content=OcvxzWCK8ETSjt1jmZw3RA== + + cat << EOF | /bin/vault kv put secret/sokrates/daps/my-sokrates-daps-key content=- + -----BEGIN PRIVATE KEY----- + MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCv+NUvK7ppJPiM + wZPaQQxE745T5pV38O/Mkay5m82nnd5BoMoCdhhRTy3Efy79FhvBfGruFBLLGzsQ + FOEUY53Albeumo2gmpZSKjJR/M2ifK4MTaRniVOWL5mEcZSKPhsItKpxdLaiYfB6 + 8uzqkqNICtmAQRSclYKzLBM9xHLEtxDWCbnzYFCHoOELGi+PTNIFsUnsT3QuKaJ/ + ejb47vdA/EZbwCQdtTyJ6i54jGhZUp0WMwq1Go2uhzJsygPmT2da/ZZZc7BNNEQE + sUSMZSpMH807TG/TunstotrzO4ShhpV4zbJ2FV/VlxH7yuCawmnR84F/KnXs9fUc + RSrQfuYBAgMBAAECggEAO+KjsjTgcG3bhBNQnMLsSP15Y0Yicbn18ZlVvaivGS7Z + d14fwSytY+ZdPfTGaey/L16HCVSdfK9cr0Fbw9OO2P5ajzobnp9dLsMbctlkpbpm + hNtbarzKTF8QkIkSsuUl0BWjt46vpJ1N+Jl5VO7oUFkY4dPEDvG2lAEY3zlekWDm + cQeOC/YgpoW4xfRwPPS6QE0w3Q+H5NfNjfz+mSHeItTlVfTKDRliWQLPWeRZFuXh + FlRFUQnTmEE/9wpIe3Hn7WXJ3fQqcYDzxU7/zwwY9I7bB15SgVHlR0ENDPAD5X8F + MVZ3EcLlqGBy+WvTWALp6pc8YfhW3fiTWyuamXtNrQKBgQDonsIzBKEOOKdKGW0e + uyw79ErmnmzkY5nuMrMxrmTA4WKCfJ/YRRA+4sxiltWsIJ3UkHe3OBCSSCdj79hb + ugb/+UzE70hOdgrct2NUQqbrj3gvsVvU8ZRQgTRMqKpmC0zY7KOMx6NU85z3IvS1 + z5fjszcUv4kLQlldYGSAuqPy+wKBgQDBqIkc8p/wcw7ygo1q/GerNeszfoxiIFp8 + h4RWLVhkwrcXFz30wBlUWuv5/kxU8tmJcmXxe72EmUstd6wvNOAnYwCiile6zQiJ + vsr1axavZnGOtNGUp6DUAsd2iviBl7IZ7kAcqCrQo4ivGhfHmahH3hmg8wuAMjYB + 8f+FSPgaMwKBgQC7W4tMrjDOFIFhJEOIWfcRvvxI7VcFSNelS76aiDzsQVwnfxr7 + hPzFucQmsBgfUBHvMADMWGK4f1cCnh5kGtwidXgIsjVJxLeQ+EAPkLOCzQZfW3l8 + dKshgD9QcxTzpaxal5ZPAEikVqaZQtVYToCmzCTUGETYBbOWitnH+Qut2wKBgQC6 + Y6DcSLUhc0xOotLDxv1sbu/aVxF8nFEbDD+Vxf0Otc4MnmUWPRHj+8KlkVkcZcR0 + IrP1kThd+EDAGS+TG9wmbIY+6tH3S8HM+eJUBWcHGJ1xUZ1p61DC3Y3nDWiTKlLT + 3Fi+fCkBOHSku4Npq/2odh7Kp0JJd4o9oxJg0VNhuwKBgQDSFn7dqFE0Xmwc40Vr + 0wJH8cPWXKGt7KJENpj894buk2DniLD4w2x874dzTjrOFi6fKxEzbBNA9Rq9UPo8 + u9gKvl/IyWmV0c4zFCNMjRwVdnkMEte/lXcJZ67T4FXZByqAZlhrr/v0FD442Z9B + AjWFbUiBCFOo+gpAFcQGrkOQHA== + -----END PRIVATE KEY----- + EOF + + cat << EOF | /bin/vault kv put secret/sokrates/daps/my-sokrates-daps-crt content=- + -----BEGIN CERTIFICATE----- + MIIEAzCCAuugAwIBAgIUXFgjbN7jxGRUDkoUvEwcN3zcew8wDQYJKoZIhvcNAQEL + BQAwgZAxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJsaW4xDzANBgNVBAcMBkJl + cmxpbjEMMAoGA1UECgwDQk1XMSAwHgYDVQQLDBdlZGMtcGxheWdyb3VuZC1wYXJ0 + bmVyMTEvMC0GA1UEAwwmc29rcmF0ZXMtZWRjLmRlbW8uY2F0ZW5hLXgubmV0L0JQ + TjEyMzQwHhcNMjIwNTEwMDc1NzMzWhcNMjMwNTEwMDc1NzMzWjCBkDELMAkGA1UE + BhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQK + DANCTVcxIDAeBgNVBAsMF2VkYy1wbGF5Z3JvdW5kLXBhcnRuZXIxMS8wLQYDVQQD + DCZzb2tyYXRlcy1lZGMuZGVtby5jYXRlbmEteC5uZXQvQlBOMTIzNDCCASIwDQYJ + KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK/41S8rumkk+IzBk9pBDETvjlPmlXfw + 78yRrLmbzaed3kGgygJ2GFFPLcR/Lv0WG8F8au4UEssbOxAU4RRjncCVt66ajaCa + llIqMlH8zaJ8rgxNpGeJU5YvmYRxlIo+Gwi0qnF0tqJh8Hry7OqSo0gK2YBBFJyV + grMsEz3EcsS3ENYJufNgUIeg4QsaL49M0gWxSexPdC4pon96Nvju90D8RlvAJB21 + PInqLniMaFlSnRYzCrUaja6HMmzKA+ZPZ1r9lllzsE00RASxRIxlKkwfzTtMb9O6 + ey2i2vM7hKGGlXjNsnYVX9WXEfvK4JrCadHzgX8qdez19RxFKtB+5gECAwEAAaNT + MFEwHQYDVR0OBBYEFOcHLXRWZjHwexDqtgMGTCN/7aZlMB8GA1UdIwQYMBaAFOcH + LXRWZjHwexDqtgMGTCN/7aZlMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL + BQADggEBAD2a5kuIdICNXfYLpSe7AIONwZVucaArYtpXBxHEy5lMJsTEJgjZzypd + iIMU7onEQGVbii6yVNpWfIpJYM4e8ytVdJuk5evclVKZs/lZ2IshLyWFVj+ITh2E + 28X4C/Hnmt4MPBCNowQf71nMp4LEziBgXp54qFV9C+qSTEVdrherRE0PU/zKyX10 + S/P5o42weTHnAO/pBN/8AmL3AymynKVgcPaW46IjjRAuc6kfZWCrYQ0M4+/7Ws5r + uM55Zae/L+C82OTNNaaK324ogsCkORPeQ23OCrRD8rZJmQ9bpoOGglPminfwEOhB + UHtyKgmvqCyOV3G/4G93W/xsLV0kxLA= + -----END CERTIFICATE----- + EOF + } + + ui: + enabled: true + externalPort: 8200 + targetPort: 8200 diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/AssetStepDefs.java b/edc-tests/src/test/java/net/catenax/edc/tests/AssetStepDefs.java deleted file mode 100644 index 3c96d9de8..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/AssetStepDefs.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.tests; - -import io.cucumber.datatable.DataTable; -import io.cucumber.java.en.Given; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import net.catenax.edc.tests.data.Asset; - -public class AssetStepDefs { - - @Given("'{connector}' has the following assets") - public void hasAssets(Connector connector, DataTable table) throws Exception { - final DataManagementAPI api = connector.getDataManagementAPI(); - final List assets = parseDataTable(table); - - for (Asset asset : assets) api.createAsset(asset); - } - - @Given("'{connector}' has '{int}' assets") - public void hasAssets(Connector connector, int assetCount) throws Exception { - final DataManagementAPI api = connector.getDataManagementAPI(); - - for (var i = 0; i < assetCount; i++) - api.createAsset(new Asset(UUID.randomUUID().toString(), i + 1 + " / " + assetCount)); - } - - private List parseDataTable(DataTable table) { - final List assets = new ArrayList<>(); - - for (Map map : table.asMaps()) { - String id = map.get("id"); - String description = map.get("description"); - assets.add(new Asset(id, description)); - } - - return assets; - } -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/ConnectorFactory.java b/edc-tests/src/test/java/net/catenax/edc/tests/ConnectorFactory.java deleted file mode 100644 index 9a9d7e2ac..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/ConnectorFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.tests; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import lombok.NonNull; -import lombok.experimental.UtilityClass; - -@UtilityClass -public class ConnectorFactory { - private static final Map CONNECTOR_CACHE = new HashMap<>(); - - public static Connector byName(@NonNull final String name) { - return CONNECTOR_CACHE.computeIfAbsent( - name.toUpperCase(Locale.ROOT), k -> createConnector(name)); - } - - private static Connector createConnector(@NonNull final String name) { - final Environment environment = Environment.byName(name); - - return new Connector(name, environment); - } -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/ConnectorSteps.java b/edc-tests/src/test/java/net/catenax/edc/tests/ConnectorSteps.java deleted file mode 100644 index 8af81d655..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/ConnectorSteps.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Implementation - * - */ - -package net.catenax.edc.tests; - -import io.cucumber.java.en.Given; -import java.sql.SQLException; - -public class ConnectorSteps { - - @Given("'{connector}' has an empty database") - public void cleanDatabase(Connector connector) throws SQLException { - connector.getDatabaseCleaner().run(); - } -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/Constants.java b/edc-tests/src/test/java/net/catenax/edc/tests/Constants.java deleted file mode 100644 index 6f16894ea..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/Constants.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.tests; - -import lombok.experimental.UtilityClass; - -@UtilityClass -public final class Constants { - public static final String DATA_MANAGEMENT_URL = "DATA_MANAGEMENT_URL"; - public static final String DATA_MANAGEMENT_API_AUTH_KEY = "DATA_MANAGEMENT_API_AUTH_KEY"; - public static final String IDS_URL = "IDS_URL"; - public static final String DATA_PLANE_URL = "DATA_PLANE_URL"; - public static final String BACKEND_SERVICE_BACKEND_API_URL = "BACKEND_SERVICE_BACKEND_API_URL"; - public static final String DATABASE_URL = "DATABASE_URL"; - public static final String DATABASE_USER = "DATABASE_USER"; - public static final String DATABASE_PASSWORD = "DATABASE_PASSWORD"; -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/DataManagementAPI.java b/edc-tests/src/test/java/net/catenax/edc/tests/DataManagementAPI.java deleted file mode 100644 index 7520b5fa7..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/DataManagementAPI.java +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.tests; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; -import net.catenax.edc.tests.data.Asset; -import net.catenax.edc.tests.data.BusinessPartnerNumberConstraint; -import net.catenax.edc.tests.data.Constraint; -import net.catenax.edc.tests.data.ContractDefinition; -import net.catenax.edc.tests.data.ContractNegotiation; -import net.catenax.edc.tests.data.ContractNegotiationState; -import net.catenax.edc.tests.data.ContractOffer; -import net.catenax.edc.tests.data.PayMeConstraint; -import net.catenax.edc.tests.data.Permission; -import net.catenax.edc.tests.data.Policy; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.HttpClientBuilder; - -@Slf4j -public class DataManagementAPI { - - private static final String ASSET_PATH = "/assets"; - private static final String POLICY_PATH = "/policydefinitions"; - private static final String CONTRACT_DEFINITIONS_PATH = "/contractdefinitions"; - private static final String CATALOG_PATH = "/catalog"; - private static final String NEGOTIATIONS_PATH = "/contractnegotiations"; - - private final String dataMgmtUrl; - private final String dataMgmtAuthKey; - private final HttpClient httpClient; - - public DataManagementAPI(String dataManagementUrl, String dataMgmtAuthKey) { - this.httpClient = HttpClientBuilder.create().build(); - this.dataMgmtUrl = dataManagementUrl; - this.dataMgmtAuthKey = dataMgmtAuthKey; - } - - public List requestCatalogFrom(String receivingConnectorUrl) throws IOException { - final String encodedUrl = URLEncoder.encode(receivingConnectorUrl, StandardCharsets.UTF_8); - final DataManagementApiContractOfferCatalog catalog = - get( - CATALOG_PATH, - "providerUrl=" + encodedUrl + "&limit=1000", - new TypeToken() {}); - - log.debug("Received " + catalog.contractOffers.size() + " offers"); - - return catalog.contractOffers.stream().map(this::mapOffer).collect(Collectors.toList()); - } - - public String initiateNegotiation( - String receivingConnectorUrl, String definitionId, String assetId, Policy policy) - throws IOException { - final DataManagementApiOffer offer = new DataManagementApiOffer(); - offer.offerId = definitionId + ":foo"; - offer.assetId = assetId; - offer.policy = mapPolicy(policy); - offer.policy.permissions.forEach(p -> p.target = assetId); - - final DataManagementApiNegotiationPayload negotiationPayload = - new DataManagementApiNegotiationPayload(); - negotiationPayload.connectorAddress = receivingConnectorUrl; - negotiationPayload.offer = offer; - - final DataManagementApiNegotiationResponse response = - post( - NEGOTIATIONS_PATH, - negotiationPayload, - new TypeToken() {}); - - if (response == null) - throw new RuntimeException( - "Initiated negotiation. Connector did not answer with negotiation ID."); - - log.debug("Initiated negotiation ( id= " + response.getId() + " )"); - - return response.getId(); - } - - public ContractNegotiation getNegotiation(String id) throws IOException { - final DataManagementApiNegotiation negotiation = - get(NEGOTIATIONS_PATH + "/" + id, new TypeToken() {}); - return mapNegotiation(negotiation); - } - - public void createAsset(Asset asset) throws IOException { - final DataManagementApiDataAddress dataAddress = new DataManagementApiDataAddress(); - dataAddress.properties = - Map.of( - DataManagementApiDataAddress.TYPE, - "HttpData", - "baseUrl", - "https://jsonplaceholder.typicode.com/todos/1"); - - final DataManagementApiAssetCreate assetCreate = new DataManagementApiAssetCreate(); - assetCreate.asset = mapAsset(asset); - assetCreate.dataAddress = dataAddress; - - post(ASSET_PATH, assetCreate); - } - - public void createPolicy(Policy policy) throws IOException { - post(POLICY_PATH, mapPolicyDefinition(policy)); - } - - public void createContractDefinition(ContractDefinition contractDefinition) throws IOException { - post(CONTRACT_DEFINITIONS_PATH, mapContractDefinition(contractDefinition)); - } - - private T get(String path, String params, TypeToken typeToken) throws IOException { - return get(path + "?" + params, typeToken); - } - - private T get(String path, TypeToken typeToken) throws IOException { - - final HttpGet get = new HttpGet(dataMgmtUrl + path); - final HttpResponse response = sendRequest(get); - final byte[] json = response.getEntity().getContent().readAllBytes(); - - log.debug("Received response: {}", new String(json, StandardCharsets.UTF_8)); - return new Gson().fromJson(new String(json, StandardCharsets.UTF_8), typeToken.getType()); - } - - private void post(String path, Object object) throws IOException { - post(path, object, new TypeToken() {}); - } - - private T post(String path, Object object, TypeToken typeToken) throws IOException { - final String url = String.format("%s%s", dataMgmtUrl, path); - final HttpPost post = new HttpPost(url); - post.addHeader("Content-Type", "application/json"); - - var json = new Gson().toJson(object); - - log.debug("POST Payload: " + json); - - post.setEntity(new StringEntity(json)); - - final HttpResponse response = sendRequest(post); - - if (typeToken.equals(new TypeToken() {})) return null; - - final byte[] responseJson = response.getEntity().getContent().readAllBytes(); - return new Gson() - .fromJson(new String(responseJson, StandardCharsets.UTF_8), typeToken.getType()); - } - - private HttpResponse sendRequest(HttpRequestBase request) throws IOException { - request.addHeader("X-Api-Key", dataMgmtAuthKey); - - log.debug(String.format("Send %-6s %s", request.getMethod(), request.getURI())); - - final HttpResponse response = httpClient.execute(request); - if (200 > response.getStatusLine().getStatusCode() - || response.getStatusLine().getStatusCode() >= 300) { - throw new RuntimeException( - String.format("Unexpected response: %s", response.getStatusLine())); - } - - return response; - } - - private ContractNegotiation mapNegotiation(DataManagementApiNegotiation negotiation) { - - ContractNegotiationState state; - - switch (negotiation.state) { - case "ERROR": - state = ContractNegotiationState.ERROR; - break; - case "INITIAL": - state = ContractNegotiationState.INITIAL; - break; - case "DECLINED": - state = ContractNegotiationState.DECLINED; - break; - case "CONFIRMED": - state = ContractNegotiationState.CONFIRMED; - break; - default: - state = ContractNegotiationState.UNKNOWN; - } - - return new ContractNegotiation(negotiation.id, negotiation.agreementId, state); - } - - private DataManagementApiAsset mapAsset(Asset asset) { - final Map properties = - Map.of( - DataManagementApiAsset.ID, asset.getId(), - DataManagementApiAsset.DESCRIPTION, asset.getDescription()); - - final DataManagementApiAsset apiObject = new DataManagementApiAsset(); - apiObject.setProperties(properties); - return apiObject; - } - - private Policy mapPolicy(DataManagementApiPolicy dataManagementApiPolicy) { - final String id = dataManagementApiPolicy.uid; - final List permissions = - dataManagementApiPolicy.permissions.stream() - .map(this::mapPermission) - .collect(Collectors.toList()); - - return new Policy(id, permissions); - } - - private DataManagementApiPolicy mapPolicy(Policy policy) { - final List permissions = - policy.getPermission().stream().map(this::mapPermission).collect(Collectors.toList()); - final DataManagementApiPolicy dataManagementApiPolicy = new DataManagementApiPolicy(); - dataManagementApiPolicy.permissions = permissions; - - return dataManagementApiPolicy; - } - - private DataManagementApiPolicyDefinition mapPolicyDefinition(Policy policy) { - final DataManagementApiPolicyDefinition apiObject = new DataManagementApiPolicyDefinition(); - apiObject.id = policy.getId(); - apiObject.policy = mapPolicy(policy); - return apiObject; - } - - private Permission mapPermission(DataManagementApiPermission dataManagementApiPermission) { - final String target = dataManagementApiPermission.target; - final String action = dataManagementApiPermission.action.type; - return new Permission(action, target, new ArrayList<>()); - } - - private DataManagementApiPermission mapPermission(Permission permission) { - final String target = permission.getTarget(); - final String action = permission.getAction(); - - final DataManagementApiRuleAction apiAction = new DataManagementApiRuleAction(); - apiAction.type = action; - - final List constraints = - permission.getConstraints().stream().map(this::mapConstraint).collect(Collectors.toList()); - - final DataManagementApiPermission apiObject = new DataManagementApiPermission(); - apiObject.target = target; - apiObject.action = apiAction; - apiObject.constraints = constraints; - return apiObject; - } - - private DataManagementApiConstraint mapConstraint(Constraint constraint) { - - if (BusinessPartnerNumberConstraint.class.equals(constraint.getClass())) { - return mapConstraint((BusinessPartnerNumberConstraint) constraint); - } else if (PayMeConstraint.class.equals(constraint.getClass())) { - return mapConstraint((PayMeConstraint) constraint); - } else { - throw new UnsupportedOperationException( - "Unsupported constraint type: " + constraint.getClass().getName()); - } - } - - private DataManagementApiConstraint mapConstraint(PayMeConstraint constraint) { - final DataManagementApiLiteralExpression leftExpression = - new DataManagementApiLiteralExpression(); - leftExpression.value = "PayMe"; - - final DataManagementApiLiteralExpression rightExpression = - new DataManagementApiLiteralExpression(); - rightExpression.value = String.valueOf(constraint.getAmount()); - - final DataManagementApiConstraint dataManagementApiConstraint = - new DataManagementApiConstraint(); - dataManagementApiConstraint.leftExpression = leftExpression; - dataManagementApiConstraint.rightExpression = rightExpression; - dataManagementApiConstraint.operator = "EQ"; - - return dataManagementApiConstraint; - } - - private DataManagementApiConstraint mapConstraint(BusinessPartnerNumberConstraint constraint) { - final DataManagementApiLiteralExpression leftExpression = - new DataManagementApiLiteralExpression(); - leftExpression.value = "BusinessPartnerNumber"; - - final DataManagementApiLiteralExpression rightExpression = - new DataManagementApiLiteralExpression(); - rightExpression.value = constraint.getBusinessPartnerNumber(); - - final DataManagementApiConstraint dataManagementApiConstraint = - new DataManagementApiConstraint(); - dataManagementApiConstraint.leftExpression = leftExpression; - dataManagementApiConstraint.rightExpression = rightExpression; - dataManagementApiConstraint.operator = "EQ"; - - return dataManagementApiConstraint; - } - - private ContractOffer mapOffer(DataManagementApiContractOffer dataManagementApiContractOffer) { - final String id = dataManagementApiContractOffer.id; - final String assetId = - dataManagementApiContractOffer.assetId != null - ? dataManagementApiContractOffer.assetId - : (String) - dataManagementApiContractOffer.asset.getProperties().get(DataManagementApiAsset.ID); - - final Policy policy = mapPolicy(dataManagementApiContractOffer.getPolicy()); - - return new ContractOffer(id, policy, assetId); - } - - private DataManagementApiContractDefinition mapContractDefinition( - ContractDefinition contractDefinition) { - - final DataManagementApiContractDefinition apiObject = new DataManagementApiContractDefinition(); - apiObject.id = contractDefinition.getId(); - apiObject.accessPolicyId = contractDefinition.getAcccessPolicyId(); - apiObject.contractPolicyId = contractDefinition.getContractPolicyId(); - apiObject.criteria = new ArrayList<>(); - - for (final String assetId : contractDefinition.getAssetIds()) { - DataManagementApiCriterion criterion = new DataManagementApiCriterion(); - criterion.operandLeft = DataManagementApiAsset.ID; - criterion.operator = "="; - criterion.operandRight = assetId; - - apiObject.criteria.add(criterion); - } - - return apiObject; - } - - @Data - private static class DataManagementApiNegotiationResponse { - private String id; - } - - @Data - private static class DataManagementApiNegotiationPayload { - private String connectorId = "foo"; - private String connectorAddress; - private DataManagementApiOffer offer; - } - - @Data - private static class DataManagementApiNegotiation { - private String id; - private String state; - private String agreementId; - } - - @Data - private static class DataManagementApiOffer { - private String offerId; - private String assetId; - private DataManagementApiPolicy policy; - } - - @Data - private static class DataManagementApiAssetCreate { - private DataManagementApiAsset asset; - private DataManagementApiDataAddress dataAddress; - } - - @Data - private static class DataManagementApiAsset { - public static final String ID = "asset:prop:id"; - public static final String DESCRIPTION = "asset:prop:description"; - - private Map properties; - } - - @Data - private static class DataManagementApiDataAddress { - public static final String TYPE = "type"; - private Map properties; - } - - @Data - private static class DataManagementApiPolicyDefinition { - private String id; - private DataManagementApiPolicy policy; - } - - @Data - private static class DataManagementApiPolicy { - private String uid; - private List permissions = new ArrayList<>(); - } - - @Data - private static class DataManagementApiPermission { - private String edctype = "dataspaceconnector:permission"; - private DataManagementApiRuleAction action; - private String target; - private List constraints = new ArrayList<>(); - } - - @Data - private static class DataManagementApiConstraint { - private String edctype = "AtomicConstraint"; - private DataManagementApiLiteralExpression leftExpression; - private DataManagementApiLiteralExpression rightExpression; - private String operator; - } - - @Data - private static class DataManagementApiLiteralExpression { - private String edctype = "dataspaceconnector:literalexpression"; - private String value; - } - - @Data - private static class DataManagementApiRuleAction { - private String type; - } - - @Data - private static class DataManagementApiContractDefinition { - private String id; - private String accessPolicyId; - private String contractPolicyId; - private List criteria = new ArrayList<>(); - } - - @Data - private static class DataManagementApiCriterion { - private Object operandLeft; - private String operator; - private Object operandRight; - } - - @Data - private static class DataManagementApiContractOffer { - private String id; - private DataManagementApiPolicy policy; - private DataManagementApiAsset asset; - private String assetId; - } - - @Data - private static class DataManagementApiContractOfferCatalog { - private String id; - private List contractOffers = new ArrayList<>(); - } -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/Environment.java b/edc-tests/src/test/java/net/catenax/edc/tests/Environment.java deleted file mode 100644 index 699472a63..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/Environment.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.tests; - -import static net.catenax.edc.tests.Constants.BACKEND_SERVICE_BACKEND_API_URL; -import static net.catenax.edc.tests.Constants.DATABASE_PASSWORD; -import static net.catenax.edc.tests.Constants.DATABASE_URL; -import static net.catenax.edc.tests.Constants.DATABASE_USER; -import static net.catenax.edc.tests.Constants.DATA_MANAGEMENT_API_AUTH_KEY; -import static net.catenax.edc.tests.Constants.DATA_MANAGEMENT_URL; -import static net.catenax.edc.tests.Constants.DATA_PLANE_URL; -import static net.catenax.edc.tests.Constants.IDS_URL; - -import java.util.Locale; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NonNull; - -@Builder(access = AccessLevel.PRIVATE) -@Getter -class Environment { - @NonNull private final String dataManagementAuthKey; - @NonNull private final String dataManagementUrl; - @NonNull private final String idsUrl; - @NonNull private final String dataPlaneUrl; - @NonNull private final String backendServiceBackendApiUrl; - @NonNull private final String databaseUrl; - @NonNull private final String databaseUser; - @NonNull private final String databasePassword; - - public static Environment byName(String name) { - name = name.toUpperCase(Locale.ROOT); - - return Environment.builder() - .dataManagementUrl(System.getenv(String.join("_", name, DATA_MANAGEMENT_URL))) - .dataManagementAuthKey(System.getenv(String.join("_", name, DATA_MANAGEMENT_API_AUTH_KEY))) - .idsUrl(System.getenv(String.join("_", name, IDS_URL))) - .dataPlaneUrl(System.getenv(String.join("_", name, DATA_PLANE_URL))) - .backendServiceBackendApiUrl( - System.getenv(String.join("_", name, BACKEND_SERVICE_BACKEND_API_URL))) - .databaseUrl(System.getenv(String.join("_", name, DATABASE_URL))) - .databaseUser(System.getenv(String.join("_", name, DATABASE_USER))) - .databasePassword(System.getenv(String.join("_", name, DATABASE_PASSWORD))) - .build(); - } -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/NegotiationSteps.java b/edc-tests/src/test/java/net/catenax/edc/tests/NegotiationSteps.java deleted file mode 100644 index bf4bcdd12..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/NegotiationSteps.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Implementation - * - */ - -package net.catenax.edc.tests; - -import static org.awaitility.Awaitility.await; - -import io.cucumber.datatable.DataTable; -import io.cucumber.java.en.Then; -import io.cucumber.java.en.When; -import java.io.IOException; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; -import lombok.extern.slf4j.Slf4j; -import net.catenax.edc.tests.data.ContractNegotiation; -import net.catenax.edc.tests.data.ContractNegotiationState; -import net.catenax.edc.tests.data.Permission; -import net.catenax.edc.tests.data.Policy; -import net.catenax.edc.tests.util.Timeouts; -import org.junit.jupiter.api.Assertions; - -@Slf4j -public class NegotiationSteps { - - private ContractNegotiation lastInitiatedNegotiation; - - @When("'{connector}' sends '{connector}' a counter offer without constraints") - public void sendOfferWithoutConstraints(Connector sender, Connector receiver, DataTable table) - throws IOException { - - final DataManagementAPI dataManagementAPI = sender.getDataManagementAPI(); - final String receiverIdsUrl = receiver.getEnvironment().getIdsUrl() + "/data"; - - for (Map map : table.asMaps()) { - final String definitionId = map.get("definition id"); - final String assetId = map.get("asset id"); - - final Permission permission = new Permission("USE", null, new ArrayList<>()); - final Policy policy = new Policy("foo", List.of(permission)); - - final String negotiationId = - dataManagementAPI.initiateNegotiation(receiverIdsUrl, definitionId, assetId, policy); - - // wait for negotiation to complete - await() - .pollDelay(Duration.ofMillis(500)) - .atMost(Timeouts.CONTRACT_NEGOTIATION) - .until(() -> isNegotiationComplete(dataManagementAPI, negotiationId)); - - lastInitiatedNegotiation = dataManagementAPI.getNegotiation(negotiationId); - } - } - - @Then("the negotiation is declined") - public void assertLastNegotiationDeclined() { - Assertions.assertEquals(ContractNegotiationState.DECLINED, lastInitiatedNegotiation.getState()); - } - - private boolean isNegotiationComplete(DataManagementAPI dataManagementAPI, String negotiationId) - throws IOException { - var negotiation = dataManagementAPI.getNegotiation(negotiationId); - return negotiation != null - && Stream.of( - ContractNegotiationState.ERROR, - ContractNegotiationState.CONFIRMED, - ContractNegotiationState.DECLINED) - .anyMatch((l) -> l.equals(negotiation.getState())); - } -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/PolicyStepDefs.java b/edc-tests/src/test/java/net/catenax/edc/tests/PolicyStepDefs.java deleted file mode 100644 index 81f173c09..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/PolicyStepDefs.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.tests; - -import io.cucumber.datatable.DataTable; -import io.cucumber.java.en.Given; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import net.catenax.edc.tests.data.BusinessPartnerNumberConstraint; -import net.catenax.edc.tests.data.Constraint; -import net.catenax.edc.tests.data.PayMeConstraint; -import net.catenax.edc.tests.data.Permission; -import net.catenax.edc.tests.data.Policy; - -public class PolicyStepDefs { - - @Given("'{connector}' has the following policies") - public void hasPolicies(Connector connector, DataTable table) throws Exception { - final DataManagementAPI api = connector.getDataManagementAPI(); - final List policies = parseDataTable(table); - - for (Policy policy : policies) api.createPolicy(policy); - } - - private List parseDataTable(DataTable table) { - final List policies = new ArrayList<>(); - - for (Map map : table.asMaps()) { - final String id = map.get("id"); - final String action = map.get("action"); - - List constraints = new ArrayList<>(); - final String businessPartnerNumber = map.get("businessPartnerNumber"); - if (businessPartnerNumber != null && !businessPartnerNumber.isBlank()) - constraints.add(new BusinessPartnerNumberConstraint(businessPartnerNumber)); - - final String payMe = map.get("payMe"); - if (payMe != null && !payMe.isBlank()) - constraints.add(new PayMeConstraint(Double.parseDouble(payMe))); - - final List permission = List.of(new Permission(action, null, constraints)); - - policies.add(new Policy(id, permission)); - } - - return policies; - } -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/Asset.java b/edc-tests/src/test/java/net/catenax/edc/tests/data/Asset.java deleted file mode 100644 index b402df750..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/Asset.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.tests.data; - -import lombok.NonNull; -import lombok.Value; - -@Value -public class Asset { - @NonNull String Id; - - @NonNull String description; -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/Constraint.java b/edc-tests/src/test/java/net/catenax/edc/tests/data/Constraint.java deleted file mode 100644 index 1fbd2fa59..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/Constraint.java +++ /dev/null @@ -1,3 +0,0 @@ -package net.catenax.edc.tests.data; - -public interface Constraint {} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractNegotiation.java b/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractNegotiation.java deleted file mode 100644 index aff80ff8b..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractNegotiation.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Implementation - * - */ - -package net.catenax.edc.tests.data; - -import lombok.NonNull; -import lombok.Value; - -@Value -public class ContractNegotiation { - @NonNull String id; - String agreementId; - @NonNull ContractNegotiationState state; -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractNegotiationState.java b/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractNegotiationState.java deleted file mode 100644 index 66b077601..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractNegotiationState.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Implementation - * - */ - -package net.catenax.edc.tests.data; - -public enum ContractNegotiationState { - UNKNOWN, - INITIAL, - DECLINED, - CONFIRMED, - ERROR -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractOffer.java b/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractOffer.java deleted file mode 100644 index 329639fed..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/ContractOffer.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.tests.data; - -import lombok.NonNull; -import lombok.Value; - -@Value -public class ContractOffer { - @NonNull String id; - Policy policy; - String assetId; -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/PayMeConstraint.java b/edc-tests/src/test/java/net/catenax/edc/tests/data/PayMeConstraint.java deleted file mode 100644 index 3a12fe12f..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/PayMeConstraint.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Implementation - * - */ - -package net.catenax.edc.tests.data; - -import lombok.Value; - -/** - * The PayMe constraint should be used when no constraint validation/enforcement in the EDC is - * intended. - */ -@Value -public class PayMeConstraint implements Constraint { - double amount; -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/Permission.java b/edc-tests/src/test/java/net/catenax/edc/tests/data/Permission.java deleted file mode 100644 index d0f15b13f..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/Permission.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ -package net.catenax.edc.tests.data; - -import java.util.List; -import lombok.NonNull; -import lombok.Value; - -@Value -public class Permission { - @NonNull String action; - String target; - - @NonNull List constraints; -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/Policy.java b/edc-tests/src/test/java/net/catenax/edc/tests/data/Policy.java deleted file mode 100644 index 2996fa032..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/Policy.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.tests.data; - -import java.util.List; -import lombok.NonNull; -import lombok.Value; - -@Value -public class Policy { - String id; - @NonNull List Permission; -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/features/ParameterTypes.java b/edc-tests/src/test/java/net/catenax/edc/tests/features/ParameterTypes.java deleted file mode 100644 index 29a3b8072..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/features/ParameterTypes.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.catenax.edc.tests.features; - -import io.cucumber.java.ParameterType; -import net.catenax.edc.tests.Connector; -import net.catenax.edc.tests.ConnectorFactory; - -public class ParameterTypes { - - @ParameterType("Plato|Sokrates") - public Connector connector(String name) { - return ConnectorFactory.byName(name); - } -} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/features/RunCucumberTest.java b/edc-tests/src/test/java/net/catenax/edc/tests/features/RunCucumberTest.java deleted file mode 100644 index 0c4c9379c..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/features/RunCucumberTest.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation - * - */ - -package net.catenax.edc.tests.features; - -import org.junit.platform.suite.api.SelectClasspathResource; -import org.junit.platform.suite.api.Suite; - -@Suite -@SelectClasspathResource("net/catenax/edc/tests/features") -public class RunCucumberTest {} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/util/Timeouts.java b/edc-tests/src/test/java/net/catenax/edc/tests/util/Timeouts.java deleted file mode 100644 index 355de752d..000000000 --- a/edc-tests/src/test/java/net/catenax/edc/tests/util/Timeouts.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation 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: - * Mercedes-Benz Tech Innovation GmbH - Initial Implementation - * - */ - -package net.catenax.edc.tests.util; - -import java.time.Duration; - -public class Timeouts { - private Timeouts() {} - - public static final Duration CONTRACT_NEGOTIATION = Duration.ofSeconds(90); -} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/AssetStepDefs.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/AssetStepDefs.java new file mode 100644 index 000000000..0405bf646 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/AssetStepDefs.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import io.cucumber.datatable.DataTable; +import io.cucumber.java.en.Given; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.eclipse.tractusx.edc.tests.data.Asset; +import org.eclipse.tractusx.edc.tests.data.NullDataAddress; + +public class AssetStepDefs { + + @Given("'{connector}' has the following assets") + public void hasAssets(Connector connector, DataTable table) throws Exception { + final DataManagementAPI api = connector.getDataManagementAPI(); + final List assets = parseDataTable(table); + + for (Asset asset : assets) api.createAsset(asset); + } + + @Given("'{connector}' has '{int}' assets") + public void hasAssets(Connector connector, int assetCount) throws Exception { + final DataManagementAPI api = connector.getDataManagementAPI(); + + for (var i = 0; i < assetCount; i++) + api.createAsset( + new Asset( + UUID.randomUUID().toString(), i + 1 + " / " + assetCount, NullDataAddress.INSTANCE)); + } + + private List parseDataTable(DataTable table) { + final List assets = new ArrayList<>(); + + for (Map map : table.asMaps()) { + String id = map.get("id"); + String description = map.get("description"); + assets.add(new Asset(id, description, NullDataAddress.INSTANCE)); + } + + return assets; + } +} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/BackendServiceBackendAPI.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/BackendServiceBackendAPI.java similarity index 87% rename from edc-tests/src/test/java/net/catenax/edc/tests/BackendServiceBackendAPI.java rename to edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/BackendServiceBackendAPI.java index f68d0da59..6b2a5ee2e 100644 --- a/edc-tests/src/test/java/net/catenax/edc/tests/BackendServiceBackendAPI.java +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/BackendServiceBackendAPI.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.tests; +package org.eclipse.tractusx.edc.tests; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -30,6 +36,7 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -48,6 +55,7 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; +@Slf4j public class BackendServiceBackendAPI { private static final String HTTP_HEADER_ACCEPT = "Accept"; private static final String HTTP_HEADER_CONTENT_TYPE = "Content-Type"; @@ -62,7 +70,7 @@ public BackendServiceBackendAPI(@NonNull final String backendServiceBackendApiUr /** Lists all files and directories associated by a backend-service path. */ @SneakyThrows - public List list(/*@Nullable*/ final String path) { + public List list(/* @Nullable */ final String path) { final URI uri = new URIBuilder(backendServiceBackendApiUrl) .setPath(Optional.ofNullable(path).orElse(PATH_ROOT)) @@ -70,6 +78,8 @@ public List list(/*@Nullable*/ final String path) { final HttpGet get = new HttpGet(uri); get.setHeader(HTTP_HEADER_ACCEPT, ContentType.APPLICATION_JSON.getMimeType()); + log.debug(String.format("Send %-6s %s", get.getMethod(), get.getURI())); + return httpClient.execute(get, ListResponseHandler.INSTANCE); } @@ -79,6 +89,8 @@ public boolean exists(@NonNull final String path) { final URI uri = new URIBuilder(backendServiceBackendApiUrl).setPath(path).build(); final HttpHead head = new HttpHead(uri); + log.debug(String.format("Send %-6s %s", head.getMethod(), head.getURI())); + return httpClient.execute(head, ExistsResponseHandler.INSTANCE); } @@ -89,6 +101,8 @@ public byte[] get(@NonNull final String path) { final HttpGet get = new HttpGet(uri); get.setHeader(HTTP_HEADER_ACCEPT, ContentType.APPLICATION_OCTET_STREAM.getMimeType()); + log.debug(String.format("Send %-6s %s", get.getMethod(), get.getURI())); + return httpClient.execute(get, GetResponseHandler.INSTANCE); } @@ -108,6 +122,8 @@ public void post( post.setEntity(entity); + log.debug(String.format("Send %-6s %s", post.getMethod(), post.getURI())); + httpClient.execute(post, PostResponseHandler.INSTANCE); } @@ -234,7 +250,7 @@ private static class ListResponseHandler extends GsonResponseHandler>() {}); // JVM type erasure: Keep generic args! + super(new TypeToken<>() {}); // JVM type erasure: Keep generic args! } } diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/BackendServiceSteps.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/BackendServiceSteps.java similarity index 90% rename from edc-tests/src/test/java/net/catenax/edc/tests/BackendServiceSteps.java rename to edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/BackendServiceSteps.java index 1d5ec62ca..05960ddf7 100644 --- a/edc-tests/src/test/java/net/catenax/edc/tests/BackendServiceSteps.java +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/BackendServiceSteps.java @@ -1,4 +1,4 @@ -package net.catenax.edc.tests; +package org.eclipse.tractusx.edc.tests; import io.cucumber.java.en.Given; diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/CatalogStepDefs.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/CatalogStepDefs.java similarity index 73% rename from edc-tests/src/test/java/net/catenax/edc/tests/CatalogStepDefs.java rename to edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/CatalogStepDefs.java index aa4468dbc..3bb8e9c5a 100644 --- a/edc-tests/src/test/java/net/catenax/edc/tests/CatalogStepDefs.java +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/CatalogStepDefs.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.tests; +package org.eclipse.tractusx.edc.tests; import io.cucumber.datatable.DataTable; import io.cucumber.java.en.Then; @@ -20,7 +26,7 @@ import java.io.IOException; import java.util.List; import java.util.Map; -import net.catenax.edc.tests.data.ContractOffer; +import org.eclipse.tractusx.edc.tests.data.ContractOffer; import org.junit.jupiter.api.Assertions; public class CatalogStepDefs { diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/Connector.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Connector.java similarity index 50% rename from edc-tests/src/test/java/net/catenax/edc/tests/Connector.java rename to edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Connector.java index 137f007cf..9ca1bcb19 100644 --- a/edc-tests/src/test/java/net/catenax/edc/tests/Connector.java +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Connector.java @@ -1,23 +1,30 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.tests; +package org.eclipse.tractusx.edc.tests; import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import net.catenax.edc.tests.util.DatabaseCleaner; +import org.eclipse.tractusx.edc.tests.util.DatabaseCleaner; +import org.eclipse.tractusx.edc.tests.util.S3Client; @RequiredArgsConstructor public class Connector { @@ -35,6 +42,9 @@ public class Connector { @Getter(lazy = true) private final DatabaseCleaner databaseCleaner = loadDatabaseCleaner(); + @Getter(lazy = true) + private final S3Client s3Client = createS3Client(); + private DataManagementAPI loadDataManagementAPI() { return new DataManagementAPI( environment.getDataManagementUrl(), environment.getDataManagementAuthKey()); @@ -50,4 +60,8 @@ private DatabaseCleaner loadDatabaseCleaner() { private BackendServiceBackendAPI loadBackendServiceBackendAPI() { return new BackendServiceBackendAPI(environment.getBackendServiceBackendApiUrl()); } + + private S3Client createS3Client() { + return new S3Client(environment); + } } diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ConnectorFactory.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ConnectorFactory.java new file mode 100644 index 000000000..7a8ef81a1 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ConnectorFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import lombok.NonNull; +import lombok.experimental.UtilityClass; + +@UtilityClass +public class ConnectorFactory { + private static final Map CONNECTOR_CACHE = new HashMap<>(); + + public static Connector byName(@NonNull final String name) { + return CONNECTOR_CACHE.computeIfAbsent( + name.toUpperCase(Locale.ROOT), k -> createConnector(name)); + } + + private static Connector createConnector(@NonNull final String name) { + final Environment environment = Environment.byName(name); + + return new Connector(name, environment); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ConnectorSteps.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ConnectorSteps.java new file mode 100644 index 000000000..cde597521 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ConnectorSteps.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import io.cucumber.java.en.Given; +import java.sql.SQLException; + +public class ConnectorSteps { + + @Given("'{connector}' has an empty database") + public void cleanDatabase(Connector connector) throws SQLException { + connector.getDatabaseCleaner().run(); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Constants.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Constants.java new file mode 100644 index 000000000..67b484e38 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Constants.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public final class Constants { + public static final String DATA_MANAGEMENT_URL = "DATA_MANAGEMENT_URL"; + public static final String DATA_MANAGEMENT_API_AUTH_KEY = "DATA_MANAGEMENT_API_AUTH_KEY"; + public static final String IDS_URL = "IDS_URL"; + public static final String DATA_PLANE_URL = "DATA_PLANE_URL"; + public static final String BACKEND_SERVICE_BACKEND_API_URL = "BACKEND_SERVICE_BACKEND_API_URL"; + public static final String DATABASE_URL = "DATABASE_URL"; + public static final String DATABASE_USER = "DATABASE_USER"; + public static final String DATABASE_PASSWORD = "DATABASE_PASSWORD"; + public static final String EDC_AWS_ENDPOINT_OVERRIDE = "EDC_AWS_ENDPOINT_OVERRIDE"; + public static final String AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"; + public static final String AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"; +} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/ContractDefinitionStepDefs.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ContractDefinitionStepDefs.java similarity index 54% rename from edc-tests/src/test/java/net/catenax/edc/tests/ContractDefinitionStepDefs.java rename to edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ContractDefinitionStepDefs.java index 11a097e68..634a845ff 100644 --- a/edc-tests/src/test/java/net/catenax/edc/tests/ContractDefinitionStepDefs.java +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ContractDefinitionStepDefs.java @@ -1,25 +1,31 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation + * 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 net.catenax.edc.tests; +package org.eclipse.tractusx.edc.tests; import io.cucumber.datatable.DataTable; import io.cucumber.java.en.Given; import java.util.ArrayList; import java.util.List; import java.util.Map; -import net.catenax.edc.tests.data.ContractDefinition; +import org.eclipse.tractusx.edc.tests.data.ContractDefinition; public class ContractDefinitionStepDefs { @@ -42,8 +48,11 @@ private List parseDataTable(DataTable table) { String assetId = map.get("asset"); List assetIds = assetId == null ? new ArrayList<>() : List.of(assetId); + String mapValidity = map.get("validity"); + Long validity = mapValidity == null ? null : Long.parseLong(mapValidity); + contractDefinitions.add( - new ContractDefinition(id, contractPolicyId, accessPolicyId, assetIds)); + new ContractDefinition(id, contractPolicyId, accessPolicyId, assetIds, validity)); } return contractDefinitions; diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ControlPlaneAdapterSteps.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ControlPlaneAdapterSteps.java new file mode 100644 index 000000000..d29a13aa4 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/ControlPlaneAdapterSteps.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023 ZF Friedrichshafen AG + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import com.google.gson.Gson; +import io.cucumber.datatable.DataTable; +import java.io.IOException; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClientBuilder; +import org.eclipse.edc.spi.system.health.HealthStatus; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.junit.jupiter.api.Assertions; + +@Slf4j +public class ControlPlaneAdapterSteps { + + private EndpointDataReference endpointDataReference; + + /* + * TODO: see of EndToEndTransfer.feature + * the current Bussinnes test is not running, because of a possible rare condition in the CI pipeline + * regarding the contract validity: see https://github.com/eclipse-edc/Connector/issues/2514 + */ + + // @When("'{connector}' gets a request endpoint from '{connector}'") + public void getEndPointFromGetRequest(Connector consumer, Connector receiver, DataTable table) + throws IOException { + + final DataManagementAPI dataManagementAPI = consumer.getDataManagementAPI(); + final String receiverIdsUrl = receiver.getEnvironment().getIdsUrl() + "/data"; + + for (Map map : table.asMaps()) { + final String assetId = map.get("asset id"); + + endpointDataReference = dataManagementAPI.getEdcEndpoint(assetId, receiverIdsUrl); + + log.debug("endpointDataReference in controlplane" + endpointDataReference.toString()); + } + } + + /* + * TODO: see EndToEndTransfer.feature + * the current Bussinnes test is not running, because of a possible rare condition in the CI pipeline + * regarding the contract validity: see https://github.com/eclipse-edc/Connector/issues/2514 + */ + + // @Then("'{connector}' asks for the asset from the endpoint") + public void receiveEndpoint(Connector consumer) throws IOException { + + var requestUrl = endpointDataReference.getEndpoint(); + var key = endpointDataReference.getAuthKey(); + var value = endpointDataReference.getAuthCode(); + var httpClient = HttpClientBuilder.create().build(); + var get = new HttpGet(requestUrl); + get.addHeader(key, value); + final CloseableHttpResponse response = httpClient.execute(get); + var bytes = response.getEntity().getContent().readAllBytes(); + var result = new String(bytes); + var resultTransformed = new Gson().fromJson(result, HealthStatus.class); + + Assertions.assertTrue(resultTransformed.isHealthy()); + Assertions.assertFalse(resultTransformed.getComponentResults().isEmpty()); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/DataManagementAPI.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/DataManagementAPI.java new file mode 100644 index 000000000..735cbf175 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/DataManagementAPI.java @@ -0,0 +1,672 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import com.google.gson.Gson; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.Data; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicHeader; +import org.eclipse.edc.spi.types.domain.edr.EndpointDataReference; +import org.eclipse.tractusx.edc.tests.data.*; + +@Slf4j +public class DataManagementAPI { + + private static final String ASSET_PATH = "/assets"; + private static final String POLICY_PATH = "/policydefinitions"; + private static final String CONTRACT_DEFINITIONS_PATH = "/contractdefinitions"; + private static final String CATALOG_PATH = "/catalog"; + private static final String NEGOTIATIONS_PATH = "/contractnegotiations"; + private static final String TRANSFER_PATH = "/transferprocess"; + private static final String ADAPTER_PATH = "/adapter/asset/sync/"; + + private final String dataMgmtUrl; + private final String dataMgmtAuthKey; + private final CloseableHttpClient httpClient; + + public DataManagementAPI(String dataManagementUrl, String dataMgmtAuthKey) { + this.httpClient = HttpClientBuilder.create().build(); + this.dataMgmtUrl = dataManagementUrl; + this.dataMgmtAuthKey = dataMgmtAuthKey; + } + + public List requestCatalogFrom(String receivingConnectorUrl) throws IOException { + final String encodedUrl = URLEncoder.encode(receivingConnectorUrl, StandardCharsets.UTF_8); + final ManagementApiContractOfferCatalog catalog = + get( + CATALOG_PATH, + "providerUrl=" + encodedUrl, + new TypeToken() {}); + + log.debug("Received " + catalog.contractOffers.size() + " offers"); + + return catalog.contractOffers.stream().map(this::mapOffer).collect(Collectors.toList()); + } + + public Negotiation initiateNegotiation( + String receivingConnectorUrl, String definitionId, String assetId, Policy policy) + throws IOException { + final ManagementApiOffer offer = new ManagementApiOffer(); + offer.offerId = definitionId + ":foo"; + offer.assetId = assetId; + offer.policy = mapPolicy(policy); + offer.policy.permissions.forEach(p -> p.target = assetId); + + final ManagementApiNegotiationPayload negotiationPayload = + new ManagementApiNegotiationPayload(); + negotiationPayload.connectorAddress = receivingConnectorUrl; + negotiationPayload.offer = offer; + + final ManagementApiNegotiationResponse response = + post( + NEGOTIATIONS_PATH, + negotiationPayload, + new TypeToken() {}); + + if (response == null) + throw new RuntimeException( + "Initiated negotiation. Connector did not answer with negotiation ID."); + + log.info(String.format("Initiated negotiation (id=%s)", response.getId())); + + final String negotiationId = response.getId(); + return new Negotiation(negotiationId); + } + + public Transfer initiateTransferProcess( + String receivingConnectorUrl, + String contractAgreementId, + String assetId, + DataAddress dataAddress) + throws IOException { + final ManagementApiTransfer transfer = new ManagementApiTransfer(); + + transfer.connectorAddress = receivingConnectorUrl; + transfer.contractId = contractAgreementId; + transfer.assetId = assetId; + transfer.transferType = new ManagementApiTransferType(); + transfer.managedResources = false; + transfer.dataDestination = mapDataAddress(dataAddress); + transfer.protocol = "ids-multipart"; + + return initiateTransferProcess(transfer); + } + + public Transfer initiateTransferProcess( + String receivingConnectorUrl, + String contractAgreementId, + String assetId, + DataAddress dataAddress, + String receiverEndpoint) + throws IOException { + final ManagementApiTransfer transfer = new ManagementApiTransfer(); + + transfer.connectorAddress = receivingConnectorUrl; + transfer.contractId = contractAgreementId; + transfer.assetId = assetId; + transfer.transferType = new ManagementApiTransferType(); + transfer.managedResources = false; + transfer.dataDestination = mapDataAddress(dataAddress); + transfer.protocol = "ids-multipart"; + transfer.properties = new ManagementApiProperties(receiverEndpoint); + + return initiateTransferProcess(transfer); + } + + private Transfer initiateTransferProcess(ManagementApiTransfer transfer) throws IOException { + final ManagementApiTransferResponse response = + post(TRANSFER_PATH, transfer, new TypeToken() {}); + + if (response == null) + throw new RuntimeException( + "Initiated transfer process. Connector did not answer with transfer process ID."); + + log.info(String.format("Initiated transfer process (id=%s)", response.getId())); + + final String transferId = response.getId(); + return new Transfer(transferId); + } + + public Asset initiateTransferProcess( + String endpointUrl, String endpointAuthKey, String endpointAuthCode) throws IOException { + Header header = new BasicHeader(endpointAuthKey, endpointAuthCode); + return get(endpointUrl, header, new TypeToken() {}); + } + + public TransferProcess getTransferProcess(String id) throws IOException { + final ManagementApiTransferProcess transferProcess = + get(TRANSFER_PATH + "/" + id, new TypeToken() {}); + return mapTransferProcess(transferProcess); + } + + public ContractNegotiation getNegotiation(String id) throws IOException { + final ManagementApiNegotiation negotiation = + get(NEGOTIATIONS_PATH + "/" + id, new TypeToken() {}); + return mapNegotiation(negotiation); + } + + public List getNegotiations() throws IOException { + final List negotiations = + get(NEGOTIATIONS_PATH + "/", new TypeToken>() {}); + return negotiations.stream().map(this::mapNegotiation).collect(Collectors.toList()); + } + + public void createAsset(Asset asset) throws IOException { + final ManagementApiAssetCreate assetCreate = new ManagementApiAssetCreate(); + + assetCreate.asset = mapAsset(asset); + assetCreate.dataAddress = mapDataAddress(asset.getDataAddress()); + + post(ASSET_PATH, assetCreate); + } + + public void createPolicy(Policy policy) throws IOException { + post(POLICY_PATH, mapPolicyDefinition(policy)); + } + + public void createContractDefinition(ContractDefinition contractDefinition) throws IOException { + post(CONTRACT_DEFINITIONS_PATH, mapContractDefinition(contractDefinition)); + } + + public EndpointDataReference getEdcEndpoint(String assetId, String receivingConnectorUrl) + throws IOException { + final String encodedUrl = ADAPTER_PATH + assetId + "?providerUrl=" + receivingConnectorUrl; + + final EndpointDataReference endpoint = + get(encodedUrl, new TypeToken() {}); + + return endpoint; + } + + private T get(String path, String params, TypeToken typeToken) throws IOException { + return get(path + "?" + params, typeToken); + } + + private T get(String path, TypeToken typeToken) throws IOException { + + final HttpGet get = new HttpGet(dataMgmtUrl + path); + final HttpResponse response = sendRequest(get); + final byte[] json = response.getEntity().getContent().readAllBytes(); + + log.debug("Received response: {}", new String(json, StandardCharsets.UTF_8)); + return new Gson().fromJson(new String(json, StandardCharsets.UTF_8), typeToken.getType()); + } + + private T get(String path, Header header, TypeToken typeToken) throws IOException { + + final HttpGet get = new HttpGet(path); + get.addHeader(header); + final HttpResponse response = sendRequest(get); + final byte[] json = response.getEntity().getContent().readAllBytes(); + + log.debug("Received response: {}", new String(json, StandardCharsets.UTF_8)); + return new Gson().fromJson(new String(json, StandardCharsets.UTF_8), typeToken.getType()); + } + + private void post(String path, Object object) throws IOException { + post(path, object, new TypeToken() {}); + } + + private T post(String path, Object object, TypeToken typeToken) throws IOException { + final String url = String.format("%s%s", dataMgmtUrl, path); + final HttpPost post = new HttpPost(url); + post.addHeader("Content-Type", "application/json"); + + var json = new Gson().toJson(object); + + log.debug("POST Payload: " + json); + + post.setEntity(new StringEntity(json)); + final CloseableHttpResponse response = sendRequest(post); + + T responseJson = null; + if (!typeToken.equals(new TypeToken() {})) { + final byte[] responseBytes = response.getEntity().getContent().readAllBytes(); + responseJson = + new Gson() + .fromJson(new String(responseBytes, StandardCharsets.UTF_8), typeToken.getType()); + } + + response.close(); + + return responseJson; + } + + private CloseableHttpResponse sendRequest(HttpRequestBase request) throws IOException { + request.addHeader("X-Api-Key", dataMgmtAuthKey); + + log.debug(String.format("Send %-6s %s", request.getMethod(), request.getURI())); + + final CloseableHttpResponse response = httpClient.execute(request); + if (200 > response.getStatusLine().getStatusCode() + || response.getStatusLine().getStatusCode() >= 300) { + throw new RuntimeException( + String.format("Unexpected response: %s", response.getStatusLine())); + } + + return response; + } + + private ContractNegotiation mapNegotiation(ManagementApiNegotiation negotiation) { + + ContractNegotiationState state; + + switch (negotiation.state) { + case "ERROR": + state = ContractNegotiationState.ERROR; + break; + case "INITIAL": + state = ContractNegotiationState.INITIAL; + break; + case "DECLINED": + state = ContractNegotiationState.DECLINED; + break; + case "CONFIRMED": + state = ContractNegotiationState.CONFIRMED; + break; + default: + state = ContractNegotiationState.UNKNOWN; + } + + return new ContractNegotiation(negotiation.id, negotiation.contractAgreementId, state); + } + + private TransferProcess mapTransferProcess(ManagementApiTransferProcess transferProcess) { + + TransferProcessState state; + + switch (transferProcess.state) { + case "COMPLETED": + state = TransferProcessState.COMPLETED; + break; + case "ERROR": + state = TransferProcessState.ERROR; + break; + default: + state = TransferProcessState.UNKNOWN; + } + + return new TransferProcess(transferProcess.id, state); + } + + private ManagementApiDataAddress mapDataAddress(@NonNull DataAddress dataAddress) { + final ManagementApiDataAddress apiObject = new ManagementApiDataAddress(); + + if (dataAddress instanceof HttpProxySourceDataAddress) { + final var address = (HttpProxySourceDataAddress) dataAddress; + var properties = new HashMap(); + properties.put("type", "HttpData"); + properties.put("baseUrl", address.getBaseUrl()); + var oauth2Provision = address.getOauth2Provision(); + if (oauth2Provision != null) { + properties.put("oauth2:tokenUrl", oauth2Provision.getTokenUrl()); + properties.put("oauth2:clientId", oauth2Provision.getClientId()); + properties.put("oauth2:clientSecret", oauth2Provision.getClientSecret()); + properties.put("oauth2:scope", oauth2Provision.getScope()); + } + apiObject.setProperties(properties); + } else if (dataAddress instanceof HttpProxySinkDataAddress) { + apiObject.setProperties(Map.of("type", "HttpProxy")); + } else if (dataAddress instanceof S3DataAddress) { + final S3DataAddress a = (S3DataAddress) dataAddress; + apiObject.setProperties( + Map.of( + "type", + "AmazonS3", + "bucketName", + a.getBucketName(), + "region", + a.getRegion(), + "keyName", + a.getKeyName())); + } else if (dataAddress instanceof NullDataAddress) { + // set something that passes validation + apiObject.setProperties(Map.of("type", "HttpData", "baseUrl", "http://localhost")); + } else { + throw new UnsupportedOperationException( + String.format( + "Cannot map data address of type %s to EDC domain", dataAddress.getClass())); + } + + return apiObject; + } + + private ManagementApiAsset mapAsset(Asset asset) { + final Map properties = + Map.of( + ManagementApiAsset.ID, asset.getId(), + ManagementApiAsset.DESCRIPTION, asset.getDescription()); + + final ManagementApiAsset apiObject = new ManagementApiAsset(); + apiObject.setProperties(properties); + return apiObject; + } + + private Policy mapPolicy(ManagementApiPolicy managementApiPolicy) { + final String id = managementApiPolicy.uid; + final List permissions = + managementApiPolicy.permissions.stream() + .map(this::mapPermission) + .collect(Collectors.toList()); + + return new Policy(id, permissions); + } + + private ManagementApiPolicy mapPolicy(Policy policy) { + final List permissions = + policy.getPermission().stream().map(this::mapPermission).collect(Collectors.toList()); + final ManagementApiPolicy managementApiPolicy = new ManagementApiPolicy(); + managementApiPolicy.permissions = permissions; + + return managementApiPolicy; + } + + private ManagementApiPolicyDefinition mapPolicyDefinition(Policy policy) { + final ManagementApiPolicyDefinition apiObject = new ManagementApiPolicyDefinition(); + apiObject.id = policy.getId(); + apiObject.policy = mapPolicy(policy); + return apiObject; + } + + private Permission mapPermission(ManagementApiPermission managementApiPermission) { + final String target = managementApiPermission.target; + final String action = managementApiPermission.action.type; + return new Permission(action, target, new ArrayList<>()); + } + + private ManagementApiPermission mapPermission(Permission permission) { + final String target = permission.getTarget(); + final String action = permission.getAction(); + + final ManagementApiRuleAction apiAction = new ManagementApiRuleAction(); + apiAction.type = action; + + var constraints = + permission.getConstraints().stream().map(this::mapConstraint).collect(Collectors.toList()); + + final ManagementApiPermission apiObject = new ManagementApiPermission(); + apiObject.target = target; + apiObject.action = apiAction; + apiObject.constraints = constraints; + return apiObject; + } + + private ManagementConstraint mapConstraint(Constraint constraint) { + if (OrConstraint.class.equals(constraint.getClass())) { + return mapConstraint((OrConstraint) constraint); + } else if (BusinessPartnerNumberConstraint.class.equals(constraint.getClass())) { + return mapConstraint((BusinessPartnerNumberConstraint) constraint); + } else if (PayMeConstraint.class.equals(constraint.getClass())) { + return mapConstraint((PayMeConstraint) constraint); + } else { + throw new UnsupportedOperationException( + "Unsupported constraint type: " + constraint.getClass().getName()); + } + } + + private ManagementAtomicConstraint mapConstraint(PayMeConstraint constraint) { + final ManagementApiLiteralExpression leftExpression = new ManagementApiLiteralExpression(); + leftExpression.value = "PayMe"; + + final ManagementApiLiteralExpression rightExpression = new ManagementApiLiteralExpression(); + rightExpression.value = String.valueOf(constraint.getAmount()); + + final ManagementAtomicConstraint dataManagementApiConstraint = new ManagementAtomicConstraint(); + dataManagementApiConstraint.leftExpression = leftExpression; + dataManagementApiConstraint.rightExpression = rightExpression; + dataManagementApiConstraint.operator = "EQ"; + + return dataManagementApiConstraint; + } + + private ManagementAtomicConstraint mapConstraint(BusinessPartnerNumberConstraint constraint) { + final ManagementApiLiteralExpression leftExpression = new ManagementApiLiteralExpression(); + leftExpression.value = "BusinessPartnerNumber"; + + final ManagementApiLiteralExpression rightExpression = new ManagementApiLiteralExpression(); + rightExpression.value = constraint.getBusinessPartnerNumber(); + + final ManagementAtomicConstraint dataManagementApiConstraint = new ManagementAtomicConstraint(); + dataManagementApiConstraint.leftExpression = leftExpression; + dataManagementApiConstraint.rightExpression = rightExpression; + dataManagementApiConstraint.operator = "EQ"; + + return dataManagementApiConstraint; + } + + private ManagementOrConstraint mapConstraint(OrConstraint constraint) { + var orConstraint = new ManagementOrConstraint(); + orConstraint.constraints = + constraint.getConstraints().stream().map(this::mapConstraint).collect(Collectors.toList()); + return orConstraint; + } + + private ContractOffer mapOffer(ManagementApiContractOffer managementApiContractOffer) { + final String id = managementApiContractOffer.id; + final String assetId = + managementApiContractOffer.assetId != null + ? managementApiContractOffer.assetId + : (String) managementApiContractOffer.asset.getProperties().get(ManagementApiAsset.ID); + + final Policy policy = mapPolicy(managementApiContractOffer.getPolicy()); + + return new ContractOffer(id, policy, assetId); + } + + private ManagementApiContractDefinition mapContractDefinition( + ContractDefinition contractDefinition) { + + final ManagementApiContractDefinition apiObject = new ManagementApiContractDefinition(); + apiObject.id = contractDefinition.getId(); + apiObject.accessPolicyId = contractDefinition.getAcccessPolicyId(); + apiObject.contractPolicyId = contractDefinition.getContractPolicyId(); + apiObject.criteria = new ArrayList<>(); + + for (final String assetId : contractDefinition.getAssetIds()) { + ManagementApiCriterion criterion = new ManagementApiCriterion(); + criterion.operandLeft = ManagementApiAsset.ID; + criterion.operator = "="; + criterion.operandRight = assetId; + + apiObject.criteria.add(criterion); + } + + return apiObject; + } + + @Data + private static class ManagementApiNegotiationResponse { + private String id; + } + + @Data + private static class ManagementApiNegotiationPayload { + private String connectorId = "foo"; + private String connectorAddress; + private ManagementApiOffer offer; + } + + @Data + private static class ManagementApiNegotiation { + private String id; + private String state; + private String contractAgreementId; + } + + @Data + private static class ManagementApiTransferProcess { + private String id; + private String state; + } + + @Data + private static class ManagementApiOffer { + private String offerId; + private String assetId; + private ManagementApiPolicy policy; + } + + @Data + private static class ManagementApiTransfer { + private String connectorId = "foo"; + private String connectorAddress; + private String contractId; + private String assetId; + private String protocol; + private ManagementApiDataAddress dataDestination; + private boolean managedResources; + private ManagementApiTransferType transferType; + private ManagementApiProperties properties; + } + + @Data + private static class ManagementApiTransferType { + private String contentType = "application/octet-stream"; + private boolean isFinite = true; + } + + @Data + private static class ManagementApiTransferResponse { + private String id; + } + + @Data + private static class ManagementApiAssetCreate { + private ManagementApiAsset asset; + private ManagementApiDataAddress dataAddress; + } + + @Data + private static class ManagementApiAsset { + public static final String ID = "asset:prop:id"; + public static final String DESCRIPTION = "asset:prop:description"; + + private Map properties; + } + + @Data + private static class ManagementApiDataAddress { + public static final String TYPE = "type"; + private Map properties; + } + + @Data + private static class ManagementApiProperties { + @SerializedName(value = "receiver.http.endpoint") + private final String receiverHttpEndpoint; + } + + @Data + private static class ManagementApiPolicyDefinition { + private String id; + private ManagementApiPolicy policy; + } + + @Data + private static class ManagementApiPolicy { + private String uid; + private List permissions = new ArrayList<>(); + } + + @Data + private static class ManagementApiPermission { + private String edctype = "dataspaceconnector:permission"; + private ManagementApiRuleAction action; + private String target; + private List constraints = new ArrayList<>(); + } + + @Data + private static class ManagementAtomicConstraint implements ManagementConstraint { + private String edctype = "AtomicConstraint"; + private ManagementApiLiteralExpression leftExpression; + private ManagementApiLiteralExpression rightExpression; + private String operator; + } + + @Data + private static class ManagementOrConstraint implements ManagementConstraint { + private String edctype = "dataspaceconnector:orconstraint"; + private List constraints; + } + + private interface ManagementConstraint {} + + @Data + private static class ManagementApiLiteralExpression { + private String edctype = "dataspaceconnector:literalexpression"; + private String value; + } + + @Data + private static class ManagementApiRuleAction { + private String type; + } + + @Data + private static class ManagementApiContractDefinition { + private String id; + private String accessPolicyId; + private String contractPolicyId; + private List criteria = new ArrayList<>(); + } + + @Data + private static class ManagementApiCriterion { + private Object operandLeft; + private String operator; + private Object operandRight; + } + + @Data + private static class ManagementApiContractOffer { + private String id; + private ManagementApiPolicy policy; + private ManagementApiAsset asset; + private String assetId; + } + + @Data + private static class ManagementApiContractOfferCatalog { + private String id; + private List contractOffers = new ArrayList<>(); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Environment.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Environment.java new file mode 100644 index 000000000..d1a199fd1 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/Environment.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import static org.eclipse.tractusx.edc.tests.Constants.AWS_ACCESS_KEY_ID; +import static org.eclipse.tractusx.edc.tests.Constants.AWS_SECRET_ACCESS_KEY; +import static org.eclipse.tractusx.edc.tests.Constants.BACKEND_SERVICE_BACKEND_API_URL; +import static org.eclipse.tractusx.edc.tests.Constants.DATABASE_PASSWORD; +import static org.eclipse.tractusx.edc.tests.Constants.DATABASE_URL; +import static org.eclipse.tractusx.edc.tests.Constants.DATABASE_USER; +import static org.eclipse.tractusx.edc.tests.Constants.DATA_MANAGEMENT_API_AUTH_KEY; +import static org.eclipse.tractusx.edc.tests.Constants.DATA_MANAGEMENT_URL; +import static org.eclipse.tractusx.edc.tests.Constants.DATA_PLANE_URL; +import static org.eclipse.tractusx.edc.tests.Constants.EDC_AWS_ENDPOINT_OVERRIDE; +import static org.eclipse.tractusx.edc.tests.Constants.IDS_URL; + +import java.util.Locale; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NonNull; +import lombok.ToString; + +@Builder(access = AccessLevel.PRIVATE) +@Getter +@ToString +public class Environment { + @NonNull private final String dataManagementAuthKey; + @NonNull private final String dataManagementUrl; + @NonNull private final String idsUrl; + @NonNull private final String dataPlaneUrl; + @NonNull private final String backendServiceBackendApiUrl; + @NonNull private final String databaseUrl; + @NonNull private final String databaseUser; + @NonNull private final String databasePassword; + @NonNull private final String awsEndpointOverride; + @NonNull private final String awsAccessKey; + @NonNull private final String awsSecretAccessKey; + + public static Environment byName(String name) { + name = name.toUpperCase(Locale.ROOT); + + return Environment.builder() + .dataManagementUrl(System.getenv(String.join("_", name, DATA_MANAGEMENT_URL))) + .dataManagementAuthKey(System.getenv(String.join("_", name, DATA_MANAGEMENT_API_AUTH_KEY))) + .idsUrl(System.getenv(String.join("_", name, IDS_URL))) + .dataPlaneUrl(System.getenv(String.join("_", name, DATA_PLANE_URL))) + .backendServiceBackendApiUrl( + System.getenv(String.join("_", name, BACKEND_SERVICE_BACKEND_API_URL))) + .databaseUrl(System.getenv(String.join("_", name, DATABASE_URL))) + .databaseUser(System.getenv(String.join("_", name, DATABASE_USER))) + .databasePassword(System.getenv(String.join("_", name, DATABASE_PASSWORD))) + .awsEndpointOverride(System.getenv(EDC_AWS_ENDPOINT_OVERRIDE)) + .awsAccessKey(System.getenv(String.join("_", name, AWS_ACCESS_KEY_ID))) + .awsSecretAccessKey(System.getenv(String.join("_", name, AWS_SECRET_ACCESS_KEY))) + .build(); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/HttpProxyTransferSteps.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/HttpProxyTransferSteps.java new file mode 100644 index 000000000..c0ae99a48 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/HttpProxyTransferSteps.java @@ -0,0 +1,99 @@ +package org.eclipse.tractusx.edc.tests; + +import io.cucumber.datatable.DataTable; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import java.io.IOException; +import java.time.Duration; +import java.util.Arrays; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.awaitility.Awaitility; +import org.eclipse.tractusx.edc.tests.data.*; +import org.junit.jupiter.api.Assertions; + +import static org.awaitility.Awaitility.await; + +@Slf4j +public class HttpProxyTransferSteps { + + private static final String ID = "id"; + private static final String DESCRIPTION = "description"; + private static final String BASE_URL = "baseUrl"; + private static final String ASSET_ID = "asset id"; + private static final String RECEIVER_HTTP_ENDPOINT = "receiverHttpEndpoint"; + + @Given("'{connector}' has a http proxy assets") + public void hasAssets(Connector connector, DataTable table) throws Exception { + final DataManagementAPI api = connector.getDataManagementAPI(); + + for (var map : table.asMaps()) { + final String id = map.get(ID); + final String description = map.get(DESCRIPTION); + final String baseUrl = map.get(BASE_URL); + + var oauth2Provision = + Arrays.stream(Oauth2DataAddressFields.values()) + .map(it -> it.text) + .anyMatch(map::containsKey) + ? new HttpProxySourceDataAddress.Oauth2Provision( + map.get(Oauth2DataAddressFields.TOKEN_URL.text), + map.get(Oauth2DataAddressFields.CLIENT_ID.text), + map.get(Oauth2DataAddressFields.CLIENT_SECRET.text), + map.get(Oauth2DataAddressFields.SCOPE.text)) + : null; + + final DataAddress address = new HttpProxySourceDataAddress(baseUrl, oauth2Provision); + final Asset asset = new Asset(id, description, address); + + api.createAsset(asset); + } + } + + @When("'{connector}' initiates HttpProxy transfer from '{connector}'") + public void sokratesInitiateHttpProxyTransferProcessFromPlato( + Connector consumer, Connector provider, DataTable dataTable) throws IOException { + final DataManagementAPI api = consumer.getDataManagementAPI(); + final String receiverUrl = provider.getEnvironment().getIdsUrl() + "/data"; + + final List negotiation = api.getNegotiations(); + final String agreementId = negotiation.get(0).getAgreementId(); + final DataAddress dataAddress = new HttpProxySinkDataAddress(); + + for (var map : dataTable.asMaps()) { + final String assetId = map.get(ASSET_ID); + final String receiverHttpEndpoint = map.get(RECEIVER_HTTP_ENDPOINT); + final Transfer transfer = + api.initiateTransferProcess( + receiverUrl, agreementId, assetId, dataAddress, receiverHttpEndpoint); + + transfer.waitUntilComplete(api); + } + } + + @Then("the backend application of '{connector}' has received data") + public void theBackendApplicationOfSocratesHasReceivedData(Connector consumer) { + final BackendServiceBackendAPI api = consumer.getBackendServiceBackendAPI(); + await() + .atMost(Duration.ofSeconds(20)) + .pollInterval(Duration.ofSeconds(1)) + .untilAsserted(() ->{ + final List transferredData = api.list("/"); + Assertions.assertNotEquals(0, transferredData.size()); + }); + } + + private enum Oauth2DataAddressFields { + TOKEN_URL("oauth2 token url"), + CLIENT_ID("oauth2 client id"), + CLIENT_SECRET("oauth2 client secret"), + SCOPE("oauth2 scope"); + + private final String text; + + Oauth2DataAddressFields(String text) { + this.text = text; + } + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/NegotiationSteps.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/NegotiationSteps.java new file mode 100644 index 000000000..5872d2dfe --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/NegotiationSteps.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import io.cucumber.datatable.DataTable; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.edc.tests.data.ContractNegotiation; +import org.eclipse.tractusx.edc.tests.data.ContractNegotiationState; +import org.eclipse.tractusx.edc.tests.data.Negotiation; +import org.eclipse.tractusx.edc.tests.data.Permission; +import org.eclipse.tractusx.edc.tests.data.Policy; +import org.junit.jupiter.api.Assertions; + +@Slf4j +public class NegotiationSteps { + + private static final String DEFINITION_ID = "definition id"; + private static final String ASSET_ID = "asset id"; + + private ContractNegotiation lastInitiatedNegotiation; + + @When("'{connector}' sends '{connector}' an offer without constraints") + public void sendAnOfferWithoutConstraints(Connector sender, Connector receiver, DataTable table) + throws IOException { + + final DataManagementAPI dataManagementAPI = sender.getDataManagementAPI(); + final String receiverIdsUrl = receiver.getEnvironment().getIdsUrl() + "/data"; + + for (Map map : table.asMaps()) { + final String definitionId = map.get(DEFINITION_ID); + final String assetId = map.get(ASSET_ID); + + final Permission permission = new Permission("USE", null, new ArrayList<>()); + final Policy policy = new Policy("foo", List.of(permission)); + + final Negotiation negotiation = + dataManagementAPI.initiateNegotiation(receiverIdsUrl, definitionId, assetId, policy); + + // wait for negotiation to complete + negotiation.waitUntilComplete(dataManagementAPI); + + lastInitiatedNegotiation = dataManagementAPI.getNegotiation(negotiation.getId()); + } + } + + @When("'{connector}' successfully negotiation a contract agreement with '{connector}'") + public void sokratesSuccessfullyNegotiationAContractAgreementPlatoFor( + Connector consumer, Connector provider, DataTable table) throws IOException { + final DataManagementAPI api = consumer.getDataManagementAPI(); + + final Map map = table.asMap(); + final String definitionId = map.get(DEFINITION_ID); + final String assetId = map.get(ASSET_ID); + + // as default always the "allow all" policy is used. So we can assume this here, too. + final Permission permission = new Permission("USE", null, new ArrayList<>()); + final Policy policy = new Policy("policy-id", List.of(permission)); + + final String receiverUrl = provider.getEnvironment().getIdsUrl(); + final Negotiation negotiation = + api.initiateNegotiation(receiverUrl, assetId, definitionId, policy); + + negotiation.waitUntilComplete(api); + } + + @Then("the negotiation is declined") + public void assertLastNegotiationDeclined() { + Assertions.assertEquals(ContractNegotiationState.DECLINED, lastInitiatedNegotiation.getState()); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/PolicyStepDefs.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/PolicyStepDefs.java new file mode 100644 index 000000000..a7ede22be --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/PolicyStepDefs.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toList; + +import io.cucumber.datatable.DataTable; +import io.cucumber.java.en.Given; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.eclipse.tractusx.edc.tests.data.*; + +public class PolicyStepDefs { + + @Given("'{connector}' has the following policies") + public void hasPolicies(Connector connector, DataTable table) throws Exception { + var api = connector.getDataManagementAPI(); + var policies = table.asMaps().stream().map(this::parseRow).collect(toList()); + + for (var policy : policies) api.createPolicy(policy); + } + + private Policy parseRow(Map row) { + var id = row.get("id"); + var action = row.get("action"); + var constraints = new ArrayList(); + + var businessPartnerNumber = row.get("businessPartnerNumber"); + if (businessPartnerNumber != null && !businessPartnerNumber.isBlank()) { + var bpnConstraints = + stream(businessPartnerNumber.split(",")) + .map(BusinessPartnerNumberConstraint::new) + .collect(toList()); + constraints.add(new OrConstraint(bpnConstraints)); + } + + var payMe = row.get("payMe"); + if (payMe != null && !payMe.isBlank()) + constraints.add(new PayMeConstraint(Double.parseDouble(payMe))); + + var permission = new Permission(action, null, constraints); + return new Policy(id, List.of(permission)); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/S3FileTransferStepsDefs.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/S3FileTransferStepsDefs.java new file mode 100644 index 000000000..c4bc85a27 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/S3FileTransferStepsDefs.java @@ -0,0 +1,179 @@ +/* Copyright (c) 2022 ZF Friedrichshafen AG + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.fail; + +import io.cucumber.datatable.DataTable; +import io.cucumber.java.AfterAll; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.eclipse.tractusx.edc.tests.data.Asset; +import org.eclipse.tractusx.edc.tests.data.DataAddress; +import org.eclipse.tractusx.edc.tests.data.Negotiation; +import org.eclipse.tractusx.edc.tests.data.Permission; +import org.eclipse.tractusx.edc.tests.data.Policy; +import org.eclipse.tractusx.edc.tests.data.S3DataAddress; +import org.eclipse.tractusx.edc.tests.data.Transfer; +import org.eclipse.tractusx.edc.tests.util.S3Client; +import org.eclipse.tractusx.edc.tests.util.Timeouts; +import org.junit.jupiter.api.Assertions; + +public class S3FileTransferStepsDefs { + + @Given("'{connector}' has an empty storage bucket called {string}") + public void hasEmptyStorageBucket(Connector connector, String bucketName) { + S3Client s3 = connector.getS3Client(); + + s3.createBucket(bucketName); + + Assertions.assertTrue(s3.listBuckets().contains(bucketName)); + Assertions.assertEquals(0, s3.listBucketContent(bucketName).size()); + } + + private File fileToTransfer; + + @Given("'{connector}' has a storage bucket called {string} with the file called {string}") + public void hasAStorageBucketWithTheFile(Connector connector, String bucketName, String fileName) + throws IOException { + + S3Client s3 = connector.getS3Client(); + s3.createBucket(bucketName); + fileToTransfer = s3.uploadFile(bucketName, fileName); + + Set bucketContent = s3.listBucketContent(bucketName); + + Assertions.assertEquals(1, bucketContent.size()); + Assertions.assertTrue(bucketContent.contains(fileName)); + } + + @Given("'{connector}' has the following S3 assets") + public void hasAssets(Connector connector, DataTable table) { + final DataManagementAPI api = connector.getDataManagementAPI(); + + parseDataTable(table) + .forEach( + asset -> { + try { + api.createAsset(asset); + } catch (IOException e) { + fail(e.getMessage()); + } + }); + } + + private String assetId; + private String agreementId; + + @Then("'{connector}' negotiates the contract successfully with '{connector}'") + public void negotiateContract(Connector sender, Connector receiver, DataTable dataTable) + throws IOException { + + String definitionId = dataTable.asMaps().get(0).get("contract offer id"); + assetId = dataTable.asMaps().get(0).get("asset id"); + String policyId = dataTable.asMaps().get(0).get("policy id"); + + final Policy policy = + new Policy(policyId, List.of(new Permission("USE", null, new ArrayList<>()))); + + final DataManagementAPI dataManagementAPI = sender.getDataManagementAPI(); + final String receiverIdsUrl = receiver.getEnvironment().getIdsUrl() + "/data"; + + final Negotiation negotiation = + dataManagementAPI.initiateNegotiation(receiverIdsUrl, definitionId, assetId, policy); + negotiation.waitUntilComplete(dataManagementAPI); + + agreementId = dataManagementAPI.getNegotiation(negotiation.getId()).getAgreementId(); + } + + @Then("'{connector}' initiate S3 transfer process from '{connector}'") + public void initiateTransferProcess(Connector sender, Connector receiver, DataTable dataTable) + throws IOException { + DataAddress dataAddress = createDataAddress(dataTable.asMaps().get(0)); + + final DataManagementAPI dataManagementAPI = sender.getDataManagementAPI(); + final String receiverIdsUrl = receiver.getEnvironment().getIdsUrl() + "/data"; + + final Transfer transferProcess = + dataManagementAPI.initiateTransferProcess( + receiverIdsUrl, agreementId, assetId, dataAddress); + transferProcess.waitUntilComplete(dataManagementAPI); + + Assertions.assertNotNull(transferProcess.getId()); + } + + private static final String COMPLETION_MARKER = ".complete"; + + @Then("'{connector}' has a storage bucket called {string} with transferred file called {string}") + public void consumerHasAStorageBucketWithFileTransferred( + Connector connector, String bucketName, String fileName) throws IOException { + S3Client s3 = connector.getS3Client(); + await() + .pollDelay(Duration.ofMillis(500)) + .atMost(Timeouts.FILE_TRANSFER) + .until(() -> isFilePresent(s3, bucketName, fileName + COMPLETION_MARKER)); + + Set bucketContent = s3.listBucketContent(bucketName); + + Assertions.assertEquals(2, bucketContent.size()); + Assertions.assertTrue(bucketContent.contains(fileName)); + Assertions.assertArrayEquals( + Files.readAllBytes(fileToTransfer.toPath()), + Files.readAllBytes(s3.downloadFile(bucketName, fileName).toPath())); + } + + private boolean isFilePresent(S3Client s3, String bucketName, String fileName) { + return s3.listBucketContent(bucketName).contains(fileName); + } + + private List parseDataTable(DataTable table) { + final List assetsWithDataAddresses = new ArrayList<>(); + + for (Map map : table.asMaps()) { + String id = map.get("id"); + String description = map.get("description"); + assetsWithDataAddresses.add(new Asset(id, description, createDataAddress(map))); + } + + return assetsWithDataAddresses; + } + + private DataAddress createDataAddress(Map map) { + final String bucketName = map.get("data_address_s3_bucket_name"); + final String region = map.get("data_address_s3_region"); + final String keyName = map.get("data_address_s3_key_name"); + return new S3DataAddress(bucketName, region, keyName); + } + + @AfterAll + public static void bucketsCleanup() { + S3Client s3 = new S3Client(Environment.byName("Sokrates")); + s3.deleteAllBuckets(); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Asset.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Asset.java new file mode 100644 index 000000000..acccef8d8 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Asset.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.eclipse.tractusx.edc.tests.data; + +import lombok.NonNull; +import lombok.Value; + +@Value +public class Asset { + @NonNull String Id; + + @NonNull String description; + + @NonNull DataAddress dataAddress; +} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/data/BusinessPartnerNumberConstraint.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/BusinessPartnerNumberConstraint.java similarity index 78% rename from edc-tests/src/test/java/net/catenax/edc/tests/data/BusinessPartnerNumberConstraint.java rename to edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/BusinessPartnerNumberConstraint.java index d7cee2be9..b9c64d158 100644 --- a/edc-tests/src/test/java/net/catenax/edc/tests/data/BusinessPartnerNumberConstraint.java +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/BusinessPartnerNumberConstraint.java @@ -1,4 +1,4 @@ -package net.catenax.edc.tests.data; +package org.eclipse.tractusx.edc.tests.data; import lombok.NonNull; import lombok.Value; diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Constraint.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Constraint.java new file mode 100644 index 000000000..c63fbed8a --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Constraint.java @@ -0,0 +1,3 @@ +package org.eclipse.tractusx.edc.tests.data; + +public interface Constraint {} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractDefinition.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractDefinition.java new file mode 100644 index 000000000..a9fca04a1 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractDefinition.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.eclipse.tractusx.edc.tests.data; + +import java.util.List; +import lombok.NonNull; +import lombok.Value; + +@Value +public class ContractDefinition { + + @NonNull String id; + + @NonNull String contractPolicyId; + @NonNull String acccessPolicyId; + + List assetIds; + Long validity; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractNegotiation.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractNegotiation.java new file mode 100644 index 000000000..109249744 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractNegotiation.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.data; + +import lombok.NonNull; +import lombok.Value; + +@Value +public class ContractNegotiation { + @NonNull String id; + String agreementId; + @NonNull ContractNegotiationState state; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractNegotiationState.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractNegotiationState.java new file mode 100644 index 000000000..9acd4368f --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractNegotiationState.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.data; + +public enum ContractNegotiationState { + UNKNOWN, + INITIAL, + DECLINED, + CONFIRMED, + ERROR +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractOffer.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractOffer.java new file mode 100644 index 000000000..75dfd8d27 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/ContractOffer.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.eclipse.tractusx.edc.tests.data; + +import lombok.NonNull; +import lombok.Value; + +@Value +public class ContractOffer { + @NonNull String id; + Policy policy; + String assetId; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/DataAddress.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/DataAddress.java new file mode 100644 index 000000000..16815827f --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/DataAddress.java @@ -0,0 +1,22 @@ +/* Copyright (c) 2022 ZF Friedrichshafen AG + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.data; + +public interface DataAddress {} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/HttpProxySinkDataAddress.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/HttpProxySinkDataAddress.java new file mode 100644 index 000000000..503701e24 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/HttpProxySinkDataAddress.java @@ -0,0 +1,3 @@ +package org.eclipse.tractusx.edc.tests.data; + +public class HttpProxySinkDataAddress implements DataAddress {} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/HttpProxySourceDataAddress.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/HttpProxySourceDataAddress.java new file mode 100644 index 000000000..4a5946cc9 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/HttpProxySourceDataAddress.java @@ -0,0 +1,18 @@ +package org.eclipse.tractusx.edc.tests.data; + +import lombok.NonNull; +import lombok.Value; + +@Value +public class HttpProxySourceDataAddress implements DataAddress { + @NonNull String baseUrl; + Oauth2Provision oauth2Provision; + + @Value + public static class Oauth2Provision { + @NonNull String tokenUrl; + @NonNull String clientId; + @NonNull String clientSecret; + String scope; + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Negotiation.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Negotiation.java new file mode 100644 index 000000000..40845e4c0 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Negotiation.java @@ -0,0 +1,34 @@ +package org.eclipse.tractusx.edc.tests.data; + +import static org.awaitility.Awaitility.await; + +import groovyjarjarantlr4.v4.runtime.misc.NotNull; +import java.io.IOException; +import java.time.Duration; +import java.util.stream.Stream; +import lombok.Value; +import org.eclipse.tractusx.edc.tests.DataManagementAPI; +import org.eclipse.tractusx.edc.tests.util.Timeouts; + +@Value +public class Negotiation { + + @NotNull String id; + + public void waitUntilComplete(DataManagementAPI dataManagementAPI) { + await() + .pollDelay(Duration.ofMillis(2000)) + .atMost(Timeouts.CONTRACT_NEGOTIATION) + .until(() -> isComplete(dataManagementAPI)); + } + + public boolean isComplete(DataManagementAPI dataManagementAPI) throws IOException { + var negotiation = dataManagementAPI.getNegotiation(id); + return negotiation != null + && Stream.of( + ContractNegotiationState.ERROR, + ContractNegotiationState.CONFIRMED, + ContractNegotiationState.DECLINED) + .anyMatch((l) -> l.equals(negotiation.getState())); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/NullDataAddress.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/NullDataAddress.java new file mode 100644 index 000000000..778600b86 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/NullDataAddress.java @@ -0,0 +1,10 @@ +package org.eclipse.tractusx.edc.tests.data; + +public class NullDataAddress implements DataAddress { + + private static final NullDataAddress _instance = new NullDataAddress(); + + public static DataAddress INSTANCE = new NullDataAddress(); + + private NullDataAddress() {} +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/OrConstraint.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/OrConstraint.java new file mode 100644 index 000000000..88bf3438d --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/OrConstraint.java @@ -0,0 +1,11 @@ +package org.eclipse.tractusx.edc.tests.data; + +import java.util.List; +import lombok.NonNull; +import lombok.Value; + +@Value +public class OrConstraint implements Constraint { + + @NonNull List constraints; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/PayMeConstraint.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/PayMeConstraint.java new file mode 100644 index 000000000..4376346b2 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/PayMeConstraint.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.data; + +import lombok.Value; + +/** + * The PayMe constraint should be used when no constraint validation/enforcement in the EDC is + * intended. + */ +@Value +public class PayMeConstraint implements Constraint { + double amount; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Permission.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Permission.java new file mode 100644 index 000000000..128e6686f --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Permission.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.eclipse.tractusx.edc.tests.data; + +import java.util.List; +import lombok.NonNull; +import lombok.Value; + +@Value +public class Permission { + @NonNull String action; + String target; + + @NonNull List constraints; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Policy.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Policy.java new file mode 100644 index 000000000..27ea65d7a --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Policy.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.data; + +import java.util.List; +import lombok.NonNull; +import lombok.Value; + +@Value +public class Policy { + String id; + @NonNull List Permission; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/S3DataAddress.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/S3DataAddress.java new file mode 100644 index 000000000..a59843447 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/S3DataAddress.java @@ -0,0 +1,12 @@ +package org.eclipse.tractusx.edc.tests.data; + +import lombok.NonNull; +import lombok.Value; + +@Value +public class S3DataAddress implements DataAddress { + + @NonNull String bucketName; + @NonNull String region; + @NonNull String keyName; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Transfer.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Transfer.java new file mode 100644 index 000000000..ebd722d07 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/Transfer.java @@ -0,0 +1,31 @@ +package org.eclipse.tractusx.edc.tests.data; + +import static org.awaitility.Awaitility.await; + +import java.io.IOException; +import java.time.Duration; +import lombok.Value; +import org.eclipse.tractusx.edc.tests.DataManagementAPI; +import org.eclipse.tractusx.edc.tests.util.Timeouts; + +@Value +public class Transfer { + + String id; + + public void waitUntilComplete(DataManagementAPI dataManagementAPI) { + await() + .pollDelay(Duration.ofMillis(2000)) + .atMost(Timeouts.FILE_TRANSFER) + .until(() -> isComplete(dataManagementAPI)); + } + + public boolean isComplete(DataManagementAPI dataManagementAPI) throws IOException { + var transferProcess = dataManagementAPI.getTransferProcess(id); + if (transferProcess == null) return false; + + var state = transferProcess.getState(); + + return state == TransferProcessState.COMPLETED || state == TransferProcessState.ERROR; + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/TransferProcess.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/TransferProcess.java new file mode 100644 index 000000000..28be5157a --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/TransferProcess.java @@ -0,0 +1,29 @@ +/* Copyright (c) 2022 ZF Friedrichshafen AG + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.data; + +import lombok.NonNull; +import lombok.Value; + +@Value +public class TransferProcess { + @NonNull String id; + @NonNull TransferProcessState state; +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/TransferProcessState.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/TransferProcessState.java new file mode 100644 index 000000000..4f5612334 --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/data/TransferProcessState.java @@ -0,0 +1,26 @@ +/* Copyright (c) 2022 ZF Friedrichshafen AG + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.data; + +public enum TransferProcessState { + COMPLETED, + ERROR, + UNKNOWN +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/features/ParameterTypes.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/features/ParameterTypes.java new file mode 100644 index 000000000..c353ec2fb --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/features/ParameterTypes.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.features; + +import io.cucumber.java.ParameterType; +import org.eclipse.tractusx.edc.tests.Connector; +import org.eclipse.tractusx.edc.tests.ConnectorFactory; + +public class ParameterTypes { + + @ParameterType("Plato|Sokrates") + public Connector connector(String name) { + return ConnectorFactory.byName(name); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/features/RunCucumberTest.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/features/RunCucumberTest.java new file mode 100644 index 000000000..d9ab3254c --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/features/RunCucumberTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.features; + +import org.junit.platform.suite.api.SelectClasspathResource; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectClasspathResource("org/eclipse/tractusx/edc/tests/features") +public class RunCucumberTest {} diff --git a/edc-tests/src/test/java/net/catenax/edc/tests/util/DatabaseCleaner.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/DatabaseCleaner.java similarity index 51% rename from edc-tests/src/test/java/net/catenax/edc/tests/util/DatabaseCleaner.java rename to edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/DatabaseCleaner.java index 530278e75..53aececa9 100644 --- a/edc-tests/src/test/java/net/catenax/edc/tests/util/DatabaseCleaner.java +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/DatabaseCleaner.java @@ -1,18 +1,24 @@ /* - * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation * - * 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 + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. * - * SPDX-License-Identifier: Apache-2.0 + * 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 * - * Contributors: - * Mercedes-Benz Tech Innovation GmbH - Initial Implementation + * 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 net.catenax.edc.tests.util; +package org.eclipse.tractusx.edc.tests.util; import java.sql.Connection; import java.sql.DriverManager; diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/S3Client.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/S3Client.java new file mode 100644 index 000000000..c2779ce0d --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/S3Client.java @@ -0,0 +1,124 @@ +/* Copyright (c) 2022 ZF Friedrichshafen AG + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.util; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.edc.tests.Environment; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.core.ResponseBytes; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.model.Bucket; +import software.amazon.awssdk.services.s3.model.BucketAlreadyOwnedByYouException; +import software.amazon.awssdk.services.s3.model.CreateBucketRequest; +import software.amazon.awssdk.services.s3.model.DeleteBucketRequest; +import software.amazon.awssdk.services.s3.model.DeleteObjectRequest; +import software.amazon.awssdk.services.s3.model.GetObjectRequest; +import software.amazon.awssdk.services.s3.model.GetObjectResponse; +import software.amazon.awssdk.services.s3.model.ListObjectsRequest; +import software.amazon.awssdk.services.s3.model.PutObjectRequest; +import software.amazon.awssdk.services.s3.model.S3Object; + +@Slf4j +public class S3Client { + + private final software.amazon.awssdk.services.s3.S3Client s3; + + public S3Client(Environment environment) { + + s3 = + software.amazon.awssdk.services.s3.S3Client.builder() + .region(Region.US_EAST_1) + .forcePathStyle(true) + .endpointOverride(URI.create(environment.getAwsEndpointOverride())) + .credentialsProvider( + StaticCredentialsProvider.create( + AwsBasicCredentials.create( + environment.getAwsAccessKey(), environment.getAwsSecretAccessKey()))) + .build(); + } + + public void createBucket(String bucketName) { + try { + s3.createBucket(CreateBucketRequest.builder().bucket(bucketName).build()); + } catch (BucketAlreadyOwnedByYouException e) { + log.info("'{}' bucket already owned - skipped bucket creation", bucketName); + } + } + + public File uploadFile(String bucketName, String fileName) throws IOException { + File tempFile = File.createTempFile(fileName, null); + Files.write( + tempFile.toPath(), "Will fail if the file has no content".getBytes(StandardCharsets.UTF_8)); + + s3.putObject( + PutObjectRequest.builder().bucket(bucketName).key(fileName).build(), + RequestBody.fromFile(tempFile)); + + return tempFile; + } + + public List listBuckets() { + return s3.listBuckets().buckets().stream().map(Bucket::name).collect(Collectors.toList()); + } + + public Set listBucketContent(String bucketName) { + return s3 + .listObjects(ListObjectsRequest.builder().bucket(bucketName).build()) + .contents() + .stream() + .map(S3Object::key) + .collect(Collectors.toSet()); + } + + public File downloadFile(String bucketName, String fileName) throws IOException { + ResponseBytes objectAsBytes = + s3.getObjectAsBytes(GetObjectRequest.builder().bucket(bucketName).key(fileName).build()); + + return Files.write(File.createTempFile(fileName, null).toPath(), objectAsBytes.asByteArray()) + .toFile(); + } + + public void deleteAllBuckets() { + List buckets = s3.listBuckets().buckets(); + buckets.forEach(this::clearBucket); + buckets.forEach( + bucket -> s3.deleteBucket(DeleteBucketRequest.builder().bucket(bucket.name()).build())); + } + + private void clearBucket(Bucket bucket) { + String bucketName = bucket.name(); + s3.listObjects(ListObjectsRequest.builder().bucket(bucketName).build()) + .contents() + .forEach( + s3Object -> + s3.deleteObject( + DeleteObjectRequest.builder().bucket(bucketName).key(s3Object.key()).build())); + } +} diff --git a/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/Timeouts.java b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/Timeouts.java new file mode 100644 index 000000000..0d67c0e5a --- /dev/null +++ b/edc-tests/src/test/java/org/eclipse/tractusx/edc/tests/util/Timeouts.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH + * Copyright (c) 2021,2022 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.tractusx.edc.tests.util; + +import java.time.Duration; + +public class Timeouts { + private Timeouts() {} + + public static final Duration CONTRACT_NEGOTIATION = Duration.ofSeconds(90); + public static final Duration FILE_TRANSFER = Duration.ofSeconds(90); +} diff --git a/edc-tests/src/test/resources/logback-test.xml b/edc-tests/src/test/resources/logback-test.xml index b175f4c6c..d8c11cbef 100644 --- a/edc-tests/src/test/resources/logback-test.xml +++ b/edc-tests/src/test/resources/logback-test.xml @@ -1,13 +1,22 @@ - - 4.0.0 - - net.catenax.edc - product-edc-parent - 0.1.6 - pom - - product-edc - - - edc-extensions - edc-controlplane - edc-dataplane - edc-tests - - - 2022 - - - Apache License 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - 11 - 11 - UTF-8 - - - 3.3.0 - - 3.3.0 - 2.27.1 - 3.1.0 - 3.4.1 - 2.0.0 - 2.22.2 - 3.0.0 - 3.2.1 - 3.0.0-M7 - 3.10.1 - 3.3.0 - 1.18.20.0 - 0.8.8 - 1.1.0 - 3.9.1.2184 - 4.2.0 - 0.0.1-SNAPSHOT - - - 0.0.1-20220922.4-SNAPSHOT - 1.2.2 - 42.5.0 - 9.3.1 - 8.23 - - - 5.9.1 - 1.8.2 - 7.8.0 - 5.2.0 - 1.1.0 - 4.8.0 - 1.18.24 - 1.70 - 4.9.3 - 1.17.3 - 2.0.0-beta1 - 1.4.1 - 2.2 - - - eclipse-tractusx - eclipse-tractusx_product-edc - ${project.groupId}_${project.artifactId} - - - - - central - Maven Central - https://repo1.maven.org/maven2 - - - sonatype-snapshots - - true - - - false - - https://oss.sonatype.org/content/repositories/snapshots/ - - - fraunhofer-iais-eis - Fraunhofer IAIS - https://maven.iais.fraunhofer.de/artifactory/eis-ids-public - - - dash-licenses-snapshots - https://repo.eclipse.org/content/repositories/dash-licenses-snapshots - - true - - - false - - - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${org.apache.maven.plugins.javadoc.version} - - - attach-javadocs - - jar - - - - - - org.codehaus.mojo - exec-maven-plugin - ${org.codehaus.mojo.exec.maven.plugin.version} - - - org.apache.commons - commons-build-plugin - 1.12 - - - org.apache.maven.plugins - maven-jar-plugin - ${org.apache.maven.plugins.maven.jar.plugin.version} - - - org.apache.maven.plugins - maven-resources-plugin - ${org.apache.maven.plugins.resources.version} - - - org.apache.maven.plugins - maven-dependency-plugin - ${org.apache.maven.plugins.maven.dependency.plugin.version} - - - org.apache.maven.plugins - maven-deploy-plugin - ${org.apache.maven.plugins.deploy.version} - - - com.diffplug.spotless - spotless-maven-plugin - ${com.diffplug.spotless.maven.plugin.version} - - - - 1.15.0 - - - - - - - spotless-check - compile - - check - - - - - - org.apache.maven.plugins - maven-source-plugin - ${org.apache.maven.plugins.source.version} - - - org.apache.maven.plugins - maven-compiler-plugin - ${org.apache.maven.plugins.compiler.version} - - - org.eclipse.dash - license-tool-plugin - ${org.eclipse.dash.license.tool.plugin.version} - - - org.projectlombok - lombok-maven-plugin - ${org.projectlombok.lombok.maven.plugin.version} - - - org.apache.maven.plugins - maven-failsafe-plugin - ${org.apache.maven.plugins.failsafe.version} - - - org.apache.maven.plugins - maven-surefire-plugin - ${org.apache.maven.plugins.surefire.version} - - all - - - - org.codehaus.mojo - license-maven-plugin - ${org.codehaus.mojo.license.maven.plugin} - - ${project.basedir}/LICENSE - true - - - Apache License 2.0|Apache License v2.0| - Apache License, 2.0| - Apache License, Version 2.0| - Apache License, version 2.0| - Apache Software License - Version 2.0| - The Apache License, Version 2.0| - The Apache Software License, Version 2.0 - - - BSD 2-Clause| - BSD-2-Clause - - - Eclipse Distribution License - v 1.0| - EDL 1.0 - - - Eclipse Public License - Version 1.0| - EPL 1.0| - EPL-1.0 - - - Eclipse Public License - Version 2.0| - EPL 2.0| - EPL-2.0 - - - GPL-2.0-with-classpath-exception| - GPL2 w/ CPE| - GPL-2.0-with-classpath-exception - - - LGPL 2.1| - LGPL, version 2.1 - - - MIT License| - MIT license| - The MIT License (MIT) - - - BSD-3-Clause| - Modified BSD - - - GNU Lesser General Public License, version 2.1| - LGPL 2.1 - - - - - - create-license-list - - aggregate-add-third-party - - generate-resources - - - - - org.jacoco - jacoco-maven-plugin - ${org.jacoco.maven.plugin.version} - - - org.sonarsource.scanner.maven - sonar-maven-plugin - ${org.sonarsource.scanner.maven.plugin.version} - - - - - - - com.diffplug.spotless - spotless-maven-plugin - - - - - - - - - net.catenax.edc.extensions - business-partner-validation - ${project.version} - - - net.catenax.edc.extensions - postgresql-migration - ${project.version} - - - net.catenax.edc.extensions - hashicorp-vault - ${project.version} - - - net.catenax.edc.extensions - dataplane-selector-configuration - ${project.version} - - - net.catenax.edc.extensions - data-encryption - ${project.version} - - - net.catenax.edc.extensions - cx-oauth2 - ${project.version} - - - - - net.catenax.edc - edc-controlplane-base - ${project.version} - - - net.catenax.edc - edc-dataplane-base - ${project.version} - - - - - net.catenax.edc - edc-controlplane-memory - ${project.version} - - - net.catenax.edc - edc-controlplane-postgresql - ${project.version} - - - net.catenax.edc - edc-controlplane-postgresql-hashicorp-vault - ${project.version} - - - - - net.catenax.edc - edc-dataplane-azure-vault - ${project.version} - - - net.catenax.edc - edc-dataplane-hashicorp-vault - ${project.version} - - - - - com.nimbusds - nimbus-jose-jwt - ${com.nimbus.jose.jwt.version} - - - org.postgresql - postgresql - ${org.postgresql.version} - - - org.flywaydb - flyway-core - ${org.flywaydb.version} - - - org.projectlombok - lombok - ${org.projectlombok.lombok.version} - - - org.bouncycastle - bcpkix-jdk15on - ${org.bouncycastle.bcpkix-jdk15on.version} - - - com.squareup.okhttp3 - okhttp - ${com.squareup.okhttp3.okhttp.version} - - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - org.slf4j - jul-to-slf4j - ${org.slf4j.version} - - - ch.qos.logback - logback-core - ${ch.qos.logback.logback-core.version} - - - - - org.eclipse.dataspaceconnector - apache-commons-pool-sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - api-configuration - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - api-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - asset-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - assetindex-cosmos - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - asset-index-sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - auth-basic - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - auth-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - auth-tokenbased - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - aws-s3 - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - aws-test - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - azure-eventgrid - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - azure-eventgrid-config - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - azure-test - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - azure-vault - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - blob-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - blob-operator - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - blob-provision - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - blobstorage - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - catalog - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - catalog-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - catalog-cache - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - catalog-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - common-sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - common-util - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contract - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contractagreement-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contractdefinition-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contract-definition-store-cosmos - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contractdefinition-store-sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contractnegotiation-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contract-negotiation-store-cosmos - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contractnegotiation-store-sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - contract-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - control-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - control-plane-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - core-base - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - core-boot - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - core-defaults - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - core-micrometer - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - core-policy - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - core-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - cosmos - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - cosmos-common - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - dataloading - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-management-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-azure-storage - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-framework - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-http - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-s3 - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-selector-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-selector-client - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-selector-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-selector-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-transfer - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-transfer-client - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-transfer-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - data-plane-transfer-sync - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - decentralized-identity - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - dummy-credentials-verifier - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - fcc-node-directory-cosmos - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - federated-catalog-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - filesystem-configuration - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - filesystem-vault - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - http - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - http-provisioner - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - http-receiver - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - iam-daps - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - iam-mock - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - identity-common-test - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - identity-did-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - identity-did-crypto - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - identity-did-service - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - identity-did-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - identity-did-web - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids-api-configuration - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids-api-multipart-dispatcher-v1 - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids-api-multipart-endpoint-v1 - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids-api-transform-v1 - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids-policy - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - ids-token-validation - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - jdk-logger-monitor - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - jersey - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - jersey-micrometer - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - jetty - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - jetty-micrometer - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - lease-sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - oauth2-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - oauth2-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - jwt-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - jwt-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - observability-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - policydefinition-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - policy-engine - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - policy-engine-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - policy-evaluator - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - policy-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - policy-store-cosmos - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - policy-store-sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - registration-service - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - registration-service-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - s3-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - s3-operator - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - s3-provision - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - state-machine-lib - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - token-generation-lib - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - token-validation-lib - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transaction-atomikos - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transaction-datasource-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transaction-local - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transaction-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transfer - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transfer-functions-core - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transfer-functions-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transferprocess-api - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transfer-process-store-cosmos - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transfer-process-store-sql - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transfer-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - transport-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - web-spi - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - junit - ${org.eclipse.dataspaceconnector.version} - - - org.eclipse.dataspaceconnector - junit - ${org.eclipse.dataspaceconnector.version} - test-fixtures - - - - - com.azure - azure-sdk-bom - ${com.azure.sdk.bom.version} - pom - import - - - org.junit - junit-bom - ${junit.jupiter.version} - pom - import - - - org.mockito - mockito-bom - ${mockito.version} - pom - import - - - - - org.testcontainers - junit-jupiter - ${org.testcontainers.version} - test - - - io.cucumber - cucumber-java - ${cucumber.version} - - - io.cucumber - cucumber-junit-platform-engine - ${cucumber.version} - test - - - io.rest-assured - rest-assured - ${io.rest.assured.version} - test - - - org.awaitility - awaitility - ${org.awaitility.awaitility.version} - test - - - - - org.hamcrest - hamcrest - ${org.hamcrest.hamcrest.version} - test - - - - - - - - failsafe - - - - org.apache.maven.plugins - maven-failsafe-plugin - - all - - - - - integration-test - verify - - - - - - - - - - generate-notice - - - - - org.jasig.maven - maven-notice-plugin - ${org.jasig.maven.notice.plugin.version} - - - jakarta.xml.bind - jakarta.xml.bind-api - 4.0.0 - - - org.glassfish.jaxb - jaxb-runtime - 4.0.1 - - - - ${project.basedir}/misc/NOTICE.md.template - false - * {0} under {1} - NOTICE.md - @{GENERATED_NOTICES} - - ${project.basedir}/misc/license-mappings.xml - - - - - - - - - coverage - - - - org.jacoco - jacoco-maven-plugin - - - prepare-agent - - prepare-agent - - - - - - - - - - diff --git a/resources/edc-checkstyle-config.xml b/resources/edc-checkstyle-config.xml new file mode 100644 index 000000000..a0fe306b2 --- /dev/null +++ b/resources/edc-checkstyle-config.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/resources/edc-codestyle.editorconfig b/resources/edc-codestyle.editorconfig new file mode 100644 index 000000000..9654ee2f6 --- /dev/null +++ b/resources/edc-codestyle.editorconfig @@ -0,0 +1,1168 @@ +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = false +max_line_length = 120 +tab_width = 4 +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = false +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false + +[*.css] +ij_css_align_closing_brace_with_properties = false +ij_css_blank_lines_around_nested_selector = 1 +ij_css_blank_lines_between_blocks = 1 +ij_css_block_comment_add_space = false +ij_css_brace_placement = end_of_line +ij_css_enforce_quotes_on_format = false +ij_css_hex_color_long_format = false +ij_css_hex_color_lower_case = false +ij_css_hex_color_short_format = false +ij_css_hex_color_upper_case = false +ij_css_keep_blank_lines_in_code = 2 +ij_css_keep_indents_on_empty_lines = false +ij_css_keep_single_line_blocks = false +ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_css_space_after_colon = true +ij_css_space_before_opening_brace = true +ij_css_use_double_quotes = true +ij_css_value_alignment = do_not_align + +[*.feature] +indent_size = 2 +ij_gherkin_keep_indents_on_empty_lines = false + +[*.gsp] +ij_gsp_keep_indents_on_empty_lines = false + +[*.haml] +indent_size = 2 +ij_haml_keep_indents_on_empty_lines = false + +[*.java] +ij_java_align_consecutive_assignments = false +ij_java_align_consecutive_variable_declarations = false +ij_java_align_group_field_declarations = false +ij_java_align_multiline_annotation_parameters = false +ij_java_align_multiline_array_initializer_expression = false +ij_java_align_multiline_assignment = false +ij_java_align_multiline_binary_operation = false +ij_java_align_multiline_chained_methods = false +ij_java_align_multiline_extends_list = false +ij_java_align_multiline_for = true +ij_java_align_multiline_method_parentheses = false +ij_java_align_multiline_parameters = true +ij_java_align_multiline_parameters_in_calls = false +ij_java_align_multiline_parenthesized_expression = false +ij_java_align_multiline_records = true +ij_java_align_multiline_resources = true +ij_java_align_multiline_ternary_operation = false +ij_java_align_multiline_text_blocks = false +ij_java_align_multiline_throws_list = false +ij_java_align_subsequent_simple_methods = false +ij_java_align_throws_keyword = false +ij_java_annotation_parameter_wrap = off +ij_java_array_initializer_new_line_after_left_brace = false +ij_java_array_initializer_right_brace_on_new_line = false +ij_java_array_initializer_wrap = off +ij_java_assert_statement_colon_on_next_line = false +ij_java_assert_statement_wrap = off +ij_java_assignment_wrap = off +ij_java_binary_operation_sign_on_next_line = false +ij_java_binary_operation_wrap = off +ij_java_blank_lines_after_anonymous_class_header = 0 +ij_java_blank_lines_after_class_header = 0 +ij_java_blank_lines_after_imports = 1 +ij_java_blank_lines_after_package = 1 +ij_java_blank_lines_around_class = 1 +ij_java_blank_lines_around_field = 0 +ij_java_blank_lines_around_field_in_interface = 0 +ij_java_blank_lines_around_initializer = 1 +ij_java_blank_lines_around_method = 1 +ij_java_blank_lines_around_method_in_interface = 1 +ij_java_blank_lines_before_class_end = 0 +ij_java_blank_lines_before_imports = 1 +ij_java_blank_lines_before_method_body = 0 +ij_java_blank_lines_before_package = 0 +ij_java_block_brace_style = end_of_line +ij_java_block_comment_add_space = false +ij_java_block_comment_at_first_column = true +ij_java_builder_methods = none +ij_java_call_parameters_new_line_after_left_paren = false +ij_java_call_parameters_right_paren_on_new_line = false +ij_java_call_parameters_wrap = off +ij_java_case_statement_on_separate_line = true +ij_java_catch_on_new_line = false +ij_java_class_annotation_wrap = split_into_lines +ij_java_class_brace_style = end_of_line +ij_java_class_count_to_use_import_on_demand = 99 +ij_java_class_names_in_javadoc = 1 +ij_java_do_not_indent_top_level_class_members = false +ij_java_do_not_wrap_after_single_annotation = false +ij_java_do_while_brace_force = never +ij_java_doc_add_blank_line_after_description = true +ij_java_doc_add_blank_line_after_param_comments = false +ij_java_doc_add_blank_line_after_return = false +ij_java_doc_add_p_tag_on_empty_lines = true +ij_java_doc_align_exception_comments = true +ij_java_doc_align_param_comments = true +ij_java_doc_do_not_wrap_if_one_line = false +ij_java_doc_enable_formatting = true +ij_java_doc_enable_leading_asterisks = true +ij_java_doc_indent_on_continuation = false +ij_java_doc_keep_empty_lines = true +ij_java_doc_keep_empty_parameter_tag = true +ij_java_doc_keep_empty_return_tag = true +ij_java_doc_keep_empty_throws_tag = true +ij_java_doc_keep_invalid_tags = true +ij_java_doc_param_description_on_new_line = false +ij_java_doc_preserve_line_breaks = false +ij_java_doc_use_throws_not_exception_tag = true +ij_java_else_on_new_line = false +ij_java_entity_dd_suffix = EJB +ij_java_entity_eb_suffix = Bean +ij_java_entity_hi_suffix = Home +ij_java_entity_lhi_prefix = Local +ij_java_entity_lhi_suffix = Home +ij_java_entity_li_prefix = Local +ij_java_entity_pk_class = java.lang.String +ij_java_entity_vo_suffix = VO +ij_java_enum_constants_wrap = off +ij_java_extends_keyword_wrap = off +ij_java_extends_list_wrap = off +ij_java_field_annotation_wrap = split_into_lines +ij_java_finally_on_new_line = false +ij_java_for_brace_force = never +ij_java_for_statement_new_line_after_left_paren = false +ij_java_for_statement_right_paren_on_new_line = false +ij_java_for_statement_wrap = off +ij_java_generate_final_locals = false +ij_java_generate_final_parameters = false +ij_java_if_brace_force = never +ij_java_imports_layout = *,|,java.**,javax.**,|,$* +ij_java_indent_case_from_switch = true +ij_java_insert_inner_class_imports = false +ij_java_insert_override_annotation = true +ij_java_keep_blank_lines_before_right_brace = 2 +ij_java_keep_blank_lines_between_package_declaration_and_header = 2 +ij_java_keep_blank_lines_in_code = 2 +ij_java_keep_blank_lines_in_declarations = 2 +ij_java_keep_builder_methods_indents = false +ij_java_keep_control_statement_in_one_line = true +ij_java_keep_first_column_comment = false +ij_java_keep_indents_on_empty_lines = false +ij_java_keep_line_breaks = true +ij_java_keep_multiple_expressions_in_one_line = false +ij_java_keep_simple_blocks_in_one_line = false +ij_java_keep_simple_classes_in_one_line = false +ij_java_keep_simple_lambdas_in_one_line = false +ij_java_keep_simple_methods_in_one_line = false +ij_java_label_indent_absolute = false +ij_java_label_indent_size = 0 +ij_java_lambda_brace_style = end_of_line +ij_java_layout_static_imports_separately = true +ij_java_line_comment_add_space = true +ij_java_line_comment_at_first_column = false +ij_java_message_dd_suffix = EJB +ij_java_message_eb_suffix = Bean +ij_java_method_annotation_wrap = split_into_lines +ij_java_method_brace_style = end_of_line +ij_java_method_call_chain_wrap = off +ij_java_method_parameters_new_line_after_left_paren = false +ij_java_method_parameters_right_paren_on_new_line = false +ij_java_method_parameters_wrap = off +ij_java_modifier_list_wrap = false +ij_java_names_count_to_use_import_on_demand = 99 +ij_java_new_line_after_lparen_in_record_header = false +ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.* +ij_java_parameter_annotation_wrap = off +ij_java_parentheses_expression_new_line_after_left_paren = false +ij_java_parentheses_expression_right_paren_on_new_line = false +ij_java_place_assignment_sign_on_next_line = false +ij_java_prefer_longer_names = true +ij_java_prefer_parameters_wrap = false +ij_java_record_components_wrap = normal +ij_java_repeat_synchronized = true +ij_java_replace_instanceof_and_cast = false +ij_java_replace_null_check = true +ij_java_replace_sum_lambda_with_method_ref = true +ij_java_resource_list_new_line_after_left_paren = false +ij_java_resource_list_right_paren_on_new_line = false +ij_java_resource_list_wrap = off +ij_java_rparen_on_new_line_in_record_header = false +ij_java_session_dd_suffix = EJB +ij_java_session_eb_suffix = Bean +ij_java_session_hi_suffix = Home +ij_java_session_lhi_prefix = Local +ij_java_session_lhi_suffix = Home +ij_java_session_li_prefix = Local +ij_java_session_si_suffix = Service +ij_java_space_after_closing_angle_bracket_in_type_argument = false +ij_java_space_after_colon = true +ij_java_space_after_comma = true +ij_java_space_after_comma_in_type_arguments = true +ij_java_space_after_for_semicolon = true +ij_java_space_after_quest = true +ij_java_space_after_type_cast = true +ij_java_space_before_annotation_array_initializer_left_brace = false +ij_java_space_before_annotation_parameter_list = false +ij_java_space_before_array_initializer_left_brace = false +ij_java_space_before_catch_keyword = true +ij_java_space_before_catch_left_brace = true +ij_java_space_before_catch_parentheses = true +ij_java_space_before_class_left_brace = true +ij_java_space_before_colon = true +ij_java_space_before_colon_in_foreach = true +ij_java_space_before_comma = false +ij_java_space_before_do_left_brace = true +ij_java_space_before_else_keyword = true +ij_java_space_before_else_left_brace = true +ij_java_space_before_finally_keyword = true +ij_java_space_before_finally_left_brace = true +ij_java_space_before_for_left_brace = true +ij_java_space_before_for_parentheses = true +ij_java_space_before_for_semicolon = false +ij_java_space_before_if_left_brace = true +ij_java_space_before_if_parentheses = true +ij_java_space_before_method_call_parentheses = false +ij_java_space_before_method_left_brace = true +ij_java_space_before_method_parentheses = false +ij_java_space_before_opening_angle_bracket_in_type_parameter = false +ij_java_space_before_quest = true +ij_java_space_before_switch_left_brace = true +ij_java_space_before_switch_parentheses = true +ij_java_space_before_synchronized_left_brace = true +ij_java_space_before_synchronized_parentheses = true +ij_java_space_before_try_left_brace = true +ij_java_space_before_try_parentheses = true +ij_java_space_before_type_parameter_list = false +ij_java_space_before_while_keyword = true +ij_java_space_before_while_left_brace = true +ij_java_space_before_while_parentheses = true +ij_java_space_inside_one_line_enum_braces = false +ij_java_space_within_empty_array_initializer_braces = false +ij_java_space_within_empty_method_call_parentheses = false +ij_java_space_within_empty_method_parentheses = false +ij_java_spaces_around_additive_operators = true +ij_java_spaces_around_assignment_operators = true +ij_java_spaces_around_bitwise_operators = true +ij_java_spaces_around_equality_operators = true +ij_java_spaces_around_lambda_arrow = true +ij_java_spaces_around_logical_operators = true +ij_java_spaces_around_method_ref_dbl_colon = false +ij_java_spaces_around_multiplicative_operators = true +ij_java_spaces_around_relational_operators = true +ij_java_spaces_around_shift_operators = true +ij_java_spaces_around_type_bounds_in_type_parameters = true +ij_java_spaces_around_unary_operator = false +ij_java_spaces_within_angle_brackets = false +ij_java_spaces_within_annotation_parentheses = false +ij_java_spaces_within_array_initializer_braces = true +ij_java_spaces_within_braces = false +ij_java_spaces_within_brackets = false +ij_java_spaces_within_cast_parentheses = false +ij_java_spaces_within_catch_parentheses = false +ij_java_spaces_within_for_parentheses = false +ij_java_spaces_within_if_parentheses = false +ij_java_spaces_within_method_call_parentheses = false +ij_java_spaces_within_method_parentheses = false +ij_java_spaces_within_parentheses = false +ij_java_spaces_within_record_header = false +ij_java_spaces_within_switch_parentheses = false +ij_java_spaces_within_synchronized_parentheses = false +ij_java_spaces_within_try_parentheses = false +ij_java_spaces_within_while_parentheses = false +ij_java_special_else_if_treatment = true +ij_java_subclass_name_suffix = Impl +ij_java_ternary_operation_signs_on_next_line = false +ij_java_ternary_operation_wrap = off +ij_java_test_name_suffix = Test +ij_java_throws_keyword_wrap = off +ij_java_throws_list_wrap = off +ij_java_use_external_annotations = false +ij_java_use_fq_class_names = false +ij_java_use_relative_indents = false +ij_java_use_single_class_imports = true +ij_java_variable_annotation_wrap = off +ij_java_visibility = public +ij_java_while_brace_force = never +ij_java_while_on_new_line = false +ij_java_wrap_comments = false +ij_java_wrap_first_method_in_call_chain = false +ij_java_wrap_long_lines = false + +[*.less] +indent_size = 2 +ij_less_align_closing_brace_with_properties = false +ij_less_blank_lines_around_nested_selector = 1 +ij_less_blank_lines_between_blocks = 1 +ij_less_block_comment_add_space = false +ij_less_brace_placement = 0 +ij_less_enforce_quotes_on_format = false +ij_less_hex_color_long_format = false +ij_less_hex_color_lower_case = false +ij_less_hex_color_short_format = false +ij_less_hex_color_upper_case = false +ij_less_keep_blank_lines_in_code = 2 +ij_less_keep_indents_on_empty_lines = false +ij_less_keep_single_line_blocks = false +ij_less_line_comment_add_space = false +ij_less_line_comment_at_first_column = false +ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_less_space_after_colon = true +ij_less_space_before_opening_brace = true +ij_less_use_double_quotes = true +ij_less_value_alignment = 0 + +[*.proto] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_protobuf_keep_blank_lines_in_code = 2 +ij_protobuf_keep_indents_on_empty_lines = false +ij_protobuf_keep_line_breaks = true +ij_protobuf_space_after_comma = true +ij_protobuf_space_before_comma = false +ij_protobuf_spaces_around_assignment_operators = true +ij_protobuf_spaces_within_braces = false +ij_protobuf_spaces_within_brackets = false + +[*.sass] +indent_size = 2 +ij_sass_align_closing_brace_with_properties = false +ij_sass_blank_lines_around_nested_selector = 1 +ij_sass_blank_lines_between_blocks = 1 +ij_sass_brace_placement = 0 +ij_sass_enforce_quotes_on_format = false +ij_sass_hex_color_long_format = false +ij_sass_hex_color_lower_case = false +ij_sass_hex_color_short_format = false +ij_sass_hex_color_upper_case = false +ij_sass_keep_blank_lines_in_code = 2 +ij_sass_keep_indents_on_empty_lines = false +ij_sass_keep_single_line_blocks = false +ij_sass_line_comment_add_space = false +ij_sass_line_comment_at_first_column = false +ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_sass_space_after_colon = true +ij_sass_space_before_opening_brace = true +ij_sass_use_double_quotes = true +ij_sass_value_alignment = 0 + +[*.scss] +indent_size = 2 +ij_scss_align_closing_brace_with_properties = false +ij_scss_blank_lines_around_nested_selector = 1 +ij_scss_blank_lines_between_blocks = 1 +ij_scss_block_comment_add_space = false +ij_scss_brace_placement = 0 +ij_scss_enforce_quotes_on_format = false +ij_scss_hex_color_long_format = false +ij_scss_hex_color_lower_case = false +ij_scss_hex_color_short_format = false +ij_scss_hex_color_upper_case = false +ij_scss_keep_blank_lines_in_code = 2 +ij_scss_keep_indents_on_empty_lines = false +ij_scss_keep_single_line_blocks = false +ij_scss_line_comment_add_space = false +ij_scss_line_comment_at_first_column = false +ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_scss_space_after_colon = true +ij_scss_space_before_opening_brace = true +ij_scss_use_double_quotes = true +ij_scss_value_alignment = 0 + +[*.styl] +indent_size = 2 +ij_stylus_align_closing_brace_with_properties = false +ij_stylus_blank_lines_around_nested_selector = 1 +ij_stylus_blank_lines_between_blocks = 1 +ij_stylus_brace_placement = 0 +ij_stylus_enforce_quotes_on_format = false +ij_stylus_hex_color_long_format = false +ij_stylus_hex_color_lower_case = false +ij_stylus_hex_color_short_format = false +ij_stylus_hex_color_upper_case = false +ij_stylus_keep_blank_lines_in_code = 2 +ij_stylus_keep_indents_on_empty_lines = false +ij_stylus_keep_single_line_blocks = false +ij_stylus_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow +ij_stylus_space_after_colon = true +ij_stylus_space_before_opening_brace = true +ij_stylus_use_double_quotes = true +ij_stylus_value_alignment = 0 + +[.editorconfig] +ij_editorconfig_align_group_field_declarations = false +ij_editorconfig_space_after_colon = false +ij_editorconfig_space_after_comma = true +ij_editorconfig_space_before_colon = false +ij_editorconfig_space_before_comma = false +ij_editorconfig_spaces_around_assignment_operators = true + +[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wadl,*.wsdd,*.wsdl,*.xjb,*.xml,*.xsd,*.xsl,*.xslt,*.xul}] +ij_xml_align_attributes = true +ij_xml_align_text = false +ij_xml_attribute_wrap = normal +ij_xml_block_comment_add_space = false +ij_xml_block_comment_at_first_column = true +ij_xml_keep_blank_lines = 2 +ij_xml_keep_indents_on_empty_lines = false +ij_xml_keep_line_breaks = true +ij_xml_keep_line_breaks_in_text = true +ij_xml_keep_whitespaces = false +ij_xml_keep_whitespaces_around_cdata = preserve +ij_xml_keep_whitespaces_inside_cdata = false +ij_xml_line_comment_at_first_column = true +ij_xml_space_after_tag_name = false +ij_xml_space_around_equals_in_attribute = false +ij_xml_space_inside_empty_tag = false +ij_xml_text_wrap = normal +ij_xml_use_custom_settings = false + +[{*.ats,*.cts,*.mts,*.ts}] +ij_continuation_indent_size = 4 +ij_typescript_align_imports = false +ij_typescript_align_multiline_array_initializer_expression = false +ij_typescript_align_multiline_binary_operation = false +ij_typescript_align_multiline_chained_methods = false +ij_typescript_align_multiline_extends_list = false +ij_typescript_align_multiline_for = true +ij_typescript_align_multiline_parameters = true +ij_typescript_align_multiline_parameters_in_calls = false +ij_typescript_align_multiline_ternary_operation = false +ij_typescript_align_object_properties = 0 +ij_typescript_align_union_types = false +ij_typescript_align_var_statements = 0 +ij_typescript_array_initializer_new_line_after_left_brace = false +ij_typescript_array_initializer_right_brace_on_new_line = false +ij_typescript_array_initializer_wrap = off +ij_typescript_assignment_wrap = off +ij_typescript_binary_operation_sign_on_next_line = false +ij_typescript_binary_operation_wrap = off +ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** +ij_typescript_blank_lines_after_imports = 1 +ij_typescript_blank_lines_around_class = 1 +ij_typescript_blank_lines_around_field = 0 +ij_typescript_blank_lines_around_field_in_interface = 0 +ij_typescript_blank_lines_around_function = 1 +ij_typescript_blank_lines_around_method = 1 +ij_typescript_blank_lines_around_method_in_interface = 1 +ij_typescript_block_brace_style = end_of_line +ij_typescript_block_comment_add_space = false +ij_typescript_block_comment_at_first_column = true +ij_typescript_call_parameters_new_line_after_left_paren = false +ij_typescript_call_parameters_right_paren_on_new_line = false +ij_typescript_call_parameters_wrap = off +ij_typescript_catch_on_new_line = false +ij_typescript_chained_call_dot_on_new_line = true +ij_typescript_class_brace_style = end_of_line +ij_typescript_comma_on_new_line = false +ij_typescript_do_while_brace_force = never +ij_typescript_else_on_new_line = false +ij_typescript_enforce_trailing_comma = keep +ij_typescript_extends_keyword_wrap = off +ij_typescript_extends_list_wrap = off +ij_typescript_field_prefix = _ +ij_typescript_file_name_style = relaxed +ij_typescript_finally_on_new_line = false +ij_typescript_for_brace_force = never +ij_typescript_for_statement_new_line_after_left_paren = false +ij_typescript_for_statement_right_paren_on_new_line = false +ij_typescript_for_statement_wrap = off +ij_typescript_force_quote_style = false +ij_typescript_force_semicolon_style = false +ij_typescript_function_expression_brace_style = end_of_line +ij_typescript_if_brace_force = never +ij_typescript_import_merge_members = global +ij_typescript_import_prefer_absolute_path = global +ij_typescript_import_sort_members = true +ij_typescript_import_sort_module_name = false +ij_typescript_import_use_node_resolution = true +ij_typescript_imports_wrap = on_every_item +ij_typescript_indent_case_from_switch = true +ij_typescript_indent_chained_calls = true +ij_typescript_indent_package_children = 0 +ij_typescript_jsdoc_include_types = false +ij_typescript_jsx_attribute_value = braces +ij_typescript_keep_blank_lines_in_code = 2 +ij_typescript_keep_first_column_comment = true +ij_typescript_keep_indents_on_empty_lines = false +ij_typescript_keep_line_breaks = true +ij_typescript_keep_simple_blocks_in_one_line = false +ij_typescript_keep_simple_methods_in_one_line = false +ij_typescript_line_comment_add_space = true +ij_typescript_line_comment_at_first_column = false +ij_typescript_method_brace_style = end_of_line +ij_typescript_method_call_chain_wrap = off +ij_typescript_method_parameters_new_line_after_left_paren = false +ij_typescript_method_parameters_right_paren_on_new_line = false +ij_typescript_method_parameters_wrap = off +ij_typescript_object_literal_wrap = on_every_item +ij_typescript_parentheses_expression_new_line_after_left_paren = false +ij_typescript_parentheses_expression_right_paren_on_new_line = false +ij_typescript_place_assignment_sign_on_next_line = false +ij_typescript_prefer_as_type_cast = false +ij_typescript_prefer_explicit_types_function_expression_returns = false +ij_typescript_prefer_explicit_types_function_returns = false +ij_typescript_prefer_explicit_types_vars_fields = false +ij_typescript_prefer_parameters_wrap = false +ij_typescript_reformat_c_style_comments = false +ij_typescript_space_after_colon = true +ij_typescript_space_after_comma = true +ij_typescript_space_after_dots_in_rest_parameter = false +ij_typescript_space_after_generator_mult = true +ij_typescript_space_after_property_colon = true +ij_typescript_space_after_quest = true +ij_typescript_space_after_type_colon = true +ij_typescript_space_after_unary_not = false +ij_typescript_space_before_async_arrow_lparen = true +ij_typescript_space_before_catch_keyword = true +ij_typescript_space_before_catch_left_brace = true +ij_typescript_space_before_catch_parentheses = true +ij_typescript_space_before_class_lbrace = true +ij_typescript_space_before_class_left_brace = true +ij_typescript_space_before_colon = true +ij_typescript_space_before_comma = false +ij_typescript_space_before_do_left_brace = true +ij_typescript_space_before_else_keyword = true +ij_typescript_space_before_else_left_brace = true +ij_typescript_space_before_finally_keyword = true +ij_typescript_space_before_finally_left_brace = true +ij_typescript_space_before_for_left_brace = true +ij_typescript_space_before_for_parentheses = true +ij_typescript_space_before_for_semicolon = false +ij_typescript_space_before_function_left_parenth = true +ij_typescript_space_before_generator_mult = false +ij_typescript_space_before_if_left_brace = true +ij_typescript_space_before_if_parentheses = true +ij_typescript_space_before_method_call_parentheses = false +ij_typescript_space_before_method_left_brace = true +ij_typescript_space_before_method_parentheses = false +ij_typescript_space_before_property_colon = false +ij_typescript_space_before_quest = true +ij_typescript_space_before_switch_left_brace = true +ij_typescript_space_before_switch_parentheses = true +ij_typescript_space_before_try_left_brace = true +ij_typescript_space_before_type_colon = false +ij_typescript_space_before_unary_not = false +ij_typescript_space_before_while_keyword = true +ij_typescript_space_before_while_left_brace = true +ij_typescript_space_before_while_parentheses = true +ij_typescript_spaces_around_additive_operators = true +ij_typescript_spaces_around_arrow_function_operator = true +ij_typescript_spaces_around_assignment_operators = true +ij_typescript_spaces_around_bitwise_operators = true +ij_typescript_spaces_around_equality_operators = true +ij_typescript_spaces_around_logical_operators = true +ij_typescript_spaces_around_multiplicative_operators = true +ij_typescript_spaces_around_relational_operators = true +ij_typescript_spaces_around_shift_operators = true +ij_typescript_spaces_around_unary_operator = false +ij_typescript_spaces_within_array_initializer_brackets = false +ij_typescript_spaces_within_brackets = false +ij_typescript_spaces_within_catch_parentheses = false +ij_typescript_spaces_within_for_parentheses = false +ij_typescript_spaces_within_if_parentheses = false +ij_typescript_spaces_within_imports = false +ij_typescript_spaces_within_interpolation_expressions = false +ij_typescript_spaces_within_method_call_parentheses = false +ij_typescript_spaces_within_method_parentheses = false +ij_typescript_spaces_within_object_literal_braces = false +ij_typescript_spaces_within_object_type_braces = true +ij_typescript_spaces_within_parentheses = false +ij_typescript_spaces_within_switch_parentheses = false +ij_typescript_spaces_within_type_assertion = false +ij_typescript_spaces_within_union_types = true +ij_typescript_spaces_within_while_parentheses = false +ij_typescript_special_else_if_treatment = true +ij_typescript_ternary_operation_signs_on_next_line = false +ij_typescript_ternary_operation_wrap = off +ij_typescript_union_types_wrap = on_every_item +ij_typescript_use_chained_calls_group_indents = false +ij_typescript_use_double_quotes = true +ij_typescript_use_explicit_js_extension = global +ij_typescript_use_path_mapping = always +ij_typescript_use_public_modifier = false +ij_typescript_use_semicolon_after_statement = true +ij_typescript_var_declaration_wrap = normal +ij_typescript_while_brace_force = never +ij_typescript_while_on_new_line = false +ij_typescript_wrap_comments = false + +[{*.bash,*.sh,*.zsh}] +indent_size = 2 +tab_width = 2 +ij_shell_binary_ops_start_line = false +ij_shell_keep_column_alignment_padding = false +ij_shell_minify_program = false +ij_shell_redirect_followed_by_space = false +ij_shell_switch_cases_indented = false +ij_shell_use_unix_line_separator = true + +[{*.cjs,*.js}] +ij_continuation_indent_size = 4 +ij_javascript_align_imports = false +ij_javascript_align_multiline_array_initializer_expression = false +ij_javascript_align_multiline_binary_operation = false +ij_javascript_align_multiline_chained_methods = false +ij_javascript_align_multiline_extends_list = false +ij_javascript_align_multiline_for = true +ij_javascript_align_multiline_parameters = true +ij_javascript_align_multiline_parameters_in_calls = false +ij_javascript_align_multiline_ternary_operation = false +ij_javascript_align_object_properties = 0 +ij_javascript_align_union_types = false +ij_javascript_align_var_statements = 0 +ij_javascript_array_initializer_new_line_after_left_brace = false +ij_javascript_array_initializer_right_brace_on_new_line = false +ij_javascript_array_initializer_wrap = off +ij_javascript_assignment_wrap = off +ij_javascript_binary_operation_sign_on_next_line = false +ij_javascript_binary_operation_wrap = off +ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** +ij_javascript_blank_lines_after_imports = 1 +ij_javascript_blank_lines_around_class = 1 +ij_javascript_blank_lines_around_field = 0 +ij_javascript_blank_lines_around_function = 1 +ij_javascript_blank_lines_around_method = 1 +ij_javascript_block_brace_style = end_of_line +ij_javascript_block_comment_add_space = false +ij_javascript_block_comment_at_first_column = true +ij_javascript_call_parameters_new_line_after_left_paren = false +ij_javascript_call_parameters_right_paren_on_new_line = false +ij_javascript_call_parameters_wrap = off +ij_javascript_catch_on_new_line = false +ij_javascript_chained_call_dot_on_new_line = true +ij_javascript_class_brace_style = end_of_line +ij_javascript_comma_on_new_line = false +ij_javascript_do_while_brace_force = never +ij_javascript_else_on_new_line = false +ij_javascript_enforce_trailing_comma = keep +ij_javascript_extends_keyword_wrap = off +ij_javascript_extends_list_wrap = off +ij_javascript_field_prefix = _ +ij_javascript_file_name_style = relaxed +ij_javascript_finally_on_new_line = false +ij_javascript_for_brace_force = never +ij_javascript_for_statement_new_line_after_left_paren = false +ij_javascript_for_statement_right_paren_on_new_line = false +ij_javascript_for_statement_wrap = off +ij_javascript_force_quote_style = false +ij_javascript_force_semicolon_style = false +ij_javascript_function_expression_brace_style = end_of_line +ij_javascript_if_brace_force = never +ij_javascript_import_merge_members = global +ij_javascript_import_prefer_absolute_path = global +ij_javascript_import_sort_members = true +ij_javascript_import_sort_module_name = false +ij_javascript_import_use_node_resolution = true +ij_javascript_imports_wrap = on_every_item +ij_javascript_indent_case_from_switch = true +ij_javascript_indent_chained_calls = true +ij_javascript_indent_package_children = 0 +ij_javascript_jsx_attribute_value = braces +ij_javascript_keep_blank_lines_in_code = 2 +ij_javascript_keep_first_column_comment = true +ij_javascript_keep_indents_on_empty_lines = false +ij_javascript_keep_line_breaks = true +ij_javascript_keep_simple_blocks_in_one_line = false +ij_javascript_keep_simple_methods_in_one_line = false +ij_javascript_line_comment_add_space = true +ij_javascript_line_comment_at_first_column = false +ij_javascript_method_brace_style = end_of_line +ij_javascript_method_call_chain_wrap = off +ij_javascript_method_parameters_new_line_after_left_paren = false +ij_javascript_method_parameters_right_paren_on_new_line = false +ij_javascript_method_parameters_wrap = off +ij_javascript_object_literal_wrap = on_every_item +ij_javascript_parentheses_expression_new_line_after_left_paren = false +ij_javascript_parentheses_expression_right_paren_on_new_line = false +ij_javascript_place_assignment_sign_on_next_line = false +ij_javascript_prefer_as_type_cast = false +ij_javascript_prefer_explicit_types_function_expression_returns = false +ij_javascript_prefer_explicit_types_function_returns = false +ij_javascript_prefer_explicit_types_vars_fields = false +ij_javascript_prefer_parameters_wrap = false +ij_javascript_reformat_c_style_comments = false +ij_javascript_space_after_colon = true +ij_javascript_space_after_comma = true +ij_javascript_space_after_dots_in_rest_parameter = false +ij_javascript_space_after_generator_mult = true +ij_javascript_space_after_property_colon = true +ij_javascript_space_after_quest = true +ij_javascript_space_after_type_colon = true +ij_javascript_space_after_unary_not = false +ij_javascript_space_before_async_arrow_lparen = true +ij_javascript_space_before_catch_keyword = true +ij_javascript_space_before_catch_left_brace = true +ij_javascript_space_before_catch_parentheses = true +ij_javascript_space_before_class_lbrace = true +ij_javascript_space_before_class_left_brace = true +ij_javascript_space_before_colon = true +ij_javascript_space_before_comma = false +ij_javascript_space_before_do_left_brace = true +ij_javascript_space_before_else_keyword = true +ij_javascript_space_before_else_left_brace = true +ij_javascript_space_before_finally_keyword = true +ij_javascript_space_before_finally_left_brace = true +ij_javascript_space_before_for_left_brace = true +ij_javascript_space_before_for_parentheses = true +ij_javascript_space_before_for_semicolon = false +ij_javascript_space_before_function_left_parenth = true +ij_javascript_space_before_generator_mult = false +ij_javascript_space_before_if_left_brace = true +ij_javascript_space_before_if_parentheses = true +ij_javascript_space_before_method_call_parentheses = false +ij_javascript_space_before_method_left_brace = true +ij_javascript_space_before_method_parentheses = false +ij_javascript_space_before_property_colon = false +ij_javascript_space_before_quest = true +ij_javascript_space_before_switch_left_brace = true +ij_javascript_space_before_switch_parentheses = true +ij_javascript_space_before_try_left_brace = true +ij_javascript_space_before_type_colon = false +ij_javascript_space_before_unary_not = false +ij_javascript_space_before_while_keyword = true +ij_javascript_space_before_while_left_brace = true +ij_javascript_space_before_while_parentheses = true +ij_javascript_spaces_around_additive_operators = true +ij_javascript_spaces_around_arrow_function_operator = true +ij_javascript_spaces_around_assignment_operators = true +ij_javascript_spaces_around_bitwise_operators = true +ij_javascript_spaces_around_equality_operators = true +ij_javascript_spaces_around_logical_operators = true +ij_javascript_spaces_around_multiplicative_operators = true +ij_javascript_spaces_around_relational_operators = true +ij_javascript_spaces_around_shift_operators = true +ij_javascript_spaces_around_unary_operator = false +ij_javascript_spaces_within_array_initializer_brackets = false +ij_javascript_spaces_within_brackets = false +ij_javascript_spaces_within_catch_parentheses = false +ij_javascript_spaces_within_for_parentheses = false +ij_javascript_spaces_within_if_parentheses = false +ij_javascript_spaces_within_imports = false +ij_javascript_spaces_within_interpolation_expressions = false +ij_javascript_spaces_within_method_call_parentheses = false +ij_javascript_spaces_within_method_parentheses = false +ij_javascript_spaces_within_object_literal_braces = false +ij_javascript_spaces_within_object_type_braces = true +ij_javascript_spaces_within_parentheses = false +ij_javascript_spaces_within_switch_parentheses = false +ij_javascript_spaces_within_type_assertion = false +ij_javascript_spaces_within_union_types = true +ij_javascript_spaces_within_while_parentheses = false +ij_javascript_special_else_if_treatment = true +ij_javascript_ternary_operation_signs_on_next_line = false +ij_javascript_ternary_operation_wrap = off +ij_javascript_union_types_wrap = on_every_item +ij_javascript_use_chained_calls_group_indents = false +ij_javascript_use_double_quotes = true +ij_javascript_use_explicit_js_extension = global +ij_javascript_use_path_mapping = always +ij_javascript_use_public_modifier = false +ij_javascript_use_semicolon_after_statement = true +ij_javascript_var_declaration_wrap = normal +ij_javascript_while_brace_force = never +ij_javascript_while_on_new_line = false +ij_javascript_wrap_comments = false + +[{*.ft,*.vm,*.vsl}] +ij_vtl_keep_indents_on_empty_lines = false + +[{*.gant,*.gradle,*.groovy,*.gson,*.gy}] +ij_groovy_align_group_field_declarations = false +ij_groovy_align_multiline_array_initializer_expression = false +ij_groovy_align_multiline_assignment = false +ij_groovy_align_multiline_binary_operation = false +ij_groovy_align_multiline_chained_methods = false +ij_groovy_align_multiline_extends_list = false +ij_groovy_align_multiline_for = true +ij_groovy_align_multiline_list_or_map = true +ij_groovy_align_multiline_method_parentheses = false +ij_groovy_align_multiline_parameters = true +ij_groovy_align_multiline_parameters_in_calls = false +ij_groovy_align_multiline_resources = true +ij_groovy_align_multiline_ternary_operation = false +ij_groovy_align_multiline_throws_list = false +ij_groovy_align_named_args_in_map = true +ij_groovy_align_throws_keyword = false +ij_groovy_array_initializer_new_line_after_left_brace = false +ij_groovy_array_initializer_right_brace_on_new_line = false +ij_groovy_array_initializer_wrap = off +ij_groovy_assert_statement_wrap = off +ij_groovy_assignment_wrap = off +ij_groovy_binary_operation_wrap = off +ij_groovy_blank_lines_after_class_header = 0 +ij_groovy_blank_lines_after_imports = 1 +ij_groovy_blank_lines_after_package = 1 +ij_groovy_blank_lines_around_class = 1 +ij_groovy_blank_lines_around_field = 0 +ij_groovy_blank_lines_around_field_in_interface = 0 +ij_groovy_blank_lines_around_method = 1 +ij_groovy_blank_lines_around_method_in_interface = 1 +ij_groovy_blank_lines_before_imports = 1 +ij_groovy_blank_lines_before_method_body = 0 +ij_groovy_blank_lines_before_package = 0 +ij_groovy_block_brace_style = end_of_line +ij_groovy_block_comment_add_space = false +ij_groovy_block_comment_at_first_column = true +ij_groovy_call_parameters_new_line_after_left_paren = false +ij_groovy_call_parameters_right_paren_on_new_line = false +ij_groovy_call_parameters_wrap = off +ij_groovy_catch_on_new_line = false +ij_groovy_class_annotation_wrap = split_into_lines +ij_groovy_class_brace_style = end_of_line +ij_groovy_class_count_to_use_import_on_demand = 5 +ij_groovy_do_while_brace_force = never +ij_groovy_else_on_new_line = false +ij_groovy_enum_constants_wrap = off +ij_groovy_extends_keyword_wrap = off +ij_groovy_extends_list_wrap = off +ij_groovy_field_annotation_wrap = split_into_lines +ij_groovy_finally_on_new_line = false +ij_groovy_for_brace_force = never +ij_groovy_for_statement_new_line_after_left_paren = false +ij_groovy_for_statement_right_paren_on_new_line = false +ij_groovy_for_statement_wrap = off +ij_groovy_if_brace_force = never +ij_groovy_import_annotation_wrap = 2 +ij_groovy_imports_layout = *,|,javax.**,java.**,|,$* +ij_groovy_indent_case_from_switch = true +ij_groovy_indent_label_blocks = true +ij_groovy_insert_inner_class_imports = false +ij_groovy_keep_blank_lines_before_right_brace = 2 +ij_groovy_keep_blank_lines_in_code = 2 +ij_groovy_keep_blank_lines_in_declarations = 2 +ij_groovy_keep_control_statement_in_one_line = true +ij_groovy_keep_first_column_comment = true +ij_groovy_keep_indents_on_empty_lines = false +ij_groovy_keep_line_breaks = true +ij_groovy_keep_multiple_expressions_in_one_line = false +ij_groovy_keep_simple_blocks_in_one_line = false +ij_groovy_keep_simple_classes_in_one_line = true +ij_groovy_keep_simple_lambdas_in_one_line = true +ij_groovy_keep_simple_methods_in_one_line = true +ij_groovy_label_indent_absolute = false +ij_groovy_label_indent_size = 0 +ij_groovy_lambda_brace_style = end_of_line +ij_groovy_layout_static_imports_separately = true +ij_groovy_line_comment_add_space = false +ij_groovy_line_comment_at_first_column = true +ij_groovy_method_annotation_wrap = split_into_lines +ij_groovy_method_brace_style = end_of_line +ij_groovy_method_call_chain_wrap = off +ij_groovy_method_parameters_new_line_after_left_paren = false +ij_groovy_method_parameters_right_paren_on_new_line = false +ij_groovy_method_parameters_wrap = off +ij_groovy_modifier_list_wrap = false +ij_groovy_names_count_to_use_import_on_demand = 3 +ij_groovy_parameter_annotation_wrap = off +ij_groovy_parentheses_expression_new_line_after_left_paren = false +ij_groovy_parentheses_expression_right_paren_on_new_line = false +ij_groovy_prefer_parameters_wrap = false +ij_groovy_resource_list_new_line_after_left_paren = false +ij_groovy_resource_list_right_paren_on_new_line = false +ij_groovy_resource_list_wrap = off +ij_groovy_space_after_assert_separator = true +ij_groovy_space_after_colon = true +ij_groovy_space_after_comma = true +ij_groovy_space_after_comma_in_type_arguments = true +ij_groovy_space_after_for_semicolon = true +ij_groovy_space_after_quest = true +ij_groovy_space_after_type_cast = true +ij_groovy_space_before_annotation_parameter_list = false +ij_groovy_space_before_array_initializer_left_brace = false +ij_groovy_space_before_assert_separator = false +ij_groovy_space_before_catch_keyword = true +ij_groovy_space_before_catch_left_brace = true +ij_groovy_space_before_catch_parentheses = true +ij_groovy_space_before_class_left_brace = true +ij_groovy_space_before_closure_left_brace = true +ij_groovy_space_before_colon = true +ij_groovy_space_before_comma = false +ij_groovy_space_before_do_left_brace = true +ij_groovy_space_before_else_keyword = true +ij_groovy_space_before_else_left_brace = true +ij_groovy_space_before_finally_keyword = true +ij_groovy_space_before_finally_left_brace = true +ij_groovy_space_before_for_left_brace = true +ij_groovy_space_before_for_parentheses = true +ij_groovy_space_before_for_semicolon = false +ij_groovy_space_before_if_left_brace = true +ij_groovy_space_before_if_parentheses = true +ij_groovy_space_before_method_call_parentheses = false +ij_groovy_space_before_method_left_brace = true +ij_groovy_space_before_method_parentheses = false +ij_groovy_space_before_quest = true +ij_groovy_space_before_record_parentheses = false +ij_groovy_space_before_switch_left_brace = true +ij_groovy_space_before_switch_parentheses = true +ij_groovy_space_before_synchronized_left_brace = true +ij_groovy_space_before_synchronized_parentheses = true +ij_groovy_space_before_try_left_brace = true +ij_groovy_space_before_try_parentheses = true +ij_groovy_space_before_while_keyword = true +ij_groovy_space_before_while_left_brace = true +ij_groovy_space_before_while_parentheses = true +ij_groovy_space_in_named_argument = true +ij_groovy_space_in_named_argument_before_colon = false +ij_groovy_space_within_empty_array_initializer_braces = false +ij_groovy_space_within_empty_method_call_parentheses = false +ij_groovy_spaces_around_additive_operators = true +ij_groovy_spaces_around_assignment_operators = true +ij_groovy_spaces_around_bitwise_operators = true +ij_groovy_spaces_around_equality_operators = true +ij_groovy_spaces_around_lambda_arrow = true +ij_groovy_spaces_around_logical_operators = true +ij_groovy_spaces_around_multiplicative_operators = true +ij_groovy_spaces_around_regex_operators = true +ij_groovy_spaces_around_relational_operators = true +ij_groovy_spaces_around_shift_operators = true +ij_groovy_spaces_within_annotation_parentheses = false +ij_groovy_spaces_within_array_initializer_braces = false +ij_groovy_spaces_within_braces = true +ij_groovy_spaces_within_brackets = false +ij_groovy_spaces_within_cast_parentheses = false +ij_groovy_spaces_within_catch_parentheses = false +ij_groovy_spaces_within_for_parentheses = false +ij_groovy_spaces_within_gstring_injection_braces = false +ij_groovy_spaces_within_if_parentheses = false +ij_groovy_spaces_within_list_or_map = false +ij_groovy_spaces_within_method_call_parentheses = false +ij_groovy_spaces_within_method_parentheses = false +ij_groovy_spaces_within_parentheses = false +ij_groovy_spaces_within_switch_parentheses = false +ij_groovy_spaces_within_synchronized_parentheses = false +ij_groovy_spaces_within_try_parentheses = false +ij_groovy_spaces_within_tuple_expression = false +ij_groovy_spaces_within_while_parentheses = false +ij_groovy_special_else_if_treatment = true +ij_groovy_ternary_operation_wrap = off +ij_groovy_throws_keyword_wrap = off +ij_groovy_throws_list_wrap = off +ij_groovy_use_flying_geese_braces = false +ij_groovy_use_fq_class_names = false +ij_groovy_use_fq_class_names_in_javadoc = true +ij_groovy_use_relative_indents = false +ij_groovy_use_single_class_imports = true +ij_groovy_variable_annotation_wrap = off +ij_groovy_while_brace_force = never +ij_groovy_while_on_new_line = false +ij_groovy_wrap_chain_calls_after_dot = false +ij_groovy_wrap_long_lines = false + +[{*.gradle.kts,*.kt,*.kts,*.main.kts,*.space.kts}] +ij_kotlin_align_in_columns_case_branch = false +ij_kotlin_align_multiline_binary_operation = false +ij_kotlin_align_multiline_extends_list = false +ij_kotlin_align_multiline_method_parentheses = false +ij_kotlin_align_multiline_parameters = true +ij_kotlin_align_multiline_parameters_in_calls = false +ij_kotlin_allow_trailing_comma = false +ij_kotlin_allow_trailing_comma_on_call_site = false +ij_kotlin_assignment_wrap = normal +ij_kotlin_blank_lines_after_class_header = 0 +ij_kotlin_blank_lines_around_block_when_branches = 0 +ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 +ij_kotlin_block_comment_add_space = false +ij_kotlin_block_comment_at_first_column = true +ij_kotlin_call_parameters_new_line_after_left_paren = true +ij_kotlin_call_parameters_right_paren_on_new_line = true +ij_kotlin_call_parameters_wrap = on_every_item +ij_kotlin_catch_on_new_line = false +ij_kotlin_class_annotation_wrap = split_into_lines +ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL +ij_kotlin_continuation_indent_for_chained_calls = false +ij_kotlin_continuation_indent_for_expression_bodies = false +ij_kotlin_continuation_indent_in_argument_lists = false +ij_kotlin_continuation_indent_in_elvis = false +ij_kotlin_continuation_indent_in_if_conditions = false +ij_kotlin_continuation_indent_in_parameter_lists = false +ij_kotlin_continuation_indent_in_supertype_lists = false +ij_kotlin_else_on_new_line = false +ij_kotlin_enum_constants_wrap = off +ij_kotlin_extends_list_wrap = normal +ij_kotlin_field_annotation_wrap = split_into_lines +ij_kotlin_finally_on_new_line = false +ij_kotlin_if_rparen_on_new_line = true +ij_kotlin_import_nested_classes = false +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ +ij_kotlin_insert_whitespaces_in_simple_one_line_method = true +ij_kotlin_keep_blank_lines_before_right_brace = 2 +ij_kotlin_keep_blank_lines_in_code = 2 +ij_kotlin_keep_blank_lines_in_declarations = 2 +ij_kotlin_keep_first_column_comment = true +ij_kotlin_keep_indents_on_empty_lines = false +ij_kotlin_keep_line_breaks = true +ij_kotlin_lbrace_on_next_line = false +ij_kotlin_line_comment_add_space = false +ij_kotlin_line_comment_at_first_column = true +ij_kotlin_method_annotation_wrap = split_into_lines +ij_kotlin_method_call_chain_wrap = normal +ij_kotlin_method_parameters_new_line_after_left_paren = true +ij_kotlin_method_parameters_right_paren_on_new_line = true +ij_kotlin_method_parameters_wrap = on_every_item +ij_kotlin_name_count_to_use_star_import = 5 +ij_kotlin_name_count_to_use_star_import_for_members = 3 +ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.** +ij_kotlin_parameter_annotation_wrap = off +ij_kotlin_space_after_comma = true +ij_kotlin_space_after_extend_colon = true +ij_kotlin_space_after_type_colon = true +ij_kotlin_space_before_catch_parentheses = true +ij_kotlin_space_before_comma = false +ij_kotlin_space_before_extend_colon = true +ij_kotlin_space_before_for_parentheses = true +ij_kotlin_space_before_if_parentheses = true +ij_kotlin_space_before_lambda_arrow = true +ij_kotlin_space_before_type_colon = false +ij_kotlin_space_before_when_parentheses = true +ij_kotlin_space_before_while_parentheses = true +ij_kotlin_spaces_around_additive_operators = true +ij_kotlin_spaces_around_assignment_operators = true +ij_kotlin_spaces_around_equality_operators = true +ij_kotlin_spaces_around_function_type_arrow = true +ij_kotlin_spaces_around_logical_operators = true +ij_kotlin_spaces_around_multiplicative_operators = true +ij_kotlin_spaces_around_range = false +ij_kotlin_spaces_around_relational_operators = true +ij_kotlin_spaces_around_unary_operator = false +ij_kotlin_spaces_around_when_arrow = true +ij_kotlin_variable_annotation_wrap = off +ij_kotlin_while_on_new_line = false +ij_kotlin_wrap_elvis_expressions = 1 +ij_kotlin_wrap_expression_body_functions = 1 +ij_kotlin_wrap_first_method_in_call_chain = false + +[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}] +indent_size = 2 +ij_json_keep_blank_lines_in_code = 0 +ij_json_keep_indents_on_empty_lines = false +ij_json_keep_line_breaks = true +ij_json_space_after_colon = true +ij_json_space_after_comma = true +ij_json_space_before_colon = true +ij_json_space_before_comma = false +ij_json_spaces_within_braces = false +ij_json_spaces_within_brackets = false +ij_json_wrap_long_lines = false + +[{*.hcl,*.nomad}] +indent_size = 2 +ij_hcl_array_wrapping = 2 +ij_hcl_keep_blank_lines_in_code = 2 +ij_hcl_keep_indents_on_empty_lines = false +ij_hcl_keep_line_breaks = true +ij_hcl_object_wrapping = 2 +ij_hcl_property_alignment = 0 +ij_hcl_property_line_commenter_character = 0 +ij_hcl_space_after_comma = true +ij_hcl_space_before_comma = false +ij_hcl_spaces_around_assignment_operators = true +ij_hcl_spaces_within_braces = false +ij_hcl_spaces_within_brackets = false +ij_hcl_wrap_long_lines = false + +[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] +ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 +ij_html_align_attributes = true +ij_html_align_text = false +ij_html_attribute_wrap = normal +ij_html_block_comment_add_space = false +ij_html_block_comment_at_first_column = true +ij_html_do_not_align_children_of_min_lines = 0 +ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p +ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot +ij_html_enforce_quotes = false +ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var +ij_html_keep_blank_lines = 2 +ij_html_keep_indents_on_empty_lines = false +ij_html_keep_line_breaks = true +ij_html_keep_line_breaks_in_text = true +ij_html_keep_whitespaces = false +ij_html_keep_whitespaces_inside = span,pre,textarea +ij_html_line_comment_at_first_column = true +ij_html_new_line_after_last_attribute = never +ij_html_new_line_before_first_attribute = never +ij_html_quote_style = double +ij_html_remove_new_line_before_tags = br +ij_html_space_after_tag_name = false +ij_html_space_around_equality_in_attribute = false +ij_html_space_inside_empty_tag = false +ij_html_text_wrap = normal + +[{*.jsf,*.jsp,*.jspf,*.tag,*.tagf,*.xjsp}] +ij_jsp_jsp_prefer_comma_separated_import_list = false +ij_jsp_keep_indents_on_empty_lines = false + +[{*.jspx,*.tagx}] +ij_jspx_keep_indents_on_empty_lines = false + +[{*.markdown,*.md}] +ij_markdown_force_one_space_after_blockquote_symbol = true +ij_markdown_force_one_space_after_header_symbol = true +ij_markdown_force_one_space_after_list_bullet = true +ij_markdown_force_one_space_between_words = true +ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_max_lines_around_block_elements = 1 +ij_markdown_max_lines_around_header = 1 +ij_markdown_max_lines_between_paragraphs = 1 +ij_markdown_min_lines_around_block_elements = 1 +ij_markdown_min_lines_around_header = 1 +ij_markdown_min_lines_between_paragraphs = 1 + +[{*.pb,*.textproto}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_prototext_keep_blank_lines_in_code = 2 +ij_prototext_keep_indents_on_empty_lines = false +ij_prototext_keep_line_breaks = true +ij_prototext_space_after_colon = true +ij_prototext_space_after_comma = true +ij_prototext_space_before_colon = false +ij_prototext_space_before_comma = false +ij_prototext_spaces_within_braces = true +ij_prototext_spaces_within_brackets = false + +[{*.properties,spring.handlers,spring.schemas}] +ij_properties_align_group_field_declarations = false +ij_properties_keep_blank_lines = false +ij_properties_key_value_delimiter = equals +ij_properties_spaces_around_key_value_delimiter = false + +[{*.tf,*.tfvars}] +indent_size = 2 +ij_hcl-terraform_array_wrapping = 2 +ij_hcl-terraform_keep_blank_lines_in_code = 2 +ij_hcl-terraform_keep_indents_on_empty_lines = false +ij_hcl-terraform_keep_line_breaks = true +ij_hcl-terraform_object_wrapping = 2 +ij_hcl-terraform_property_alignment = 0 +ij_hcl-terraform_property_line_commenter_character = 0 +ij_hcl-terraform_space_after_comma = true +ij_hcl-terraform_space_before_comma = false +ij_hcl-terraform_spaces_around_assignment_operators = true +ij_hcl-terraform_spaces_within_braces = false +ij_hcl-terraform_spaces_within_brackets = false +ij_hcl-terraform_wrap_long_lines = false + +[{*.yaml,*.yml}] +indent_size = 2 +ij_yaml_align_values_properties = do_not_align +ij_yaml_autoinsert_sequence_marker = true +ij_yaml_block_mapping_on_new_line = false +ij_yaml_indent_sequence_value = true +ij_yaml_keep_indents_on_empty_lines = false +ij_yaml_keep_line_breaks = true +ij_yaml_sequence_on_new_line = false +ij_yaml_space_before_colon = false +ij_yaml_spaces_within_braces = true +ij_yaml_spaces_within_brackets = true diff --git a/resources/edc-codestyle.xml b/resources/edc-codestyle.xml new file mode 100644 index 000000000..73c05a7cf --- /dev/null +++ b/resources/edc-codestyle.xml @@ -0,0 +1,319 @@ + + + + + + + + + +

+ + + + true + true + true + true + + + +
+
+ + + + true + true + true + true + + + +
+
+ + + + true + true + true + true + + + +
+
+ + + + true + true + true + true + + + +
+
+ + + + true + true + true + + + +
+
+ + + + true + true + true + + + +
+
+ + + + true + true + true + + + +
+
+ + + + true + true + true + + + +
+
+ + + + true + true + + + +
+
+ + + + true + true + true + + + +
+
+ + + + true + true + true + + + +
+
+ + + + true + true + true + + + +
+
+ + + + true + true + true + + + +
+
+ + + + true + true + + + +
+
+ + + + true + true + + + +
+
+ + + + true + true + + + +
+
+ + + + true + true + + + +
+
+ + + true + + +
+
+ + + true + + +
+
+ + + true + + +
+
+ + + + true + true + + + +
+
+ + + true + + +
+
+ + + + true + true + + + +
+
+ + + + true + true + + + +
+
+ + + true + + +
+
+ + + true + + +
+
+ + + + true + true + + + +
+
+ + + true + + +
+ + + + + + \ No newline at end of file diff --git a/resources/save_actions_screenshot.png b/resources/save_actions_screenshot.png new file mode 100644 index 000000000..10ae06cb0 Binary files /dev/null and b/resources/save_actions_screenshot.png differ diff --git a/resources/suppressions.xml b/resources/suppressions.xml new file mode 100644 index 000000000..6a89b011f --- /dev/null +++ b/resources/suppressions.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 000000000..6fc530f73 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,163 @@ +rootProject.name = "product-edc" + +include(":edc-extensions:business-partner-validation") +include(":edc-extensions:control-plane-adapter") +include(":edc-extensions:cx-oauth2") +include(":edc-extensions:data-encryption") +include(":edc-extensions:dataplane-selector-configuration") +include(":edc-extensions:hashicorp-vault") +include(":edc-extensions:postgresql-migration") +include(":edc-extensions:provision-additional-headers") +include(":edc-extensions:transferprocess-sftp-client") +include(":edc-extensions:transferprocess-sftp-common") +include(":edc-extensions:transferprocess-sftp-provisioner") +include(":edc-tests") + +// modules for controlplane artifacts +include(":edc-controlplane") +include(":edc-controlplane:edc-controlplane-base") +include(":edc-controlplane:edc-controlplane-memory") +include(":edc-controlplane:edc-controlplane-memory-hashicorp-vault") +include(":edc-controlplane:edc-controlplane-postgresql") +include(":edc-controlplane:edc-controlplane-postgresql-hashicorp-vault") + +// modules for dataplane artifacts +include(":edc-dataplane") +include(":edc-dataplane:edc-dataplane-azure-vault") +include(":edc-dataplane:edc-dataplane-base") +include(":edc-dataplane:edc-dataplane-hashicorp-vault") + +// this is needed to have access to snapshot builds of plugins +pluginManagement { + repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots/") + } + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots/") + } + mavenCentral() + mavenLocal() + } + versionCatalogs { + create("libs") { + from("org.eclipse.edc:edc-versions:0.0.1-20230220-SNAPSHOT") + library("testcontainers-junit", "org.testcontainers","junit-jupiter").version("1.17.6") + library("apache-sshd-core", "org.apache.sshd","sshd-core").version("2.9.2") + library("apache-sshd-sftp", "org.apache.sshd","sshd-sftp").version("2.9.2") + } + // create version catalog for all EDC modules + create("edc") { + version("edc", "0.0.1-20230220-SNAPSHOT") + library("spi-catalog", "org.eclipse.edc", "catalog-spi").versionRef("edc") + library("spi-transfer", "org.eclipse.edc", "transfer-spi").versionRef("edc") + library("spi-core", "org.eclipse.edc", "core-spi").versionRef("edc") + library("spi-policy", "org.eclipse.edc", "policy-spi").versionRef("edc") + library("spi-policyengine", "org.eclipse.edc", "policy-engine-spi").versionRef("edc") + library("spi-transaction-datasource", "org.eclipse.edc", "transaction-datasource-spi").versionRef("edc") + library("spi-transactionspi", "org.eclipse.edc", "transaction-spi").versionRef("edc") + library("spi-aggregateservices", "org.eclipse.edc", "aggregate-service-spi").versionRef("edc") + library("spi-web", "org.eclipse.edc", "web-spi").versionRef("edc") + library("spi-jwt", "org.eclipse.edc", "jwt-spi").versionRef("edc") + library("spi-oauth2", "org.eclipse.edc", "oauth2-spi").versionRef("edc") + library("util", "org.eclipse.edc", "util").versionRef("edc") + library("boot", "org.eclipse.edc", "boot").versionRef("edc") + library("config-filesystem", "org.eclipse.edc", "configuration-filesystem").versionRef("edc") + library("core-controlplane", "org.eclipse.edc", "control-plane-core").versionRef("edc") + library("core-connector", "org.eclipse.edc", "connector-core").versionRef("edc") + library("core-jetty", "org.eclipse.edc", "jetty-core").versionRef("edc") + library("core-jersey", "org.eclipse.edc", "jersey-core").versionRef("edc") + library("junit", "org.eclipse.edc", "junit").versionRef("edc") + library("api-management-config", "org.eclipse.edc", "management-api-configuration").versionRef("edc") + library("api-management", "org.eclipse.edc", "management-api").versionRef("edc") + library("api-observability", "org.eclipse.edc", "api-observability").versionRef("edc") + library("ext-http", "org.eclipse.edc", "http").versionRef("edc") + library("spi-ids", "org.eclipse.edc", "ids-spi").versionRef("edc") + library("ids", "org.eclipse.edc", "ids").versionRef("edc") + library("iam-mock", "org.eclipse.edc", "iam-mock").versionRef("edc") + library("ext-azure-cosmos-core", "org.eclipse.edc", "azure-cosmos-core").versionRef("edc") + library("ext-azure-test", "org.eclipse.edc", "azure-test").versionRef("edc") + library("policy-engine", "org.eclipse.edc", "policy-engine").versionRef("edc") + library("auth-tokenbased", "org.eclipse.edc", "auth-tokenbased").versionRef("edc") + library("auth-oauth2-core", "org.eclipse.edc", "oauth2-core").versionRef("edc") + library("auth-oauth2-daps", "org.eclipse.edc", "oauth2-daps").versionRef("edc") + library("transaction-local", "org.eclipse.edc", "transaction-local").versionRef("edc") + + // implementations + library("sql-assetindex", "org.eclipse.edc", "asset-index-sql").versionRef("edc") + library("sql-contract-definition", "org.eclipse.edc", "contract-definition-store-sql").versionRef("edc") + library("sql-contract-negotiation", "org.eclipse.edc", "contract-negotiation-store-sql").versionRef("edc") + library("sql-transferprocess", "org.eclipse.edc", "transfer-process-store-sql").versionRef("edc") + library("sql-policydef", "org.eclipse.edc", "policy-definition-store-sql").versionRef("edc") + library("sql-core", "org.eclipse.edc", "sql-core").versionRef("edc") + library("sql-lease", "org.eclipse.edc", "sql-lease").versionRef("edc") + library("sql-pool", "org.eclipse.edc", "sql-pool-apache-commons").versionRef("edc") + + // azure stuff + library("azure-vault", "org.eclipse.edc", "vault-azure").versionRef("edc") + library("azure-identity", "com.azure:azure-identity:+") + + // DPF modules + library("spi-dataplane-dataplane", "org.eclipse.edc", "data-plane-spi").versionRef("edc") + library("spi-dataplane-transfer", "org.eclipse.edc", "transfer-data-plane-spi").versionRef("edc") + library("spi-dataplane-selector", "org.eclipse.edc", "data-plane-selector-spi").versionRef("edc") + library("dpf-transferclient", "org.eclipse.edc", "data-plane-transfer-client").versionRef("edc") + library("dpf-selector-client", "org.eclipse.edc", "data-plane-selector-client").versionRef("edc") + library("dpf-selector-spi", "org.eclipse.edc", "data-plane-selector-spi").versionRef("edc") + library("dpf-selector-core", "org.eclipse.edc", "data-plane-selector-core").versionRef("edc") + library("dpf-transfer", "org.eclipse.edc", "transfer-data-plane").versionRef("edc") + library("dpf-framework", "org.eclipse.edc", "data-plane-framework").versionRef("edc") + library("dpf-core", "org.eclipse.edc", "data-plane-core").versionRef("edc") + library("dpf-util", "org.eclipse.edc", "data-plane-util").versionRef("edc") + library("dpf-awss3", "org.eclipse.edc", "data-plane-aws-s3").versionRef("edc") + library("dpf-http", "org.eclipse.edc", "data-plane-http").versionRef("edc") + library("dpf-oauth2", "org.eclipse.edc", "data-plane-http-oauth2").versionRef("edc") + library("dpf-api", "org.eclipse.edc", "data-plane-api").versionRef("edc") + + // micrometer and other infra stuff + library("micrometer-core", "org.eclipse.edc", "micrometer-core").versionRef("edc") + library("micrometer-jersey", "org.eclipse.edc", "jersey-micrometer").versionRef("edc") + library("micrometer-jetty", "org.eclipse.edc", "jetty-micrometer").versionRef("edc") + library("monitor-jdklogger", "org.eclipse.edc", "monitor-jdk-logger").versionRef("edc") + library( + "transfer.dynamicreceiver", + "org.eclipse.edc", + "transfer-pull-http-dynamic-receiver" + ).versionRef("edc") + + bundle( + "connector", + listOf("boot", "core-connector", "core-jersey", "core-controlplane", "api-observability") + ) + + bundle( + "dpf", + listOf("dpf-transfer", "dpf-selector-core", "dpf-selector-client", "spi-dataplane-selector") + ) + + bundle( + "sqlstores", + listOf( + "sql-assetindex", + "sql-contract-definition", + "sql-contract-negotiation", + "sql-transferprocess", + "sql-policydef" + ) + ) + + bundle( + "monitoring", + listOf("micrometer-core", "micrometer-jersey", "micrometer-jetty") +// listOf("micrometer-core", "micrometer-jersey", "micrometer-jetty", "monitor-jdklogger") + ) + } + } +} diff --git a/settings.xml b/settings.xml deleted file mode 100644 index 805b7a95c..000000000 --- a/settings.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - github-edc - ${env.GITHUB_PACKAGE_USERNAME} - ${env.GITHUB_PACKAGE_PASSWORD} - - - - github - ${env.GITHUB_PACKAGE_USERNAME} - ${env.GITHUB_PACKAGE_PASSWORD} - - -