From 67cf437a4c14c8b1a66f0db7ce60362aa87633a5 Mon Sep 17 00:00:00 2001 From: Richard Treier Date: Thu, 26 Sep 2024 11:17:53 +0200 Subject: [PATCH] feat: config as java code (WIP) --- CHANGELOG.md | 4 +- config/build.gradle.kts | 31 + .../sovity/edc/utils/config/ConfigProps.java | 617 ++++++++++++++++++ .../edc/utils/config/ConfigService.java | 119 ++++ .../sovity/edc/utils/config/ConfigUtils.java | 88 +++ .../edc/utils/config/SovityEdcRuntime.java | 31 + .../config/SovityServiceExtensionContext.java | 55 ++ .../edc/utils/config/model/ConfigProp.java | 81 +++ .../model/ConfigPropDefaultValueFn.java | 18 +- .../config/model/ConfigPropRequiredIfFn.java | 9 +- .../edc/utils/config/utils/UrlPathUtils.java | 30 + config/src/test/java/UrlPathUtilsTest.java | 53 ++ docker-compose-dev.yaml | 50 +- docs/api/sovity-edc-api-wrapper.yaml | 4 +- .../contract-termination/build.gradle.kts | 1 + .../ContractTerminationExtension.java | 11 +- ...tAgreementTerminationDetailsQueryTest.java | 4 +- .../query/TerminateContractQueryTest.java | 2 +- .../database-direct-access/build.gradle.kts | 1 + .../DatabaseDirectAccessExtension.java | 34 +- .../db/directaccess/DslContextFactory.java | 4 +- extensions/postgres-flyway/build.gradle.kts | 2 + .../extension/postgresql/FlywayMigrator.java | 5 +- .../postgresql/PostgresFlywayConfig.java | 46 +- .../postgresql/PostgresFlywayExtension.java | 64 -- .../migration/DatabaseMigrationManager.java | 6 +- .../SovityMessengerExtensionE2eTest.java | 2 +- .../demo/SovityMessengerDemoTest.java | 2 +- extensions/wrapper/wrapper/build.gradle.kts | 1 + .../edc/ext/wrapper/WrapperExtension.java | 6 - .../WrapperExtensionContextBuilder.java | 5 +- .../api/ui/pages/asset/AssetApiService.java | 1 - .../services/ConfigPropertyUtils.java | 18 - .../dashboard/services/DapsConfigService.java | 14 +- .../dashboard/services/MiwConfigService.java | 11 +- .../services/SelfDescriptionService.java | 80 +-- .../ui/pages/asset/AssetApiServiceTest.java | 4 +- .../api/ui/pages/catalog/CatalogApiTest.java | 6 +- .../ContractAgreementPageTest.java | 6 +- ...ntractAgreementTransferApiServiceTest.java | 4 +- .../ContractDefinitionPageApiServiceTest.java | 4 +- .../DashboardPageApiServiceTest.java | 15 +- .../PolicyDefinitionApiServiceTest.java | 4 +- .../TransferHistoryPageApiServiceTest.java | 4 +- .../TransferProcessAssetApiServiceTest.java | 4 +- .../ext/wrapper/api/usecase/KpiApiTest.java | 4 +- .../api/usecase/SupportedPolicyApiTest.java | 4 +- .../api/usecase/UseCaseApiWrapperTest.java | 12 +- launchers/common/base/build.gradle.kts | 3 + .../src/main/java/de/sovity/edc/Main.java | 10 + launchers/connectors/mds-ce/build.gradle.kts | 2 +- .../connectors/sovity-ce/build.gradle.kts | 2 +- .../connectors/sovity-dev/build.gradle.kts | 2 +- .../connectors/test-backend/build.gradle.kts | 2 +- settings.gradle.kts | 1 + tests/build.gradle.kts | 1 + .../e2e/AlwaysTrueMigrationReversedTest.java | 11 +- .../edc/e2e/AlwaysTrueMigrationTest.java | 11 +- .../de/sovity/edc/e2e/ApiWrapperDemoTest.java | 14 +- .../e2e/DataSourceParameterizationTest.java | 9 +- .../edc/e2e/DataSourceQueryParamsTest.java | 2 +- .../edc/e2e/ManagementApiTransferTest.java | 4 +- .../de/sovity/edc/e2e/UiApiWrapperTest.java | 10 +- .../sovity/edc/e2e/UseCaseApiWrapperTest.java | 4 +- utils/test-utils/build.gradle.kts | 1 + .../e2e/connector/ConnectorRemote.java | 50 +- .../e2e/connector/MockDataAddressRemote.java | 5 +- .../e2e/connector/config/ConnectorConfig.java | 54 +- .../config/ConnectorConfigFactory.java | 80 +-- .../config/ConnectorRemoteConfig.java | 42 +- .../config/ConnectorRemoteConfigFactory.java | 84 --- .../connector/config/api/EdcApiConfig.java | 39 -- .../config/api/EdcApiConfigFactory.java | 90 --- .../e2e/connector/config/api/EdcApiGroup.java | 45 -- .../config/api/EdcApiGroupConfig.java | 39 -- .../config/api/auth/ApiKeyAuthProvider.java | 30 - .../extension/e2e/extension/E2eScenario.java | 10 +- .../e2e/extension/E2eTestExtension.java | 20 +- .../e2e/extension/E2eTestExtensionConfig.java | 6 +- 79 files changed, 1452 insertions(+), 812 deletions(-) create mode 100644 config/build.gradle.kts create mode 100644 config/src/main/java/de/sovity/edc/utils/config/ConfigProps.java create mode 100644 config/src/main/java/de/sovity/edc/utils/config/ConfigService.java create mode 100644 config/src/main/java/de/sovity/edc/utils/config/ConfigUtils.java create mode 100644 config/src/main/java/de/sovity/edc/utils/config/SovityEdcRuntime.java create mode 100644 config/src/main/java/de/sovity/edc/utils/config/SovityServiceExtensionContext.java create mode 100644 config/src/main/java/de/sovity/edc/utils/config/model/ConfigProp.java rename utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/NoneAuthProvider.java => config/src/main/java/de/sovity/edc/utils/config/model/ConfigPropDefaultValueFn.java (54%) rename utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/AuthProvider.java => config/src/main/java/de/sovity/edc/utils/config/model/ConfigPropRequiredIfFn.java (65%) create mode 100644 config/src/main/java/de/sovity/edc/utils/config/utils/UrlPathUtils.java create mode 100644 config/src/test/java/UrlPathUtilsTest.java delete mode 100644 extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/ConfigPropertyUtils.java create mode 100644 launchers/common/base/src/main/java/de/sovity/edc/Main.java delete mode 100644 utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorRemoteConfigFactory.java delete mode 100644 utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiConfig.java delete mode 100644 utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiConfigFactory.java delete mode 100644 utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiGroup.java delete mode 100644 utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiGroupConfig.java delete mode 100644 utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/ApiKeyAuthProvider.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 939153876..c564213db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,13 +12,13 @@ please see [changelog_updates.md](docs/dev/changelog_updates.md). #### Major Changes -- Moved Catalog Crawler to the Authority Portal +- Removed Catalog Crawler as it will be added to the Authority Portal to prevent circular dependencies #### Minor Changes #### Patch Changes -### Deployment Migration Notes +- Refactoring: Config as Java Code### Deployment Migration Notes _No special deployment migration steps required_ diff --git a/config/build.gradle.kts b/config/build.gradle.kts new file mode 100644 index 000000000..041257464 --- /dev/null +++ b/config/build.gradle.kts @@ -0,0 +1,31 @@ + +plugins { + `java-library` + `maven-publish` +} + +dependencies { + annotationProcessor(libs.lombok) + compileOnly(libs.lombok) + + api(libs.edc.bootSpi) + + + testAnnotationProcessor(libs.lombok) + testCompileOnly(libs.lombok) + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.junitJupiter) + testImplementation(libs.assertj.core) + testImplementation(libs.junit.api) + testRuntimeOnly(libs.junit.engine) +} + +group = libs.versions.sovityEdcGroup.get() + +publishing { + publications { + create(project.name) { + from(components["java"]) + } + } +} diff --git a/config/src/main/java/de/sovity/edc/utils/config/ConfigProps.java b/config/src/main/java/de/sovity/edc/utils/config/ConfigProps.java new file mode 100644 index 000000000..a63a14d58 --- /dev/null +++ b/config/src/main/java/de/sovity/edc/utils/config/ConfigProps.java @@ -0,0 +1,617 @@ +/* + * Copyright (c) 2023 sovity 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: + * sovity GmbH - init + * + */ + +package de.sovity.edc.utils.config; + +import de.sovity.edc.utils.config.model.ConfigProp; +import de.sovity.edc.utils.config.utils.UrlPathUtils; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import lombok.experimental.UtilityClass; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +/** + * Configuration Properties for the EDC:
+ * - Source-Of-Truth for all EDC Properties used in our code
+ * - Ordered list of available properties for documentation
+ * - Ordered list of properties for defaulting before edc boot + */ +@SuppressWarnings("unused") +@UtilityClass +public class ConfigProps { + public static final List ALL_CE_PROPS = new ArrayList<>(); + + /* The order of the properties affects evaluation! */ + + public static final ConfigProp MY_EDC_NETWORK_TYPE = ConfigProp.builder() + .category(Category.ADVANCED) + .property("my.edc.network.type") + .description( + "Configuring EDCs for different environments. Available values are: %s".formatted( + String.join(", ", NetworkType.ALL_NETWORK_TYPES))) + .warnIfOverridden(true) + .defaultValue(NetworkType.PRODUCTION) + .build().also(ALL_CE_PROPS::add); + + /* Basic Configuration */ + + public static final ConfigProp MY_EDC_PARTICIPANT_ID = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.participant.id") + .description("Participant ID / Connector ID") + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_TITLE = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.title") + .description("Connector Title") + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_DESCRIPTION = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.description") + .description("Connector Description") + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_CURATOR_URL = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.curator.url") + .description("Curator URL") + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_CURATOR_NAME = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.curator.name") + .description("Curator Name") + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_MAINTAINER_URL = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.maintainer.url") + .description("Maintainer URL") + .defaultValue("https://sovity.de") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_MAINTAINER_NAME = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.maintainer.name") + .description("Maintainer Name") + .defaultValue("sovity GmbH") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_FQDN = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.fqdn") + .description("Fully Qualified Domain Name of where the Connector is hosted, e.g. my-connector.myorg.com") + .requiredIf(props -> NetworkType.isProduction(props) || NetworkType.isLocalDemoDockerCompose(props)) + .defaultValueFn(props -> new NetworkTypeMatcher(props).unitTest(() -> "localhost").orElseThrow()) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_JDBC_URL = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.jdbc.url") + .description("PostgreSQL DB Connection: JDBC URL") + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_JDBC_USER = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.jdbc.user") + .description("PostgreSQL DB Connection: Username") + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_JDBC_PASSWORD = ConfigProp.builder() + .category(Category.BASIC) + .property("my.edc.jdbc.password") + .description("PostgreSQL DB Connection: Password") + .required(true) + .build().also(ALL_CE_PROPS::add); + + /* Auth */ + + // EDC_API_AUTH_KEY: ApiKeyDefaultValue + public static final ConfigProp EDC_API_AUTH_KEY = ConfigProp.builder() + .category(Category.BASIC) + .property("edc.api.auth.key") + .description("Management API: API Key, provided with Header X-Api-Key.") + .required(true) + .defaultValue("ApiKeyDefaultValue") + .warnIfUnset(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_C2C_IAM_TYPE = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("my.edc.c2c.iam.type") + .description( + "Type of Connector-to-Connector IAM / Authentication Mechanism used. Available values are: 'daps-sovity', 'daps-omejdn', 'mock-iam'. Default: 'daps-sovity'") + .warnIfOverridden(true) + .defaultValue("daps-sovity") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_OAUTH_TOKEN_URL = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.oauth.token.url") + .description("OAuth2 / DAPS: Token URL") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_OAUTH_PROVIDER_JWKS_URL = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.oauth.provider.jwks.url") + .description("OAuth2 / DAPS: JWKS URL") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_OAUTH_CLIENT_ID = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.oauth.client.id") + .description("OAuth2 / DAPS: Client ID. Defaults to Participant ID") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .defaultValueFn(MY_EDC_PARTICIPANT_ID::getRaw) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_KEYSTORE = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.keystore") + .description("File-Based Vault: Keystore file (.jks)") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_KEYSTORE_PASSWORD = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.keystore.password") + .description("File-Based Vault: Keystore password") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .required(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_OAUTH_CERTIFICATE_ALIAS = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.oauth.certificate.alias") + .description("OAuth2 / DAPS: Certificate Vault Entry for the Public Key. Default: '1'") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .defaultValue("1") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_OAUTH_PRIVATE_KEY_ALIAS = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.oauth.private.key.alias") + .description("OAuth2 / DAPS: Certificate Vault Entry for the Private Key. Default: '1'") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .defaultValue("1") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_OAUTH_PROVIDER_AUDIENCE = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.oauth.provider.audience") + .description("OAuth2 / DAPS: Provider Audience") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .warnIfOverridden(true) + .defaultValueFn(props -> { + if ("daps-omejdn".equals(MY_EDC_C2C_IAM_TYPE.getRaw(props))) { + return "idsc:IDS_CONNECTORS_ALL"; + } + + // daps-sovity + return EDC_OAUTH_TOKEN_URL.getRaw(props); + }) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_OAUTH_ENDPOINT_AUDIENCE = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.oauth.endpoint.audience") + .description("OAuth2 / DAPS: Endpoint Audience") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .warnIfOverridden(true) + .defaultValue("idsc:IDS_CONNECTORS_ALL") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_AGENT_IDENTITY_KEY = ConfigProp.builder() + .category(Category.C2C_IAM) + .property("edc.agent.identity.key") + .description("OAuth2 / DAPS: Agent Identity Key") + .relevantIf(props -> MY_EDC_C2C_IAM_TYPE.getRaw(props).startsWith("daps")) + .warnIfOverridden(true) + .defaultValueFn(props -> { + if ("daps-omejdn".equals(MY_EDC_C2C_IAM_TYPE.getRaw(props))) { + return "client_id"; + } + + // daps-sovity + return "referringConnector"; + }) + .build().also(ALL_CE_PROPS::add); + + /* Advanced */ + + public static final ConfigProp MY_EDC_FIRST_PORT = ConfigProp.builder() + .category(Category.ADVANCED) + .property("my.edc.first.port") + .description("The first port of several ports to be used for the several API endpoints. " + + "Useful when starting two EDCs on the host machine network / during tests") + .warnIfOverridden(true) + .defaultValue("11000") + .build().also(ALL_CE_PROPS::add); + public static final ConfigProp EDC_SERVER_DB_CONNECTION_POOL_SIZE = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.server.db.connection.pool.size") + .description("Size of the Hikari Connection Pool") + .defaultValue("10") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.flyway.additional.migration.locations") + .description("Coma-separated list of additional flyway migration scripts locations. Useful for DB Migration Tests in Unit Tests. " + + "Need to be correct Flyway Migration Script Locations. " + + "See https://flywaydb.org/documentation/configuration/parameters/locations") + .warnIfOverridden(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_SERVER_DB_CONNECTION_TIMEOUT_IN_MS = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.server.db.connection.timeout.in.ms") + .description("Sets the connection timeout for the datasource in milliseconds.") + .defaultValue("5000") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_FLYWAY_REPAIR = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.flyway.repair") + .description("(Deprecated) Attempts to fix the history when a migration fails. Only supported in older migration scripts.") + .defaultValue("false") + .warnIfOverridden(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_FLYWAY_CLEAN_ENABLE = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.flyway.clean.enable") + .description("Allows the deletion of the database. Goes in pair with edc.flyway.clean.enable. Both options must be enabled for a clean to happen.") + .defaultValue("false") + .warnIfOverridden(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_FLYWAY_CLEAN = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.flyway.clean") + .description("Request the deletion of the database. Goes in pair with edc.flyway.clean. Both options must be enabled for a clean to happen.") + .defaultValue("false") + .warnIfOverridden(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_WEB_REST_CORS_ENABLED = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.web.rest.cors.enabled") + .description("Enable CORS") + .warnIfOverridden(true) + .relevantIf(props -> !NetworkType.isProduction(props)) + .defaultValue("true") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_WEB_REST_CORS_HEADERS = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.web.rest.cors.headers") + .description("CORS: Allowed Headers") + .warnIfOverridden(true) + .relevantIf(props -> !NetworkType.isProduction(props)) + .defaultValue("origin,content-type,accept,authorization,X-Api-Key") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_WEB_REST_CORS_ORIGINS = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.web.rest.cors.origins") + .description("CORS: Allowed Origins") + .warnIfOverridden(true) + .relevantIf(props -> !NetworkType.isProduction(props)) + .defaultValue("*") + .build().also(ALL_CE_PROPS::add); + + private static final ConfigProp EDC_BUILD_DATE = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.build.date") + .description("Build Date, usually set via CI into a build arg into the built image") + .defaultValue("Unknown version") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_DOCKER_COMPOSE_SERVICE_NAME = ConfigProp.builder() + .category(Category.ADVANCED) + .property("edc.web.rest.cors.origins") + .description("CORS: Allowed Origins") + .warnIfOverridden(true) + .relevantIf(props -> !NetworkType.isProduction(props)) + .defaultValue("*") + .build().also(ALL_CE_PROPS::add); + + /* Defaults of EDC Configuration */ + + public static final ConfigProp MY_EDC_PROTOCOL = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("my.edc.protocol") + .description("HTTP Protocol for when the EDC exposes its own URL for callbacks") + .warnIfOverridden(true) + .defaultValueFn(props -> NetworkType.isProduction(props) ? "https://" : "http://") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_BASE_PATH = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("my.edc.base.path") + .description("Optional prefix to be added before all API paths") + .warnIfOverridden(true) + .defaultValue("/") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_PATH = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.path") + .description("API Group 'Web' contains misc API endpoints, usually not meant to be public, this is the base path.") + .warnIfOverridden(true) + .defaultValueFn(props -> UrlPathUtils.urlPathJoin(MY_EDC_BASE_PATH.getRaw(props), "api")) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_PORT = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.port") + .description("API Group 'Web' contains misc API endpoints, usually not meant to be public, this is the port.") + .warnIfOverridden(true) + .defaultValueFn(props -> plus(props, MY_EDC_FIRST_PORT, 1)) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_MANAGEMENT_PATH = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.management.path") + .description( + "API Group 'Management' contains API endpoints for EDC interaction and should be protected from unauthorized access. This is the base path.") + .warnIfOverridden(true) + .defaultValueFn(props -> UrlPathUtils.urlPathJoin(MY_EDC_BASE_PATH.getRaw(props), "api/management")) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_MANAGEMENT_PORT = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.management.port") + .description( + "API Group 'Management' contains API endpoints for EDC interaction and should be protected from unauthorized access. This is the port.") + .warnIfOverridden(true) + .defaultValueFn(props -> plus(props, MY_EDC_FIRST_PORT, 2)) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_PROTOCOL_PATH = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.protocol.path") + .description("API Group 'Protocol' must be public as it is used for connector to connector communication, this is the base path.") + .warnIfOverridden(true) + .defaultValueFn(props -> UrlPathUtils.urlPathJoin(MY_EDC_BASE_PATH.getRaw(props), "api/dsp")) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_PROTOCOL_PORT = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.protocol.port") + .description("API Group 'Protocol' must be public as it is used for connector to connector communication, this is the port.") + .warnIfOverridden(true) + .defaultValueFn(props -> plus(props, MY_EDC_FIRST_PORT, 3)) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_CONTROL_PATH = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.control.path") + .description( + "API Group 'Control' contains API endpoints for control plane/data plane interaction and should be non-public, this is the base path.") + .warnIfOverridden(true) + .defaultValueFn(props -> UrlPathUtils.urlPathJoin(MY_EDC_BASE_PATH.getRaw(props), "api/control")) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_CONTROL_PORT = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.control.port") + .description( + "API Group 'Control' contains API endpoints for control plane/data plane interaction and should be non-public, this is the port.") + .warnIfOverridden(true) + .defaultValueFn(props -> plus(props, MY_EDC_FIRST_PORT, 4)) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_PUBLIC_PATH = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.public.path") + .description("API Group 'Public' contains public data plane API endpoints. This is the base path.") + .warnIfOverridden(true) + .defaultValueFn(props -> UrlPathUtils.urlPathJoin(MY_EDC_BASE_PATH.getRaw(props), "api/public")) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp WEB_HTTP_PUBLIC_PORT = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("web.http.public.port") + .description("API Group 'Public' contains public data plane API endpoints. This is the port.") + .warnIfOverridden(true) + .defaultValueFn(props -> plus(props, MY_EDC_FIRST_PORT, 5)) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_JSONLD_HTTPS_ENABLED = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.jsonld.https.enabled") + .description("Required to be set since Eclipse EDC 0.2.1") + .warnIfOverridden(true) + .defaultValue("true") + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_NAME_KEBAB_CASE = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("my.edc.name.kebab-case") + .description("Deprecated. Prefer using %s instead".formatted(MY_EDC_PARTICIPANT_ID.getProperty())) + .warnIfOverridden(true) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_CONNECTOR_NAME = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.connector.name") + .description("Connector Name") + .warnIfOverridden(true) + .defaultValueFn(props -> coalesce(MY_EDC_PARTICIPANT_ID.getRaw(props), MY_EDC_NAME_KEBAB_CASE.getRaw(props))) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_PARTICIPANT_ID = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.participant.id") + .description("Participant ID / Connector ID") + .warnIfOverridden(true) + .defaultValueFn(props -> coalesce(MY_EDC_PARTICIPANT_ID.getRaw(props), MY_EDC_NAME_KEBAB_CASE.getRaw(props))) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_HOSTNAME = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.hostname") + .description("Same as %s".formatted(MY_EDC_FQDN.getProperty())) + .warnIfOverridden(true) + .defaultValueFn(MY_EDC_FQDN::getRaw) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_DSP_CALLBACK_ADDRESS = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.dsp.callback.address") + .description("Full URL for the DSP callback address") + .warnIfOverridden(true) + .defaultValueFn(ConfigUtils::getProtocolApiUrl) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_UI_MANAGEMENT_API_URL_SHOWN_IN_DASHBOARD = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.ui.management.api.url.shown.in.dashboard") + .description( + "URL shown in the EDC UI for the management API. This might differ from the default Management API URL if an auth proxy solution has been put between") + .defaultValueFn(ConfigUtils::getManagementApiUrl) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp MY_EDC_DATASOURCE_PLACEHOLDER_BASEURL = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("my.edc.datasource.placeholder.baseurl") + .description("Base URL for the On Request asset datasource, as reachable by the data plane") + .warnIfOverridden(true) + .defaultValueFn(EDC_DSP_CALLBACK_ADDRESS::getRaw) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_DATASOURCE_DEFAULT_URL = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.datasource.default.url") + .description("Default Datasource: JDBC URL. Prefer setting %s".formatted(MY_EDC_JDBC_URL.getProperty())) + .warnIfOverridden(true) + .defaultValueFn(MY_EDC_JDBC_URL::getRaw) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_DATASOURCE_DEFAULT_USER = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.datasource.default.user") + .description("Default Datasource: Username. Prefer setting %s".formatted(MY_EDC_JDBC_USER.getProperty())) + .warnIfOverridden(true) + .defaultValueFn(MY_EDC_JDBC_USER::getRaw) + .build().also(ALL_CE_PROPS::add); + + public static final ConfigProp EDC_DATASOURCE_DEFAULT_PASSWORD = ConfigProp.builder() + .category(Category.RAW_EDC_CONFIG_DEFAULTS) + .property("edc.datasource.default.password") + .description("Default Datasource: Password. Prefer setting %s".formatted(MY_EDC_JDBC_PASSWORD.getProperty())) + .warnIfOverridden(true) + .defaultValueFn(MY_EDC_JDBC_PASSWORD::getRaw) + .build().also(ALL_CE_PROPS::add); + + public String coalesce(String... values) { + for (String value : values) { + if (value != null) { + return value; + } + } + return null; + } + + private static String plus(Map props, ConfigProp prop, int add) { + var raw = prop.getRaw(props); + var result = Integer.parseInt(raw == null ? "0" : raw) + add; + return String.valueOf(result); + } + + @UtilityClass + public static class NetworkType { + public static final String PRODUCTION = "production"; + public static final String LOCAL_DEMO_DOCKER_COMPOSE = "local-demo-docker-compose"; + public static final String UNIT_TEST = "unit-test"; + public static final List ALL_NETWORK_TYPES = List.of(PRODUCTION, LOCAL_DEMO_DOCKER_COMPOSE, UNIT_TEST); + + public static boolean isProduction(Map props) { + return NetworkType.PRODUCTION.equals(MY_EDC_NETWORK_TYPE.getRaw(props)); + } + + public static boolean isLocalDemoDockerCompose(Map props) { + return NetworkType.LOCAL_DEMO_DOCKER_COMPOSE.equals(MY_EDC_NETWORK_TYPE.getRaw(props)); + } + + public static boolean isUnitTest(Map props) { + return NetworkType.UNIT_TEST.equals(MY_EDC_NETWORK_TYPE.getRaw(props)); + } + } + + @Setter + @Accessors(fluent = true, chain = true) + @RequiredArgsConstructor + public static class NetworkTypeMatcher { + private final Map props; + private Supplier production; + private Supplier localDemoDockerCompose; + private Supplier unitTest; + + public T orElse(Supplier elseFn) { + if (production != null && NetworkType.isProduction(props)) { + return production.get(); + } + + if (localDemoDockerCompose != null && NetworkType.isLocalDemoDockerCompose(props)) { + return localDemoDockerCompose.get(); + } + + if (unitTest != null && NetworkType.isUnitTest(props)) { + return unitTest.get(); + } + + return elseFn.get(); + } + + public T orElseThrow() { + return orElse(() -> { + var msg = "Unhandled %s: %s".formatted( + MY_EDC_NETWORK_TYPE.getProperty(), + MY_EDC_NETWORK_TYPE.getRaw(props) + ); + throw new IllegalArgumentException(msg); + }); + } + } + + @UtilityClass + private static class Category { + public static final String BASIC = "Basic Configuration"; + public static final String ADVANCED = "Advanced configuration"; + public static final String C2C_IAM = "Connector-to-Connector IAM"; + public static final String RAW_EDC_CONFIG_DEFAULTS = "EDC Config Defaults / Overrides"; + } +} diff --git a/config/src/main/java/de/sovity/edc/utils/config/ConfigService.java b/config/src/main/java/de/sovity/edc/utils/config/ConfigService.java new file mode 100644 index 000000000..f4f05841b --- /dev/null +++ b/config/src/main/java/de/sovity/edc/utils/config/ConfigService.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2023 sovity 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: + * sovity GmbH - init + * + */ + +package de.sovity.edc.utils.config; + +import de.sovity.edc.utils.config.model.ConfigProp; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.spi.monitor.ConsoleMonitor; +import org.eclipse.edc.spi.monitor.Monitor; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static java.util.stream.Collectors.toMap; + +@RequiredArgsConstructor +public class ConfigService { + private final Monitor monitor; + + /** + * This is a field so the sovity EE can use a different list of available properties for defaulting + */ + private final List configProps; + + public static Map applyDefaultsStatic( + Map propertiesInput, + List configProps + ) { + var configService = new ConfigService(new ConsoleMonitor(), configProps); + var properties = propertiesInput.entrySet().stream() + .collect(toMap(e -> e.getKey().getProperty(), Map.Entry::getValue)); + return configService.applyDefaults(properties); + } + + public Map applyDefaults(Map properties) { + var withDefaults = new HashMap<>(translateToDotCase(properties)); + configProps.forEach(prop -> applyDefault(withDefaults, prop)); + return withDefaults; + } + + private void applyDefault(Map properties, ConfigProp prop) { + if (prop.getRelevantIf() != null && !prop.getRelevantIf().predicate(properties)) { + return; + } + String value = prop.getRaw(properties); + warnIfRequired(prop, value); + + if (value != null) { + return; + } + + if (prop.isRequired()) { + var message = "Missing required Config Property: %s \"%s\" (%s)".formatted( + prop.getProperty(), + prop.getDescription(), + prop.getCategory() + ); + throw new IllegalStateException(message); + } + + var defaultValue = prop.getDefaultValue(); + if (prop.getDefaultValueFn() != null) { + defaultValue = prop.getDefaultValueFn().apply(properties); + } + if (defaultValue != null) { + properties.put(prop.getProperty(), defaultValue); + } + } + + private void warnIfRequired(ConfigProp prop, String value) { + if (value != null && prop.isWarnIfOverridden()) { + monitor.warning("Property set to 'warn if overriden': %s, value=%s \"%s\" (%s)".formatted( + prop.getProperty(), + value, + prop.getDescription(), + prop.getCategory() + )); + } + + if ((value == null || value.isBlank()) && prop.isWarnIfUnset()) { + monitor.warning("Property set to 'warn if unset': %s, value=%s \"%s\" (%s)".formatted( + prop.getProperty(), + value, + prop.getDescription(), + prop.getCategory() + )); + } + } + + private Map translateToDotCase(Map properties) { + Map result = new HashMap<>(); + properties.forEach((key, value) -> { + String newKey = toDotCase(key); + if (result.containsKey(newKey)) { + monitor.severe("Duplicate Config Property: %s: %s -> %s".formatted(key, result.get(newKey), value)); + } + result.put(newKey, value); + }); + return result; + } + + @NotNull + private String toDotCase(String key) { + return key.toLowerCase().replace("_", "."); + } +} diff --git a/config/src/main/java/de/sovity/edc/utils/config/ConfigUtils.java b/config/src/main/java/de/sovity/edc/utils/config/ConfigUtils.java new file mode 100644 index 000000000..d27557998 --- /dev/null +++ b/config/src/main/java/de/sovity/edc/utils/config/ConfigUtils.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2023 sovity 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: + * sovity GmbH - init + * + */ + +package de.sovity.edc.utils.config; + +import de.sovity.edc.utils.config.utils.UrlPathUtils; +import lombok.experimental.UtilityClass; + +import java.util.Map; + +@UtilityClass +public class ConfigUtils { + + public static String getProtocolApiUrl(Map props) { + var hasReverseProxy = ConfigProps.NetworkType.isProduction(props); + + var host = ConfigProps.MY_EDC_FQDN.getRaw(props); + if (!hasReverseProxy) { + host = "%s:%s".formatted(host, ConfigProps.WEB_HTTP_PROTOCOL_PORT.getRaw(props)); + } + + return UrlPathUtils.urlPathJoin( + ConfigProps.MY_EDC_PROTOCOL.getRaw(props), + host, + ConfigProps.WEB_HTTP_PROTOCOL_PATH.getRaw(props) + ); + } + + public static String getManagementApiUrl(Map props) { + var hasReverseProxy = ConfigProps.NetworkType.isProduction(props); + + var host = ConfigProps.MY_EDC_FQDN.getRaw(props); + if (!hasReverseProxy) { + host = "%s:%s".formatted(host, ConfigProps.WEB_HTTP_MANAGEMENT_PORT.getRaw(props)); + } + + return UrlPathUtils.urlPathJoin( + ConfigProps.MY_EDC_PROTOCOL.getRaw(props), + host, + ConfigProps.WEB_HTTP_MANAGEMENT_PATH.getRaw(props) + ); + } + + public static String getManagementApiKey(Map props) { + return ConfigProps.EDC_API_AUTH_KEY.getRaw(props); + } + + public static String getDefaultApiUrl(Map props) { + var hasReverseProxy = ConfigProps.NetworkType.isProduction(props); + + var host = ConfigProps.MY_EDC_FQDN.getRaw(props); + if (!hasReverseProxy) { + host = "%s:%s".formatted(host, ConfigProps.WEB_HTTP_PORT.getRaw(props)); + } + + return UrlPathUtils.urlPathJoin( + ConfigProps.MY_EDC_PROTOCOL.getRaw(props), + host, + ConfigProps.WEB_HTTP_PATH.getRaw(props) + ); + } + + public static String getPublicApiUrl(Map props) { + var hasReverseProxy = ConfigProps.NetworkType.isProduction(props); + + var host = ConfigProps.MY_EDC_FQDN.getRaw(props); + if (!hasReverseProxy) { + host = "%s:%s".formatted(host, ConfigProps.WEB_HTTP_PUBLIC_PORT.getRaw(props)); + } + + return UrlPathUtils.urlPathJoin( + ConfigProps.MY_EDC_PROTOCOL.getRaw(props), + host, + ConfigProps.WEB_HTTP_PUBLIC_PATH.getRaw(props) + ); + } +} diff --git a/config/src/main/java/de/sovity/edc/utils/config/SovityEdcRuntime.java b/config/src/main/java/de/sovity/edc/utils/config/SovityEdcRuntime.java new file mode 100644 index 000000000..90bbe14be --- /dev/null +++ b/config/src/main/java/de/sovity/edc/utils/config/SovityEdcRuntime.java @@ -0,0 +1,31 @@ +package de.sovity.edc.utils.config; + +import de.sovity.edc.utils.config.model.ConfigProp; +import lombok.RequiredArgsConstructor; +import org.eclipse.edc.boot.system.runtime.BaseRuntime; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Custom {@link BaseRuntime} for applying config defaults on EDC startup + */ +@RequiredArgsConstructor +public class SovityEdcRuntime extends BaseRuntime { + /** + * Will be evaluated in sequence to apply default config values and validate the configuration. + */ + private final List configProps; + + public static void boot(List configProps) { + var runtime = new SovityEdcRuntime(configProps); + runtime.boot(); + } + + @Override + protected @NotNull ServiceExtensionContext createContext(Monitor monitor) { + return new SovityServiceExtensionContext(monitor, configProps, this.loadConfigurationExtensions()); + } +} diff --git a/config/src/main/java/de/sovity/edc/utils/config/SovityServiceExtensionContext.java b/config/src/main/java/de/sovity/edc/utils/config/SovityServiceExtensionContext.java new file mode 100644 index 000000000..a21522383 --- /dev/null +++ b/config/src/main/java/de/sovity/edc/utils/config/SovityServiceExtensionContext.java @@ -0,0 +1,55 @@ +package de.sovity.edc.utils.config; + +import de.sovity.edc.utils.config.model.ConfigProp; +import org.eclipse.edc.boot.system.DefaultServiceExtensionContext; +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.ConfigurationExtension; +import org.eclipse.edc.spi.system.ServiceExtensionContext; +import org.eclipse.edc.spi.system.configuration.Config; +import org.eclipse.edc.spi.system.configuration.ConfigFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Custom {@link ServiceExtensionContext} for applying config defaults on EDC startup + */ +public class SovityServiceExtensionContext extends DefaultServiceExtensionContext { + /** + * Will be evaluated in sequence to apply default config values and validate the configuration. + */ + private final List configProps; + private final List configurationExtensions; + private final Config config; + + public SovityServiceExtensionContext(Monitor monitor, List configProps, List configurationExtensions) { + super(monitor, configurationExtensions); + this.configProps = configProps; + this.configurationExtensions = configurationExtensions; + this.config = loadValidatedConfigWithDefaults(); + } + + @Override + public Config getConfig(String path) { + return this.config.getConfig(path); + } + + private Config loadValidatedConfigWithDefaults() { + var configs = new ArrayList(); + + this.configurationExtensions.stream() + .map(ConfigurationExtension::getConfig) + .filter(Objects::nonNull) + .forEach(configs::add); + + configs.add(ConfigFactory.fromEnvironment(System.getenv())); + configs.add(ConfigFactory.fromProperties(System.getProperties())); + + var rawConfig = configs.stream().reduce(Config::merge) + .orElseGet(ConfigFactory::empty); + + var configService = new ConfigService(getMonitor(), configProps); + return ConfigFactory.fromMap(configService.applyDefaults(rawConfig.getEntries())); + } +} diff --git a/config/src/main/java/de/sovity/edc/utils/config/model/ConfigProp.java b/config/src/main/java/de/sovity/edc/utils/config/model/ConfigProp.java new file mode 100644 index 000000000..afe4a0281 --- /dev/null +++ b/config/src/main/java/de/sovity/edc/utils/config/model/ConfigProp.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 sovity 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: + * sovity GmbH - init + * + */ + +package de.sovity.edc.utils.config.model; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.eclipse.edc.spi.system.configuration.Config; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.function.Consumer; + +@Setter +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class ConfigProp { + @NotNull + private String property; + + @NotNull + private String category; + + @NotNull + private String description; + + private ConfigPropRequiredIfFn relevantIf; + + private boolean required; + private ConfigPropRequiredIfFn requiredIf; + private String defaultValue; + private ConfigPropDefaultValueFn defaultValueFn; + + private boolean warnIfOverridden; + private boolean warnIfUnset; + + public ConfigProp also(Consumer fn) { + fn.accept(this); + return this; + } + + @Nullable + public String getRaw(Map props) { + return props.get(property); + } + + public String getStringOrNull(Config config) { + return config.getString(property, null); + } + + public String getStringOrEmpty(Config config) { + // Default should already be handled by ConfigProp + return config.getString(property, ""); + } + + public Boolean getBoolean(Config config) { + // Default should already be handled by ConfigProp + return config.getBoolean(property); + } + + public Integer getInt(Config config) { + // Default should already be handled by ConfigProp + return config.getInteger(property); + } +} diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/NoneAuthProvider.java b/config/src/main/java/de/sovity/edc/utils/config/model/ConfigPropDefaultValueFn.java similarity index 54% rename from utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/NoneAuthProvider.java rename to config/src/main/java/de/sovity/edc/utils/config/model/ConfigPropDefaultValueFn.java index af59e7eb3..c0e581326 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/NoneAuthProvider.java +++ b/config/src/main/java/de/sovity/edc/utils/config/model/ConfigPropDefaultValueFn.java @@ -12,16 +12,16 @@ * */ -package de.sovity.edc.extension.e2e.connector.config.api.auth; +package de.sovity.edc.utils.config.model; -public class NoneAuthProvider implements AuthProvider { - @Override - public String getAuthorizationHeader() { - return ""; - } +import java.util.Map; + + +@FunctionalInterface +public interface ConfigPropDefaultValueFn { + String apply(Map props); - @Override - public String getAuthorizationHeaderValue() { - return ""; + static ConfigPropDefaultValueFn constant(String value) { + return p -> value; } } diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/AuthProvider.java b/config/src/main/java/de/sovity/edc/utils/config/model/ConfigPropRequiredIfFn.java similarity index 65% rename from utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/AuthProvider.java rename to config/src/main/java/de/sovity/edc/utils/config/model/ConfigPropRequiredIfFn.java index a2e11a921..d6a9c338f 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/AuthProvider.java +++ b/config/src/main/java/de/sovity/edc/utils/config/model/ConfigPropRequiredIfFn.java @@ -12,11 +12,12 @@ * */ -package de.sovity.edc.extension.e2e.connector.config.api.auth; +package de.sovity.edc.utils.config.model; -public interface AuthProvider { +import java.util.Map; - String getAuthorizationHeader(); - String getAuthorizationHeaderValue(); +@FunctionalInterface +public interface ConfigPropRequiredIfFn { + boolean predicate(Map props); } diff --git a/config/src/main/java/de/sovity/edc/utils/config/utils/UrlPathUtils.java b/config/src/main/java/de/sovity/edc/utils/config/utils/UrlPathUtils.java new file mode 100644 index 000000000..cfd8cd9b6 --- /dev/null +++ b/config/src/main/java/de/sovity/edc/utils/config/utils/UrlPathUtils.java @@ -0,0 +1,30 @@ +package de.sovity.edc.utils.config.utils; + +import lombok.experimental.UtilityClass; + +import java.util.Objects; +import java.util.stream.Stream; + +@UtilityClass +public class UrlPathUtils { + public static String urlPathJoin(String... parts) { + return Stream.of(parts) + .filter(Objects::nonNull) + .filter(it -> !it.isEmpty()) + .reduce("", (cur, add) -> { + // Special Case: https:// + if (add.contains("://")) { + return add; + } + + // Join with a single slash + if (cur.endsWith("/") && add.startsWith("/")) { + return cur + add.substring(1); + } else if (!cur.isEmpty() && !cur.endsWith("/") && !add.startsWith("/")) { + return cur + "/" + add; + } else { + return cur + add; + } + }); + } +} diff --git a/config/src/test/java/UrlPathUtilsTest.java b/config/src/test/java/UrlPathUtilsTest.java new file mode 100644 index 000000000..551ee4ba5 --- /dev/null +++ b/config/src/test/java/UrlPathUtilsTest.java @@ -0,0 +1,53 @@ +import org.junit.jupiter.api.Test; + +import static de.sovity.edc.utils.config.utils.UrlPathUtils.urlPathJoin; +import static org.assertj.core.api.Assertions.assertThat; + +class UrlPathUtilsTest { + @Test + void urlPathJoin_empty() { + assertThat(urlPathJoin()).isEmpty(); + assertThat(urlPathJoin("")).isEmpty(); + assertThat(urlPathJoin("/")).isEqualTo("/"); + } + + @Test + void urlPathJoin_relative() { + assertThat(urlPathJoin("a")).isEqualTo("a"); + assertThat(urlPathJoin("a/")).isEqualTo("a/"); + assertThat(urlPathJoin("a", "b")).isEqualTo("a/b"); + assertThat(urlPathJoin("a/", "b")).isEqualTo("a/b"); + assertThat(urlPathJoin("a", "/b")).isEqualTo("a/b"); + assertThat(urlPathJoin("a/", "/b")).isEqualTo("a/b"); + } + + @Test + void urlPathJoin_absolute() { + assertThat(urlPathJoin("/a")).isEqualTo("/a"); + assertThat(urlPathJoin("/a/")).isEqualTo("/a/"); + assertThat(urlPathJoin("/a", "b")).isEqualTo("/a/b"); + assertThat(urlPathJoin("/a/", "b")).isEqualTo("/a/b"); + assertThat(urlPathJoin("/a", "/b")).isEqualTo("/a/b"); + assertThat(urlPathJoin("/a/", "/b")).isEqualTo("/a/b"); + } + + @Test + void urlPathJoin_protocol() { + assertThat(urlPathJoin("https://a")).isEqualTo("https://a"); + assertThat(urlPathJoin("https://a/")).isEqualTo("https://a/"); + assertThat(urlPathJoin("https://a", "b")).isEqualTo("https://a/b"); + assertThat(urlPathJoin("https://a/", "b")).isEqualTo("https://a/b"); + assertThat(urlPathJoin("https://a", "/b")).isEqualTo("https://a/b"); + assertThat(urlPathJoin("https://a/", "/b")).isEqualTo("https://a/b"); + } + + @Test + void urlPathJoin_protocol_overrules_previous_segment() { + assertThat(urlPathJoin("https://ignored", "https://a")).isEqualTo("https://a"); + assertThat(urlPathJoin("https://ignored", "https://a/")).isEqualTo("https://a/"); + assertThat(urlPathJoin("https://ignored", "https://a", "b")).isEqualTo("https://a/b"); + assertThat(urlPathJoin("https://ignored", "https://a/", "b")).isEqualTo("https://a/b"); + assertThat(urlPathJoin("https://ignored", "https://a", "/b")).isEqualTo("https://a/b"); + assertThat(urlPathJoin("https://ignored", "https://a/", "/b")).isEqualTo("https://a/b"); + } +} diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml index 8dfd7e1af..36f289878 100644 --- a/docker-compose-dev.yaml +++ b/docker-compose-dev.yaml @@ -20,7 +20,17 @@ services: postgresql: condition: service_healthy environment: + MY_EDC_NETWORK_TYPE: local-demo-docker-compose + EDC_API_AUTH_KEY: ApiKeyDefaultValue + MY_EDC_FQDN: "edc" + + MY_EDC_C2C_IAM_TYPE: "mock-iam" MY_EDC_PARTICIPANT_ID: "my-edc" + + MY_EDC_JDBC_URL: jdbc:postgresql://postgresql:5432/edc + MY_EDC_JDBC_USER: edc + MY_EDC_JDBC_PASSWORD: edc + MY_EDC_TITLE: "EDC Connector" MY_EDC_DESCRIPTION: "sovity Community Edition EDC Connector" MY_EDC_CURATOR_URL: "https://example.com" @@ -28,21 +38,6 @@ services: MY_EDC_MAINTAINER_URL: "https://sovity.de" MY_EDC_MAINTAINER_NAME: "sovity GmbH" - MY_EDC_FQDN: "edc" - EDC_API_AUTH_KEY: ApiKeyDefaultValue - - MY_EDC_JDBC_URL: jdbc:postgresql://postgresql:5432/edc - MY_EDC_JDBC_USER: edc - MY_EDC_JDBC_PASSWORD: edc - - # docker compose local dev environment overrides (don't use with non-dev images) - MY_EDC_PROTOCOL: "http://" - EDC_DSP_CALLBACK_ADDRESS: http://edc:11003/api/dsp - EDC_WEB_REST_CORS_ENABLED: 'true' - EDC_WEB_REST_CORS_HEADERS: 'origin,content-type,accept,authorization,X-Api-Key' - EDC_WEB_REST_CORS_ORIGINS: '*' - EDC_AGENT_IDENTITY_KEY: 'client_id' # required for Mock IAM to work - ports: - '11001:11001' - '11002:11002' @@ -68,7 +63,17 @@ services: postgresql2: condition: service_healthy environment: + MY_EDC_NETWORK_TYPE: local-demo-docker-compose + EDC_API_AUTH_KEY: ApiKeyDefaultValue + MY_EDC_FQDN: "edc2" + + MY_EDC_C2C_IAM_TYPE: "mock-iam" MY_EDC_PARTICIPANT_ID: "my-edc2" + + MY_EDC_JDBC_URL: jdbc:postgresql://postgresql2:5432/edc + MY_EDC_JDBC_USER: edc + MY_EDC_JDBC_PASSWORD: edc + MY_EDC_TITLE: "EDC Connector 2" MY_EDC_DESCRIPTION: "sovity Community Edition EDC Connector" MY_EDC_CURATOR_URL: "https://example.com" @@ -76,21 +81,6 @@ services: MY_EDC_MAINTAINER_URL: "https://sovity.de" MY_EDC_MAINTAINER_NAME: "sovity GmbH" - MY_EDC_FQDN: "edc2" - EDC_API_AUTH_KEY: ApiKeyDefaultValue - - MY_EDC_JDBC_URL: jdbc:postgresql://postgresql2:5432/edc - MY_EDC_JDBC_USER: edc - MY_EDC_JDBC_PASSWORD: edc - - # docker compose local dev environment overrides (don't use with non-dev images) - MY_EDC_PROTOCOL: "http://" - EDC_DSP_CALLBACK_ADDRESS: http://edc2:11003/api/dsp - EDC_WEB_REST_CORS_ENABLED: 'true' - EDC_WEB_REST_CORS_HEADERS: 'origin,content-type,accept,authorization,X-Api-Key' - EDC_WEB_REST_CORS_ORIGINS: '*' - EDC_AGENT_IDENTITY_KEY: 'client_id' # required for Mock IAM to work - ports: - '22001:11001' - '22002:11002' diff --git a/docs/api/sovity-edc-api-wrapper.yaml b/docs/api/sovity-edc-api-wrapper.yaml index 8cda83f2b..0b2e49462 100644 --- a/docs/api/sovity-edc-api-wrapper.yaml +++ b/docs/api/sovity-edc-api-wrapper.yaml @@ -623,11 +623,11 @@ components: DataSourceType: type: string description: Supported Data Source Types by UiDataSource + default: CUSTOM enum: - HTTP_DATA - ON_REQUEST - CUSTOM - default: CUSTOM SecretValue: type: object properties: @@ -835,6 +835,7 @@ components: UiDataSourceHttpDataMethod: type: string description: Supported HTTP Methods by UiDataSource + default: GET enum: - GET - POST @@ -842,7 +843,6 @@ components: - PATCH - DELETE - OPTIONS - default: GET UiDataSourceOnRequest: required: - contactEmail diff --git a/extensions/contract-termination/build.gradle.kts b/extensions/contract-termination/build.gradle.kts index bcb87a44e..8e0ae126a 100644 --- a/extensions/contract-termination/build.gradle.kts +++ b/extensions/contract-termination/build.gradle.kts @@ -8,6 +8,7 @@ dependencies { annotationProcessor(libs.lombok) compileOnly(libs.lombok) + implementation(project(":config")) implementation(project(":utils:jooq-database-access")) implementation(project(":extensions:database-direct-access")) implementation(project(":extensions:sovity-messenger")) diff --git a/extensions/contract-termination/src/main/java/de/sovity/edc/extension/contacttermination/ContractTerminationExtension.java b/extensions/contract-termination/src/main/java/de/sovity/edc/extension/contacttermination/ContractTerminationExtension.java index 84bb39b0f..bd51bc29c 100644 --- a/extensions/contract-termination/src/main/java/de/sovity/edc/extension/contacttermination/ContractTerminationExtension.java +++ b/extensions/contract-termination/src/main/java/de/sovity/edc/extension/contacttermination/ContractTerminationExtension.java @@ -20,13 +20,12 @@ import de.sovity.edc.extension.db.directaccess.DslContextFactory; import de.sovity.edc.extension.messenger.SovityMessenger; import de.sovity.edc.extension.messenger.SovityMessengerRegistry; +import de.sovity.edc.utils.config.ConfigProps; import lombok.val; import org.eclipse.edc.connector.transfer.spi.observe.TransferProcessObservable; import org.eclipse.edc.runtime.metamodel.annotation.Inject; import org.eclipse.edc.runtime.metamodel.annotation.Provides; -import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.agent.ParticipantAgentService; -import org.eclipse.edc.spi.iam.IdentityService; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; @@ -35,15 +34,9 @@ @Provides(ContractAgreementTerminationService.class) public class ContractTerminationExtension implements ServiceExtension { - @Setting(required = true) - private static final String EDC_PARTICIPANT_ID = "edc.participant.id"; - @Inject private DslContextFactory dslContextFactory; - @Inject - private IdentityService identityService; - @Inject private Monitor monitor; @@ -78,7 +71,7 @@ private ContractAgreementTerminationService setupTerminationService(ServiceExten contractAgreementTerminationDetailsQuery, terminateContractQuery, monitor, - config.getString(EDC_PARTICIPANT_ID) + ConfigProps.EDC_PARTICIPANT_ID.getStringOrEmpty(config) ); context.registerService(ContractAgreementTerminationService.class, terminationService); diff --git a/extensions/contract-termination/src/test/java/de/sovity/edc/extension/contacttermination/query/ContractAgreementTerminationDetailsQueryTest.java b/extensions/contract-termination/src/test/java/de/sovity/edc/extension/contacttermination/query/ContractAgreementTerminationDetailsQueryTest.java index ebc74740c..b937b9131 100644 --- a/extensions/contract-termination/src/test/java/de/sovity/edc/extension/contacttermination/query/ContractAgreementTerminationDetailsQueryTest.java +++ b/extensions/contract-termination/src/test/java/de/sovity/edc/extension/contacttermination/query/ContractAgreementTerminationDetailsQueryTest.java @@ -60,7 +60,7 @@ void fetchAgreementDetailsOrThrow_whenAgreementIsPresent_shouldReturnTheAgreemen assertThat(details).isEqualTo(ContractAgreementTerminationDetails.builder() .contractAgreementId(agreementId) .counterpartyId("provider") - .counterpartyAddress(providerConfig.getProtocolEndpoint().getUri().toString()) + .counterpartyAddress(providerConfig.getProtocolApiUrl()) .type(CONSUMER) .providerAgentId("provider") .consumerAgentId("consumer") @@ -113,7 +113,7 @@ void fetchAgreementDetailsOrThrow_whenTerminationAlreadyExists_shouldReturnOptio // assert assertThat(details.contractAgreementId()).isEqualTo(agreementId); assertThat(details.counterpartyId()).isEqualTo("provider"); - assertThat(details.counterpartyAddress()).isEqualTo(providerConfig.getProtocolEndpoint().getUri().toString()); + assertThat(details.counterpartyAddress()).isEqualTo(providerConfig.getProtocolApiUrl()); assertThat(details.type()).isEqualTo(CONSUMER); assertThat(details.providerAgentId()).isEqualTo("provider"); assertThat(details.consumerAgentId()).isEqualTo("consumer"); diff --git a/extensions/contract-termination/src/test/java/de/sovity/edc/extension/contacttermination/query/TerminateContractQueryTest.java b/extensions/contract-termination/src/test/java/de/sovity/edc/extension/contacttermination/query/TerminateContractQueryTest.java index b7000d35a..ce40e4670 100644 --- a/extensions/contract-termination/src/test/java/de/sovity/edc/extension/contacttermination/query/TerminateContractQueryTest.java +++ b/extensions/contract-termination/src/test/java/de/sovity/edc/extension/contacttermination/query/TerminateContractQueryTest.java @@ -76,7 +76,7 @@ void terminateConsumerAgreementOrThrow_shouldInsertRowInTerminationTable( assertThat(detailsAfterTermination.contractAgreementId()).isEqualTo(agreementId); assertThat(detailsAfterTermination.counterpartyId()).isEqualTo("provider"); assertThat(detailsAfterTermination.counterpartyAddress()) - .isEqualTo(providerConfig.getProtocolEndpoint().getUri().toString()); + .isEqualTo(providerConfig.getProtocolApiUrl()); assertThat(detailsAfterTermination.type()).isEqualTo(ContractNegotiation.Type.CONSUMER); assertThat(detailsAfterTermination.providerAgentId()).isEqualTo("provider"); assertThat(detailsAfterTermination.consumerAgentId()).isEqualTo("consumer"); diff --git a/extensions/database-direct-access/build.gradle.kts b/extensions/database-direct-access/build.gradle.kts index 3aecfb4d1..d6ecd6c16 100644 --- a/extensions/database-direct-access/build.gradle.kts +++ b/extensions/database-direct-access/build.gradle.kts @@ -8,6 +8,7 @@ dependencies { annotationProcessor(libs.lombok) compileOnly(libs.lombok) + implementation(project(":config")) implementation(libs.edc.coreSpi) implementation(libs.jooq.jooq) diff --git a/extensions/database-direct-access/src/main/java/de/sovity/edc/extension/db/directaccess/DatabaseDirectAccessExtension.java b/extensions/database-direct-access/src/main/java/de/sovity/edc/extension/db/directaccess/DatabaseDirectAccessExtension.java index 480fb0d41..869644143 100644 --- a/extensions/database-direct-access/src/main/java/de/sovity/edc/extension/db/directaccess/DatabaseDirectAccessExtension.java +++ b/extensions/database-direct-access/src/main/java/de/sovity/edc/extension/db/directaccess/DatabaseDirectAccessExtension.java @@ -16,9 +16,9 @@ import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +import de.sovity.edc.utils.config.ConfigProps; import lombok.val; import org.eclipse.edc.runtime.metamodel.annotation.Provides; -import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; @@ -26,30 +26,6 @@ public class DatabaseDirectAccessExtension implements ServiceExtension { public static final String NAME = "DirectDatabaseAccess"; - /** - * The JDBC URL. - */ - @Setting(required = true) - public static final String EDC_DATASOURCE_DEFAULT_URL = "edc.datasource.default.url"; - - /** - * The JDBC user. - */ - @Setting(required = true) - public static final String EDC_DATASOURCE_JDBC_USER = "edc.datasource.default.user"; - - /** - * The JDBC password. - */ - @Setting(required = true) - public static final String EDC_DATASOURCE_JDBC_PASSWORD = "edc.datasource.default.password"; - - /** - * Sets the connection pool size to use during the flyway migration. - */ - @Setting(defaultValue = "3") - public static final String EDC_SERVER_DB_CONNECTION_POOL_SIZE = "edc.server.db.connection.pool.size"; - @Override public String name() { @@ -65,11 +41,11 @@ private void initializeDirectDatabaseAccess(ServiceExtensionContext context) { val hikariConfig = new HikariConfig(); val config = context.getConfig(); - hikariConfig.setJdbcUrl(config.getString(EDC_DATASOURCE_DEFAULT_URL)); - hikariConfig.setUsername(config.getString(EDC_DATASOURCE_JDBC_USER)); - hikariConfig.setPassword(config.getString(EDC_DATASOURCE_JDBC_PASSWORD)); + hikariConfig.setJdbcUrl(ConfigProps.EDC_DATASOURCE_DEFAULT_URL.getStringOrNull(config)); + hikariConfig.setUsername(ConfigProps.EDC_DATASOURCE_DEFAULT_USER.getStringOrNull(config)); + hikariConfig.setPassword(ConfigProps.EDC_DATASOURCE_DEFAULT_PASSWORD.getStringOrNull(config)); hikariConfig.setMinimumIdle(1); - hikariConfig.setMaximumPoolSize(config.getInteger(EDC_SERVER_DB_CONNECTION_POOL_SIZE, 3)); + hikariConfig.setMaximumPoolSize(config.getInteger(ConfigProps.EDC_SERVER_DB_CONNECTION_POOL_SIZE.getProperty(), 3)); hikariConfig.setIdleTimeout(30000); hikariConfig.setPoolName("direct-database-access"); hikariConfig.setMaxLifetime(50000); diff --git a/extensions/database-direct-access/src/main/java/de/sovity/edc/extension/db/directaccess/DslContextFactory.java b/extensions/database-direct-access/src/main/java/de/sovity/edc/extension/db/directaccess/DslContextFactory.java index dbca8cca0..1c85513ce 100644 --- a/extensions/database-direct-access/src/main/java/de/sovity/edc/extension/db/directaccess/DslContextFactory.java +++ b/extensions/database-direct-access/src/main/java/de/sovity/edc/extension/db/directaccess/DslContextFactory.java @@ -35,7 +35,7 @@ private DSLContext newDslContext() { } public void transaction(Consumer consumer) { - newDslContext().transaction((trx) -> consumer.accept(trx.dsl())); + newDslContext().transaction(trx -> consumer.accept(trx.dsl())); } /** @@ -53,6 +53,6 @@ public void rollbackTransaction(Consumer consumer) { } public T transactionResult(Function f) { - return newDslContext().transactionResult((trx) -> f.apply(trx.dsl())); + return newDslContext().transactionResult(trx -> f.apply(trx.dsl())); } } diff --git a/extensions/postgres-flyway/build.gradle.kts b/extensions/postgres-flyway/build.gradle.kts index 96b90d1b5..bf3e52c75 100644 --- a/extensions/postgres-flyway/build.gradle.kts +++ b/extensions/postgres-flyway/build.gradle.kts @@ -8,6 +8,8 @@ dependencies { annotationProcessor(libs.lombok) compileOnly(libs.lombok) + implementation(project(":config")) + implementation(libs.edc.coreSpi) implementation(libs.edc.sqlCore) diff --git a/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/FlywayMigrator.java b/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/FlywayMigrator.java index 03764ceba..1679f6ccd 100644 --- a/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/FlywayMigrator.java +++ b/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/FlywayMigrator.java @@ -4,6 +4,7 @@ import de.sovity.edc.extension.postgresql.legacy.migration.DatabaseMigrationManager; import de.sovity.edc.extension.postgresql.legacy.migration.FlywayService; import de.sovity.edc.extension.postgresql.utils.DatabaseUtils; +import de.sovity.edc.utils.config.ConfigProps; import lombok.val; import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.persistence.EdcPersistenceException; @@ -76,11 +77,11 @@ private void cleanDatabase() { if (shouldClean) { if (!canClean) { throw new IllegalStateException("In order to clean the history both %s and %s must be set to true.".formatted( - PostgresFlywayExtension.FLYWAY_CLEAN, PostgresFlywayExtension.FLYWAY_CLEAN_ENABLE + ConfigProps.EDC_FLYWAY_CLEAN.getProperty(), ConfigProps.EDC_FLYWAY_CLEAN_ENABLE.getProperty() )); } monitor.info(() -> "Cleaning database before migrations, since %s=true and %s=true.".formatted( - PostgresFlywayExtension.FLYWAY_CLEAN_ENABLE, PostgresFlywayExtension.FLYWAY_CLEAN + ConfigProps.EDC_FLYWAY_CLEAN.getProperty(), ConfigProps.EDC_FLYWAY_CLEAN_ENABLE.getProperty() )); val flyway = flywayFactory.setupFlywayForUnifiedHistory(dataSource); diff --git a/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/PostgresFlywayConfig.java b/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/PostgresFlywayConfig.java index 2eedacd1e..d7a98b886 100644 --- a/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/PostgresFlywayConfig.java +++ b/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/PostgresFlywayConfig.java @@ -15,38 +15,32 @@ package de.sovity.edc.extension.postgresql; import de.sovity.edc.extension.postgresql.utils.JdbcCredentials; -import org.apache.commons.lang3.Validate; +import de.sovity.edc.utils.config.ConfigProps; import org.eclipse.edc.spi.system.configuration.Config; public record PostgresFlywayConfig( - JdbcCredentials jdbcCredentials, - boolean flywayRepair, - boolean flywayCleanEnabled, - boolean flywayClean, - String edcFlywayAdditionalMigrationLocations, - int poolSize, - int connectionTimeoutInMs) { + JdbcCredentials jdbcCredentials, + boolean flywayRepair, + boolean flywayCleanEnabled, + boolean flywayClean, + String edcFlywayAdditionalMigrationLocations, + int poolSize, + int connectionTimeoutInMs +) { public static PostgresFlywayConfig fromConfig(Config config) { return new PostgresFlywayConfig( - new JdbcCredentials( - getRequiredStringProperty(config, PostgresFlywayExtension.JDBC_URL), - getRequiredStringProperty(config, PostgresFlywayExtension.JDBC_USER), - getRequiredStringProperty(config, PostgresFlywayExtension.JDBC_PASSWORD) - ), - config.getBoolean(PostgresFlywayExtension.EDC_DATASOURCE_REPAIR_SETTING, false), - config.getBoolean(PostgresFlywayExtension.FLYWAY_CLEAN_ENABLE, false), - config.getBoolean(PostgresFlywayExtension.FLYWAY_CLEAN, false), - config.getString(PostgresFlywayExtension.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, ""), - config.getInteger(PostgresFlywayExtension.DB_CONNECTION_POOL_SIZE, 3), - config.getInteger(PostgresFlywayExtension.DB_CONNECTION_TIMEOUT_IN_MS, 5000) + new JdbcCredentials( + ConfigProps.EDC_DATASOURCE_DEFAULT_URL.getStringOrNull(config), + ConfigProps.EDC_DATASOURCE_DEFAULT_USER.getStringOrNull(config), + ConfigProps.EDC_DATASOURCE_DEFAULT_PASSWORD.getStringOrNull(config) + ), + ConfigProps.EDC_FLYWAY_REPAIR.getBoolean(config), + ConfigProps.EDC_FLYWAY_CLEAN_ENABLE.getBoolean(config), + ConfigProps.EDC_FLYWAY_CLEAN.getBoolean(config), + ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS.getStringOrEmpty(config), + ConfigProps.EDC_SERVER_DB_CONNECTION_POOL_SIZE.getInt(config), + ConfigProps.EDC_SERVER_DB_CONNECTION_TIMEOUT_IN_MS.getInt(config) ); } - - public static String getRequiredStringProperty(Config config, String name) { - String value = config.getString(name, ""); - Validate.notBlank(value, "EDC Property '%s' is required".formatted(name)); - return value; - } - } diff --git a/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/PostgresFlywayExtension.java b/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/PostgresFlywayExtension.java index 28afc4ae9..4103f3b87 100644 --- a/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/PostgresFlywayExtension.java +++ b/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/PostgresFlywayExtension.java @@ -16,74 +16,10 @@ import com.zaxxer.hikari.HikariDataSource; import lombok.val; -import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; public class PostgresFlywayExtension implements ServiceExtension { - - /** - * The JDBC URL. - */ - @Setting(required = true) - public static final String JDBC_URL = "edc.datasource.default.url"; - - /** - * The JDBC user. - */ - @Setting(required = true) - public static final String JDBC_USER = "edc.datasource.default.user"; - - /** - * The JDBC password. - */ - @Setting(required = true) - public static final String JDBC_PASSWORD = "edc.datasource.default.password"; - - /** - * Attempts to fix the history when a migration fails. Only supported in older migration scripts. - */ - @Setting(defaultValue = "false") - public static final String EDC_DATASOURCE_REPAIR_SETTING = "edc.flyway.repair"; - - /** - * Allows the deletion of the database. Goes in pair with {@link #FLYWAY_CLEAN}. Both options must be enabled for a clean to happen. - */ - @Setting(defaultValue = "false") - public static final String FLYWAY_CLEAN_ENABLE = "edc.flyway.clean.enable"; - - /** - * Request the deletion of the database. Goes in pair with {@link #FLYWAY_CLEAN_ENABLE}. Both options must be enabled for a clean to happen. - */ - @Setting(defaultValue = "false") - public static final String FLYWAY_CLEAN = "edc.flyway.clean"; - - /** - * Sets the connection pool size to use during the flyway migration. - */ - @Setting(defaultValue = "3") - public static final String DB_CONNECTION_POOL_SIZE = "edc.server.db.connection.pool.size"; - - /** - * Sets the connection timeout for the datasource in milliseconds. - */ - @Setting(defaultValue = "5000") - public static final String DB_CONNECTION_TIMEOUT_IN_MS = "edc.server.db.connection.timeout.in.ms"; - - /** - * Coma-separated list of additional migration scripts files. - *
- * Additional Migration Scripts can be added by specifying the configuration property - * `edc.flyway.additional.migration.locations`. - *
- * Values are comma separated and need to be correct FlyWay migration script locations. - * These migration scripts need to be compatible with the migrations in {@code resources/db/migration} and {@code resources/db/migration/legacy}. - *
- */ - @Setting(defaultValue = "") - public static final String EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS = "edc.flyway.additional.migration.locations"; - - private HikariDataSource dataSource; @Override diff --git a/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/legacy/migration/DatabaseMigrationManager.java b/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/legacy/migration/DatabaseMigrationManager.java index 659d4dee7..1e7dd4539 100644 --- a/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/legacy/migration/DatabaseMigrationManager.java +++ b/extensions/postgres-flyway/src/main/java/de/sovity/edc/extension/postgresql/legacy/migration/DatabaseMigrationManager.java @@ -15,15 +15,13 @@ package de.sovity.edc.extension.postgresql.legacy.migration; import de.sovity.edc.extension.postgresql.legacy.connection.JdbcConnectionProperties; -import org.eclipse.edc.runtime.metamodel.annotation.Setting; +import de.sovity.edc.utils.config.ConfigProps; import org.eclipse.edc.spi.system.configuration.Config; import java.util.Arrays; import java.util.List; public class DatabaseMigrationManager { - @Setting - public static final String EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS = "edc.flyway.additional.migration.locations"; private static final String DEFAULT_DATASOURCE = "default"; private final Config config; @@ -62,7 +60,7 @@ public List getAdditionalFlywayMigrationLocations(String datasourceName) return List.of(); } - String commaJoined = config.getString(EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, ""); + String commaJoined = ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS.getStringOrEmpty(config); return Arrays.stream(commaJoined.split(",")) .map(String::trim) .filter(it -> !it.isEmpty()) diff --git a/extensions/sovity-messenger/src/test/java/de/sovity/edc/extension/messenger/SovityMessengerExtensionE2eTest.java b/extensions/sovity-messenger/src/test/java/de/sovity/edc/extension/messenger/SovityMessengerExtensionE2eTest.java index 898c9645f..41241378c 100644 --- a/extensions/sovity-messenger/src/test/java/de/sovity/edc/extension/messenger/SovityMessengerExtensionE2eTest.java +++ b/extensions/sovity-messenger/src/test/java/de/sovity/edc/extension/messenger/SovityMessengerExtensionE2eTest.java @@ -66,7 +66,7 @@ void setup() { receiverEdcContext.setConfiguration(consumerConfig.getProperties()); receiverEdcContext.registerServiceMock(TokenDecorator.class, (td) -> td); - counterPartyAddress = consumerConfig.getProtocolEndpoint().getUri().toString(); + counterPartyAddress = consumerConfig.getProtocolApiUrl(); } @Test diff --git a/extensions/sovity-messenger/src/test/java/de/sovity/edc/extension/messenger/demo/SovityMessengerDemoTest.java b/extensions/sovity-messenger/src/test/java/de/sovity/edc/extension/messenger/demo/SovityMessengerDemoTest.java index 9a4c57992..7caf8fc8c 100644 --- a/extensions/sovity-messenger/src/test/java/de/sovity/edc/extension/messenger/demo/SovityMessengerDemoTest.java +++ b/extensions/sovity-messenger/src/test/java/de/sovity/edc/extension/messenger/demo/SovityMessengerDemoTest.java @@ -121,6 +121,6 @@ void demo() { @BeforeEach void setup() { - receiverAddress = receiverConfig.getProtocolEndpoint().getUri().toString(); + receiverAddress = receiverConfig.getProtocolApiUrl(); } } diff --git a/extensions/wrapper/wrapper/build.gradle.kts b/extensions/wrapper/wrapper/build.gradle.kts index 027f3c567..76261cc76 100644 --- a/extensions/wrapper/wrapper/build.gradle.kts +++ b/extensions/wrapper/wrapper/build.gradle.kts @@ -8,6 +8,7 @@ dependencies { annotationProcessor(libs.lombok) compileOnly(libs.lombok) + implementation(project(":config")) api(project(":extensions:wrapper:wrapper-api")) api(project(":extensions:wrapper:wrapper-common-mappers")) api(project(":utils:catalog-parser")) diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtension.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtension.java index 3c0f81079..5863f579a 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtension.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtension.java @@ -36,7 +36,6 @@ import org.eclipse.edc.policy.engine.spi.PolicyEngine; import org.eclipse.edc.protocol.dsp.api.configuration.DspApiConfiguration; import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.runtime.metamodel.annotation.Setting; import org.eclipse.edc.spi.CoreConstants; import org.eclipse.edc.spi.asset.AssetIndex; import org.eclipse.edc.spi.system.ServiceExtension; @@ -46,9 +45,6 @@ public class WrapperExtension implements ServiceExtension { - @Setting(value = "Base URL for the On Request asset datasource, as reachable by the data plane") - public static final String MY_EDC_DATASOURCE_PLACEHOLDER_BASEURL = "my.edc.datasource.placeholder.baseurl"; - public static final String EXTENSION_NAME = "WrapperExtension"; @Inject @@ -127,8 +123,6 @@ public void initialize(ServiceExtensionContext context) { typeTransformerRegistry ); - wrapperExtensionContext.selfDescriptionService().validateSelfDescriptionConfig(); - wrapperExtensionContext.managementApiResources().forEach(resource -> webService.registerResource(dataManagementApiConfiguration.getContextAlias(), resource)); diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtensionContextBuilder.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtensionContextBuilder.java index 2e8a40fbc..2c819360b 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtensionContextBuilder.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtensionContextBuilder.java @@ -81,6 +81,7 @@ import de.sovity.edc.extension.db.directaccess.DslContextFactory; import de.sovity.edc.utils.catalog.DspCatalogService; import de.sovity.edc.utils.catalog.mapper.DspDataOfferBuilder; +import de.sovity.edc.utils.config.ConfigProps; import lombok.NoArgsConstructor; import lombok.val; import org.eclipse.edc.connector.contract.spi.negotiation.store.ContractNegotiationStore; @@ -145,10 +146,10 @@ public static WrapperExtensionContext buildContext( var criterionLiteralMapper = new CriterionLiteralMapper(); var criterionMapper = new CriterionMapper(criterionOperatorMapper, criterionLiteralMapper); var edcPropertyUtils = new EdcPropertyUtils(); - var selfDescriptionService = new SelfDescriptionService(config, monitor); + var selfDescriptionService = new SelfDescriptionService(config); var ownConnectorEndpointService = new OwnConnectorEndpointServiceImpl(selfDescriptionService); var placeholderEndpointService = new PlaceholderEndpointService( - config.getString(WrapperExtension.MY_EDC_DATASOURCE_PLACEHOLDER_BASEURL, "http://0.0.0.0") + ConfigProps.MY_EDC_DATASOURCE_PLACEHOLDER_BASEURL.getStringOrEmpty(config) ); var assetMapper = newAssetMapper(typeTransformerRegistry, jsonLd, ownConnectorEndpointService, placeholderEndpointService); var policyMapper = newPolicyMapper(objectMapper, typeTransformerRegistry, operatorMapper); diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/asset/AssetApiService.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/asset/AssetApiService.java index d5d72bdc0..04a0a8f58 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/asset/AssetApiService.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/asset/AssetApiService.java @@ -15,7 +15,6 @@ package de.sovity.edc.ext.wrapper.api.ui.pages.asset; import de.sovity.edc.ext.db.jooq.Tables; -import de.sovity.edc.ext.db.jooq.tables.EdcAsset; import de.sovity.edc.ext.wrapper.api.ServiceException; import de.sovity.edc.ext.wrapper.api.common.mappers.AssetMapper; import de.sovity.edc.ext.wrapper.api.common.model.UiAsset; diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/ConfigPropertyUtils.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/ConfigPropertyUtils.java deleted file mode 100644 index a38d65dde..000000000 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/ConfigPropertyUtils.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.sovity.edc.ext.wrapper.api.ui.pages.dashboard.services; - -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class ConfigPropertyUtils { - - /** - * Maps a {@literal CONFIG_KEY} to {@literal config.key} - * - * @param envVarKey {@literal CONFIG_KEY} - * @return {@literal config.key} - */ - public static String configKey(String envVarKey) { - return String.join(".", envVarKey.split("_")).toLowerCase(); - } -} diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/DapsConfigService.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/DapsConfigService.java index 5d1608d42..41ed3c03c 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/DapsConfigService.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/DapsConfigService.java @@ -15,28 +15,20 @@ package de.sovity.edc.ext.wrapper.api.ui.pages.dashboard.services; import de.sovity.edc.ext.wrapper.api.ui.model.DashboardDapsConfig; +import de.sovity.edc.utils.config.ConfigProps; import lombok.RequiredArgsConstructor; import org.eclipse.edc.spi.system.configuration.Config; import static com.apicatalog.jsonld.StringUtils.isBlank; -import static de.sovity.edc.ext.wrapper.api.ui.pages.dashboard.services.ConfigPropertyUtils.configKey; @RequiredArgsConstructor public class DapsConfigService { private final Config config; - private static final String DAPS_TOKEN_URL = configKey("EDC_OAUTH_TOKEN_URL"); - - private static final String DAPS_JWKS_URL = configKey("EDC_OAUTH_PROVIDER_JWKS_URL"); - public DashboardDapsConfig buildDapsConfigOrNull() { var dapsConfig = new DashboardDapsConfig(); - dapsConfig.setTokenUrl(configValue(DAPS_TOKEN_URL)); - dapsConfig.setJwksUrl(configValue(DAPS_JWKS_URL)); + dapsConfig.setTokenUrl(ConfigProps.EDC_OAUTH_TOKEN_URL.getStringOrNull(config)); + dapsConfig.setJwksUrl(ConfigProps.EDC_OAUTH_PROVIDER_JWKS_URL.getStringOrNull(config)); return isBlank(dapsConfig.getTokenUrl()) ? null : dapsConfig; } - - String configValue(String configKey) { - return config.getString(configKey, ""); - } } diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/MiwConfigService.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/MiwConfigService.java index 8bab54198..61e6556f4 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/MiwConfigService.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/MiwConfigService.java @@ -19,7 +19,6 @@ import org.eclipse.edc.spi.system.configuration.Config; import static com.apicatalog.jsonld.StringUtils.isBlank; -import static de.sovity.edc.ext.wrapper.api.ui.pages.dashboard.services.ConfigPropertyUtils.configKey; @RequiredArgsConstructor public class MiwConfigService { @@ -42,4 +41,14 @@ public DashboardMiwConfig buildMiwConfigOrNull() { String configValue(String configKey) { return config.getString(configKey, ""); } + + /** + * Maps a {@literal CONFIG_KEY} to {@literal config.key} + * + * @param envVarKey {@literal CONFIG_KEY} + * @return {@literal config.key} + */ + public static String configKey(String envVarKey) { + return String.join(".", envVarKey.split("_")).toLowerCase(); + } } diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/SelfDescriptionService.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/SelfDescriptionService.java index eb318a271..9dbf44bff 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/SelfDescriptionService.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/SelfDescriptionService.java @@ -14,105 +14,43 @@ package de.sovity.edc.ext.wrapper.api.ui.pages.dashboard.services; +import de.sovity.edc.utils.config.ConfigProps; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.Validate; -import org.eclipse.edc.spi.monitor.Monitor; import org.eclipse.edc.spi.system.configuration.Config; -import java.util.List; -import java.util.Objects; - -import static de.sovity.edc.ext.wrapper.api.ui.pages.dashboard.services.ConfigPropertyUtils.configKey; - @RequiredArgsConstructor public class SelfDescriptionService { private final Config config; - private final Monitor monitor; - private static final String PARTICIPANT_ID = configKey("MY_EDC_PARTICIPANT_ID"); - private static final String CONNECTOR_ENDPOINT = configKey("EDC_DSP_CALLBACK_ADDRESS"); - private static final String TITLE = configKey("MY_EDC_TITLE"); - private static final String DESCRIPTION = configKey("MY_EDC_DESCRIPTION"); - private static final String CURATOR_URL = configKey("MY_EDC_CURATOR_URL"); - private static final String CURATOR_NAME = configKey("MY_EDC_CURATOR_NAME"); - private static final String MAINTAINER_URL = configKey("MY_EDC_MAINTAINER_URL"); - private static final String MAINTAINER_NAME = configKey("MY_EDC_MAINTAINER_NAME"); - private static final List REQUIRED = List.of( - PARTICIPANT_ID, - CONNECTOR_ENDPOINT, - TITLE, - DESCRIPTION, - CURATOR_URL, - CURATOR_NAME, - MAINTAINER_URL, - MAINTAINER_NAME - ); - - /** - * Eclipse EDC Participant ID. Prefer setting {@link #PARTICIPANT_ID} when configuring the connector. - */ - private static final String ECLIPSE_EDC_PARTICIPANT_ID = configKey("EDC_PARTICIPANT_ID"); - - /** - * Deprecated Connector ID configuration property. - *

- * Required for printing out a warning if still set. - * - * @deprecated Use {@link #PARTICIPANT_ID} instead. - */ - @Deprecated(forRemoval = true) - private static final String NAME_KEBAB_CASE = configKey("MY_EDC_NAME_KEBAB_CASE"); public String getParticipantId() { - return configValue(PARTICIPANT_ID); + return ConfigProps.EDC_PARTICIPANT_ID.getStringOrNull(config); } public String getConnectorEndpoint() { - return configValue(CONNECTOR_ENDPOINT); + return ConfigProps.EDC_DSP_CALLBACK_ADDRESS.getStringOrNull(config); } public String getConnectorTitle() { - return configValue(TITLE); + return ConfigProps.MY_EDC_TITLE.getStringOrNull(config); } public String getConnectorDescription() { - return configValue(DESCRIPTION); + return ConfigProps.MY_EDC_DESCRIPTION.getStringOrNull(config); } public String getCuratorUrl() { - return configValue(CURATOR_URL); + return ConfigProps.MY_EDC_CURATOR_URL.getStringOrNull(config); } public String getCuratorName() { - return configValue(CURATOR_NAME); + return ConfigProps.MY_EDC_CURATOR_NAME.getStringOrNull(config); } public String getMaintainerUrl() { - return configValue(MAINTAINER_URL); + return ConfigProps.MY_EDC_MAINTAINER_URL.getStringOrNull(config); } public String getMaintainerName() { - return configValue(MAINTAINER_NAME); - } - - public void validateSelfDescriptionConfig() { - var missing = REQUIRED.stream() - .filter(key -> StringUtils.isBlank(configValue(key))) - .toList(); - Validate.isTrue(missing.isEmpty(), - "Missing required configuration properties: %s".formatted(missing)); - - Validate.isTrue(Objects.equals(configValue(PARTICIPANT_ID), configValue(ECLIPSE_EDC_PARTICIPANT_ID)), - "Config Properties %s and %s have different values. Please set %s instead of %s." - .formatted(PARTICIPANT_ID, ECLIPSE_EDC_PARTICIPANT_ID, PARTICIPANT_ID, ECLIPSE_EDC_PARTICIPANT_ID)); - - if (StringUtils.isNotBlank(configValue(NAME_KEBAB_CASE))) { - monitor.warning("Config Property %s is deprecated in favor of %s. Please configure that instead." - .formatted(NAME_KEBAB_CASE, PARTICIPANT_ID)); - } - } - - String configValue(String configKey) { - return config.getString(configKey, ""); + return ConfigProps.MY_EDC_MAINTAINER_NAME.getStringOrNull(config); } } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/asset/AssetApiServiceTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/asset/AssetApiServiceTest.java index f11cee68b..791bdc550 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/asset/AssetApiServiceTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/asset/AssetApiServiceTest.java @@ -58,8 +58,8 @@ public class AssetApiServiceTest { testDatabase -> { val config = forTestDatabase("MyEDC", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/catalog/CatalogApiTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/catalog/CatalogApiTest.java index 101a76fdb..ecec4a5bd 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/catalog/CatalogApiTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/catalog/CatalogApiTest.java @@ -54,8 +54,8 @@ class CatalogApiTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } @@ -76,7 +76,7 @@ void testDistributionKey() { createPolicy(); createContractDefinition(); // act - var catalogPageDataOffers = client.uiApi().getCatalogPageDataOffers(config.getProtocolEndpoint().getUri().toString()); + var catalogPageDataOffers = client.uiApi().getCatalogPageDataOffers(config.getProtocolApiUrl()); // assert assertThat(catalogPageDataOffers.size()).isEqualTo(1); diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_agreement/ContractAgreementPageTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_agreement/ContractAgreementPageTest.java index a69824768..016222283 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_agreement/ContractAgreementPageTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_agreement/ContractAgreementPageTest.java @@ -54,7 +54,7 @@ import java.util.UUID; import static de.sovity.edc.extension.e2e.connector.config.ConnectorConfigFactory.forTestDatabase; -import static de.sovity.edc.extension.e2e.connector.config.ConnectorRemoteConfigFactory.fromConnectorConfig; +import static de.sovity.edc.extension.e2e.connector.config.ConnectorRemoteConfig.fromConnectorConfig; import static org.assertj.core.api.Assertions.assertThat; @ApiTest @@ -71,8 +71,8 @@ class ContractAgreementPageTest { testDatabase -> { config = forTestDatabase("provider", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); connector = new ConnectorRemote(fromConnectorConfig(config)); return config.getProperties(); diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_agreement/ContractAgreementTransferApiServiceTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_agreement/ContractAgreementTransferApiServiceTest.java index 84ceac267..58be55de4 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_agreement/ContractAgreementTransferApiServiceTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_agreement/ContractAgreementTransferApiServiceTest.java @@ -57,8 +57,8 @@ class ContractAgreementTransferApiServiceTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_definitions/ContractDefinitionPageApiServiceTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_definitions/ContractDefinitionPageApiServiceTest.java index 3f9e18eb4..b0bc2a953 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_definitions/ContractDefinitionPageApiServiceTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/contract_definitions/ContractDefinitionPageApiServiceTest.java @@ -37,8 +37,8 @@ class ContractDefinitionPageApiServiceTest { testDatabase -> { config = forTestDatabase(PARTICIPANT_ID, testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiServiceTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiServiceTest.java index 2bd2af260..2ffe93446 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiServiceTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiServiceTest.java @@ -17,6 +17,7 @@ import de.sovity.edc.client.EdcClient; import de.sovity.edc.extension.e2e.connector.config.ConnectorConfig; import de.sovity.edc.extension.e2e.db.EdcRuntimeExtensionWithTestDatabase; +import de.sovity.edc.utils.config.ConfigProps; import org.eclipse.edc.connector.contract.spi.negotiation.store.ContractNegotiationStore; import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; @@ -65,16 +66,16 @@ class DashboardPageApiServiceTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); - config.setProperty("edc.oauth.token.url", "https://token-url.daps"); - config.setProperty("edc.oauth.provider.jwks.url", "https://jwks-url.daps"); + config.setProperty(ConfigProps.EDC_OAUTH_TOKEN_URL, "https://token-url.daps"); + config.setProperty(ConfigProps.EDC_OAUTH_PROVIDER_JWKS_URL, "https://jwks-url.daps"); config.setProperty("tx.ssi.oauth.token.url", "https://token.miw"); config.setProperty("tx.ssi.miw.url", "https://miw"); config.setProperty("tx.ssi.miw.authority.id", "my-authority-id"); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } @@ -92,8 +93,8 @@ class DashboardPageApiServiceTest { void setUp(EdcExtension context) { client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); @@ -167,7 +168,7 @@ void testConnectorMetadata() { assertThat(dashboardPage.getConnectorDescription()).isEqualTo("Connector Description my-edc-participant-id"); assertThat(dashboardPage.getConnectorTitle()).isEqualTo("Connector Title my-edc-participant-id"); - assertThat(dashboardPage.getConnectorEndpoint()).isEqualTo(config.getProtocolEndpoint().getUri().toString()); + assertThat(dashboardPage.getConnectorEndpoint()).isEqualTo(config.getProtocolApiUrl()); assertThat(dashboardPage.getConnectorCuratorName()).isEqualTo("Curator Name my-edc-participant-id"); assertThat(dashboardPage.getConnectorCuratorUrl()).isEqualTo("http://curator.my-edc-participant-id"); assertThat(dashboardPage.getConnectorMaintainerName()).isEqualTo("Maintainer Name my-edc-participant-id"); diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/policy/PolicyDefinitionApiServiceTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/policy/PolicyDefinitionApiServiceTest.java index f6e3344df..f0c03f615 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/policy/PolicyDefinitionApiServiceTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/policy/PolicyDefinitionApiServiceTest.java @@ -54,8 +54,8 @@ class PolicyDefinitionApiServiceTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/transferhistory/TransferHistoryPageApiServiceTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/transferhistory/TransferHistoryPageApiServiceTest.java index a0cf4346c..6254c318b 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/transferhistory/TransferHistoryPageApiServiceTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/transferhistory/TransferHistoryPageApiServiceTest.java @@ -45,8 +45,8 @@ class TransferHistoryPageApiServiceTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/transferhistory/TransferProcessAssetApiServiceTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/transferhistory/TransferProcessAssetApiServiceTest.java index f18f73f05..31b60758d 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/transferhistory/TransferProcessAssetApiServiceTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/transferhistory/TransferProcessAssetApiServiceTest.java @@ -44,8 +44,8 @@ class TransferProcessAssetApiServiceTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/KpiApiTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/KpiApiTest.java index 27c8cafcb..b3a24f5e2 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/KpiApiTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/KpiApiTest.java @@ -36,8 +36,8 @@ class KpiApiTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/SupportedPolicyApiTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/SupportedPolicyApiTest.java index 094595f7f..509c2ce0f 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/SupportedPolicyApiTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/SupportedPolicyApiTest.java @@ -37,8 +37,8 @@ class SupportedPolicyApiTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/UseCaseApiWrapperTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/UseCaseApiWrapperTest.java index 4a4dbfd43..c638d38e0 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/UseCaseApiWrapperTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/usecase/UseCaseApiWrapperTest.java @@ -58,8 +58,8 @@ class UseCaseApiWrapperTest { testDatabase -> { config = forTestDatabase("my-edc-participant-id", testDatabase); client = EdcClient.builder() - .managementApiUrl(config.getManagementEndpoint().getUri().toString()) - .managementApiKey(config.getProperties().get("edc.api.auth.key")) + .managementApiUrl(config.getManagementApiUrl()) + .managementApiKey(config.getManagementApiKey()) .build(); return config.getProperties(); } @@ -128,7 +128,7 @@ void shouldFetchWithoutFilterButWithLimit() { private CatalogQuery criterion(String leftOperand, CatalogFilterExpressionOperator operator, String rightOperand) { return CatalogQuery.builder() - .connectorEndpoint(config.getProtocolEndpoint().getUri().toString()) + .connectorEndpoint(config.getProtocolApiUrl()) .filterExpressions( List.of( CatalogFilterExpression.builder() @@ -143,7 +143,7 @@ private CatalogQuery criterion(String leftOperand, CatalogFilterExpressionOperat private CatalogQuery criterion(String leftOperand, CatalogFilterExpressionOperator operator, List rightOperand) { return CatalogQuery.builder() - .connectorEndpoint(config.getProtocolEndpoint().getUri().toString()) + .connectorEndpoint(config.getProtocolApiUrl()) .filterExpressions( List.of( CatalogFilterExpression.builder() @@ -158,7 +158,7 @@ private CatalogQuery criterion(String leftOperand, CatalogFilterExpressionOperat private CatalogQuery criterion(Integer limit, Integer offset) { return CatalogQuery.builder() - .connectorEndpoint(config.getProtocolEndpoint().getUri().toString()) + .connectorEndpoint(config.getProtocolApiUrl()) .limit(limit) .offset(offset) .build(); @@ -184,7 +184,7 @@ private void setupAssets() { var dataSource = UiDataSource.builder() .type(DataSourceType.HTTP_DATA) .httpData(UiDataSourceHttpData.builder() - .baseUrl(config.getProtocolEndpoint().getUri().toString()) + .baseUrl(config.getProtocolApiUrl()) .build()) .build(); diff --git a/launchers/common/base/build.gradle.kts b/launchers/common/base/build.gradle.kts index b32ec7b71..dfb0f3a23 100644 --- a/launchers/common/base/build.gradle.kts +++ b/launchers/common/base/build.gradle.kts @@ -3,6 +3,9 @@ plugins { } dependencies { + // For Custom Launcher Code + implementation(project(":config")) + // Control-Plane api(libs.edc.controlPlaneCore) api(libs.edc.managementApi) diff --git a/launchers/common/base/src/main/java/de/sovity/edc/Main.java b/launchers/common/base/src/main/java/de/sovity/edc/Main.java new file mode 100644 index 000000000..7b9dbb677 --- /dev/null +++ b/launchers/common/base/src/main/java/de/sovity/edc/Main.java @@ -0,0 +1,10 @@ +package de.sovity.edc; + +import de.sovity.edc.utils.config.ConfigProps; +import de.sovity.edc.utils.config.SovityEdcRuntime; + +public class Main { + public static void main(String[] args) { + SovityEdcRuntime.boot(ConfigProps.ALL_CE_PROPS); + } +} diff --git a/launchers/connectors/mds-ce/build.gradle.kts b/launchers/connectors/mds-ce/build.gradle.kts index 1698e71d5..171112ac3 100644 --- a/launchers/connectors/mds-ce/build.gradle.kts +++ b/launchers/connectors/mds-ce/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { } application { - mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") + mainClass.set("de.sovity.edc.Main") } tasks.withType { diff --git a/launchers/connectors/sovity-ce/build.gradle.kts b/launchers/connectors/sovity-ce/build.gradle.kts index d2a570d2b..684f46c29 100644 --- a/launchers/connectors/sovity-ce/build.gradle.kts +++ b/launchers/connectors/sovity-ce/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { } application { - mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") + mainClass.set("de.sovity.edc.Main") } tasks.withType { diff --git a/launchers/connectors/sovity-dev/build.gradle.kts b/launchers/connectors/sovity-dev/build.gradle.kts index c65dd86ff..7548d3047 100644 --- a/launchers/connectors/sovity-dev/build.gradle.kts +++ b/launchers/connectors/sovity-dev/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { } application { - mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") + mainClass.set("de.sovity.edc.Main") } tasks.withType { diff --git a/launchers/connectors/test-backend/build.gradle.kts b/launchers/connectors/test-backend/build.gradle.kts index 60a27b971..c74086d51 100644 --- a/launchers/connectors/test-backend/build.gradle.kts +++ b/launchers/connectors/test-backend/build.gradle.kts @@ -14,7 +14,7 @@ dependencies { } application { - mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime") + mainClass.set("de.sovity.edc.Main") } tasks.withType { diff --git a/settings.gradle.kts b/settings.gradle.kts index 1220a8e77..72e602a44 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,6 @@ rootProject.name = "sovity-ce-edc" +include(":config") include(":extensions:contract-termination") include(":extensions:database-direct-access") include(":extensions:edc-ui-config") diff --git a/tests/build.gradle.kts b/tests/build.gradle.kts index e5e0d221b..255718f4b 100644 --- a/tests/build.gradle.kts +++ b/tests/build.gradle.kts @@ -3,6 +3,7 @@ plugins { } dependencies { + api(project(":config")) api(project(":launchers:common:base")) api(project(":launchers:common:auth-mock")) diff --git a/tests/src/test/java/de/sovity/edc/e2e/AlwaysTrueMigrationReversedTest.java b/tests/src/test/java/de/sovity/edc/e2e/AlwaysTrueMigrationReversedTest.java index e9347079d..55973ac88 100644 --- a/tests/src/test/java/de/sovity/edc/e2e/AlwaysTrueMigrationReversedTest.java +++ b/tests/src/test/java/de/sovity/edc/e2e/AlwaysTrueMigrationReversedTest.java @@ -20,6 +20,7 @@ import de.sovity.edc.extension.e2e.extension.E2eTestExtension; import de.sovity.edc.extension.e2e.extension.Provider; import de.sovity.edc.extension.utils.junit.DisabledOnGithub; +import de.sovity.edc.utils.config.ConfigProps; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockserver.integration.ClientAndServer; @@ -32,10 +33,12 @@ class AlwaysTrueMigrationReversedTest { @RegisterExtension private static final E2eTestExtension E2E_TEST_EXTENSION = new E2eTestExtension( defaultBuilder().toBuilder() - .consumerConfigCustomizer(config -> config.getProperties() - .put("edc.flyway.additional.migration.locations", "classpath:db/additional-test-data/always-true-policy-legacy")) - .providerConfigCustomizer(config -> config.getProperties() - .put("edc.flyway.additional.migration.locations", "classpath:db/additional-test-data/always-true-policy-migrated")) + .consumerConfigCustomizer(config -> config.setProperty( + ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, "classpath:db/additional-test-data/always-true-policy-legacy" + )) + .providerConfigCustomizer(config -> config.setProperty( + ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, "classpath:db/additional-test-data/always-true-policy-migrated" + )) .build() ); diff --git a/tests/src/test/java/de/sovity/edc/e2e/AlwaysTrueMigrationTest.java b/tests/src/test/java/de/sovity/edc/e2e/AlwaysTrueMigrationTest.java index e1d08fabd..d9a22c7cb 100644 --- a/tests/src/test/java/de/sovity/edc/e2e/AlwaysTrueMigrationTest.java +++ b/tests/src/test/java/de/sovity/edc/e2e/AlwaysTrueMigrationTest.java @@ -25,6 +25,7 @@ import de.sovity.edc.extension.e2e.extension.Provider; import de.sovity.edc.extension.policy.AlwaysTruePolicyConstants; import de.sovity.edc.extension.utils.junit.DisabledOnGithub; +import de.sovity.edc.utils.config.ConfigProps; import de.sovity.edc.utils.jsonld.vocab.Prop; import jakarta.ws.rs.HttpMethod; import lombok.val; @@ -45,10 +46,12 @@ class AlwaysTrueMigrationTest { @RegisterExtension private static final E2eTestExtension E2E_TEST_EXTENSION = new E2eTestExtension( withModule(":launchers:connectors:sovity-dev").toBuilder() - .consumerConfigCustomizer(config -> config.getProperties() - .put("edc.flyway.additional.migration.locations", "classpath:db/additional-test-data/always-true-policy-migrated")) - .providerConfigCustomizer(config -> config.getProperties() - .put("edc.flyway.additional.migration.locations", "classpath:db/additional-test-data/always-true-policy-legacy")) + .consumerConfigCustomizer(config -> config.setProperty( + ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, "classpath:db/additional-test-data/always-true-policy-legacy" + )) + .providerConfigCustomizer(config -> config.setProperty( + ConfigProps.EDC_FLYWAY_ADDITIONAL_MIGRATION_LOCATIONS, "classpath:db/additional-test-data/always-true-policy-migrated" + )) .build() ); diff --git a/tests/src/test/java/de/sovity/edc/e2e/ApiWrapperDemoTest.java b/tests/src/test/java/de/sovity/edc/e2e/ApiWrapperDemoTest.java index 88c0e5f63..44f9b2604 100644 --- a/tests/src/test/java/de/sovity/edc/e2e/ApiWrapperDemoTest.java +++ b/tests/src/test/java/de/sovity/edc/e2e/ApiWrapperDemoTest.java @@ -54,7 +54,7 @@ import static de.sovity.edc.extension.e2e.connector.DataTransferTestUtil.validateDataTransferred; import static de.sovity.edc.extension.e2e.connector.config.ConnectorConfigFactory.forTestDatabase; -import static de.sovity.edc.extension.e2e.connector.config.ConnectorRemoteConfigFactory.fromConnectorConfig; +import static de.sovity.edc.extension.e2e.connector.config.ConnectorRemoteConfig.fromConnectorConfig; import static org.assertj.core.api.Assertions.assertThat; class ApiWrapperDemoTest { @@ -90,8 +90,8 @@ void setup() { providerConnector = new ConnectorRemote(fromConnectorConfig(providerConfig)); providerClient = EdcClient.builder() - .managementApiUrl(providerConfig.getManagementEndpoint().getUri().toString()) - .managementApiKey(providerConfig.getProperties().get("edc.api.auth.key")) + .managementApiUrl(providerConfig.getManagementApiUrl()) + .managementApiKey(providerConfig.getManagementApiKey()) .build(); // set up consumer EDC + Client @@ -100,12 +100,12 @@ void setup() { consumerConnector = new ConnectorRemote(fromConnectorConfig(consumerConfig)); consumerClient = EdcClient.builder() - .managementApiUrl(consumerConfig.getManagementEndpoint().getUri().toString()) - .managementApiKey(consumerConfig.getProperties().get("edc.api.auth.key")) + .managementApiUrl(consumerConfig.getManagementApiUrl()) + .managementApiKey(consumerConfig.getManagementApiKey()) .build(); // We use the provider EDC as data sink / data source (it has the test-backend-controller extension) - dataAddress = new MockDataAddressRemote(providerConnector.getConfig().getDefaultEndpoint()); + dataAddress = new MockDataAddressRemote(providerConfig.getDefaultApiUrl()); } @Test @@ -236,6 +236,6 @@ private void initiateTransfer(UiContractNegotiation negotiation) { } private String getProtocolEndpoint(ConnectorRemote connector) { - return connector.getConfig().getProtocolEndpoint().getUri().toString(); + return connector.getConfig().getProtocolApiUrl(); } } diff --git a/tests/src/test/java/de/sovity/edc/e2e/DataSourceParameterizationTest.java b/tests/src/test/java/de/sovity/edc/e2e/DataSourceParameterizationTest.java index 300dd0fdc..c27a48af2 100644 --- a/tests/src/test/java/de/sovity/edc/e2e/DataSourceParameterizationTest.java +++ b/tests/src/test/java/de/sovity/edc/e2e/DataSourceParameterizationTest.java @@ -61,7 +61,6 @@ import org.mockserver.model.HttpResponse; import org.mockserver.model.HttpStatusCode; -import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Base64; @@ -154,7 +153,7 @@ void canUseTheWorkaroundInCustomTransferRequest( createData(providerClient, testCase, context); // act - val providerEndpoint = providerConfig.getProtocolEndpoint().getUri().toString(); + val providerEndpoint = providerConfig.getProtocolApiUrl(); val dataOffers = consumerClient.uiApi().getCatalogPageDataOffers(providerEndpoint); val startNegotiation = initiateNegotiation(consumerClient, dataOffers.get(0), dataOffers.get(0).getContractOffers().get(0)); val negotiation = awaitNegotiationDone(consumerClient, startNegotiation.getContractNegotiationId()); @@ -248,7 +247,7 @@ void sendWithEdcManagementApi( createData(providerClient, testCase, context); // act - val providerEndpoint = providerConfig.getProtocolEndpoint().getUri().toString(); + val providerEndpoint = providerConfig.getProtocolApiUrl(); val dataOffers = consumerClient.uiApi().getCatalogPageDataOffers(providerEndpoint); val startNegotiation = initiateNegotiation(consumerClient, dataOffers.get(0), dataOffers.get(0).getContractOffers().get(0)); val negotiation = awaitNegotiationDone(consumerClient, startNegotiation.getContractNegotiationId()); @@ -258,7 +257,7 @@ void sendWithEdcManagementApi( val transferId = consumerConnector.initiateTransfer( negotiation.getContractAgreementId(), testCase.id, - URI.create(providerEndpoint), + providerEndpoint, Json.createObjectBuilder(Map.of( standardBase + "type", "HttpData", standardBase + "baseUrl", context.destinationUrl, @@ -300,7 +299,7 @@ void canTransferParameterizedAsset( createData(providerClient, testCase, context); // act - val connectorEndpoint = providerConfig.getProtocolEndpoint().getUri().toString(); + val connectorEndpoint = providerConfig.getProtocolApiUrl(); val dataOffers = consumerClient.uiApi().getCatalogPageDataOffers(connectorEndpoint); val dataOffer = dataOffers.stream().filter(it -> it.getAsset().getAssetId().equals(testCase.id)).findFirst().get(); val negotiationInit = initiateNegotiation(consumerClient, dataOffer, dataOffer.getContractOffers().get(0)); diff --git a/tests/src/test/java/de/sovity/edc/e2e/DataSourceQueryParamsTest.java b/tests/src/test/java/de/sovity/edc/e2e/DataSourceQueryParamsTest.java index b3bb3d0d5..061594233 100644 --- a/tests/src/test/java/de/sovity/edc/e2e/DataSourceQueryParamsTest.java +++ b/tests/src/test/java/de/sovity/edc/e2e/DataSourceQueryParamsTest.java @@ -46,7 +46,7 @@ class DataSourceQueryParamsTest { @BeforeEach void setup(@Provider ConnectorConfig providerConfig) { // We use the provider EDC as data sink / data source (it has the test-backend-controller extension) - dataAddress = new MockDataAddressRemote(providerConfig.getDefaultEndpoint()); + dataAddress = new MockDataAddressRemote(providerConfig.getDefaultApiUrl()); } @Test diff --git a/tests/src/test/java/de/sovity/edc/e2e/ManagementApiTransferTest.java b/tests/src/test/java/de/sovity/edc/e2e/ManagementApiTransferTest.java index 1f571485b..358cc8b4f 100644 --- a/tests/src/test/java/de/sovity/edc/e2e/ManagementApiTransferTest.java +++ b/tests/src/test/java/de/sovity/edc/e2e/ManagementApiTransferTest.java @@ -39,7 +39,7 @@ class ManagementApiTransferTest { @BeforeEach void setup(@Provider ConnectorRemote providerConnector) { // We use the provider EDC as data sink / data source (it has the test-backend-controller extension) - dataAddress = new MockDataAddressRemote(providerConnector.getConfig().getDefaultEndpoint()); + dataAddress = new MockDataAddressRemote(providerConnector.getConfig().getDefaultApiUrl()); } @Test @@ -51,7 +51,7 @@ void testDataTransfer(@Consumer ConnectorRemote consumerConnector, @Provider Con // act consumerConnector.consumeOffer( providerConnector.getParticipantId(), - providerConnector.getConfig().getProtocolEndpoint().getUri(), + providerConnector.getConfig().getProtocolApiUrl(), assetId, dataAddress.getDataSinkJsonLd()); diff --git a/tests/src/test/java/de/sovity/edc/e2e/UiApiWrapperTest.java b/tests/src/test/java/de/sovity/edc/e2e/UiApiWrapperTest.java index 0b9875b62..08a925680 100644 --- a/tests/src/test/java/de/sovity/edc/e2e/UiApiWrapperTest.java +++ b/tests/src/test/java/de/sovity/edc/e2e/UiApiWrapperTest.java @@ -99,7 +99,7 @@ class UiApiWrapperTest { @BeforeEach void setup(@Provider ConnectorRemote providerConnector) { // We use the provider EDC as data sink / data source (it has the test-backend-controller extension) - dataAddress = new MockDataAddressRemote(providerConnector.getConfig().getDefaultEndpoint()); + dataAddress = new MockDataAddressRemote(providerConnector.getConfig().getDefaultApiUrl()); } @DisabledOnGithub @@ -198,7 +198,7 @@ void provide_consume_assetMapping_policyMapping_agreements( assertThat(assets).hasSize(1); var asset = assets.get(0); - var providerProtocolEndpoint = providerConfig.getProtocolEndpoint().getUri().toString(); + var providerProtocolEndpoint = providerConfig.getProtocolApiUrl(); var dataOffers = consumerClient.uiApi().getCatalogPageDataOffers(providerProtocolEndpoint); assertThat(dataOffers).hasSize(1); var dataOffer = dataOffers.get(0); @@ -286,7 +286,7 @@ void provide_consume_assetMapping_policyMapping_agreements( // Provider Contract Agreement assertThat(providerAgreement.getContractAgreementId()).isEqualTo(negotiation.getContractAgreementId()); assertThat(providerAgreement.getDirection()).isEqualTo(PROVIDING); - assertThat(providerAgreement.getCounterPartyAddress()).isEqualTo(consumerConfig.getProtocolEndpoint().getUri().toString()); + assertThat(providerAgreement.getCounterPartyAddress()).isEqualTo(consumerConfig.getProtocolApiUrl()); assertThat(providerAgreement.getCounterPartyId()).isEqualTo(CONSUMER_PARTICIPANT_ID); assertThat(providerAgreement.getAsset().getAssetId()).isEqualTo(assetId); @@ -409,7 +409,7 @@ void customTransferRequest( .assetSelector(List.of()) .build()); - val providerProtocolEndpoint = providerConfig.getProtocolEndpoint().getUri().toString(); + val providerProtocolEndpoint = providerConfig.getProtocolApiUrl(); var dataOffers = consumerClient.uiApi().getCatalogPageDataOffers(providerProtocolEndpoint); assertThat(dataOffers).hasSize(1); var dataOffer = dataOffers.get(0); @@ -501,7 +501,7 @@ void editAssetOnLiveContract( .build())) .build()); - val providerProtocolEndpoint = providerConfig.getProtocolEndpoint().getUri().toString(); + val providerProtocolEndpoint = providerConfig.getProtocolApiUrl(); var dataOffers = consumerClient.uiApi().getCatalogPageDataOffers(providerProtocolEndpoint); assertThat(dataOffers).hasSize(1); var dataOffer = dataOffers.get(0); diff --git a/tests/src/test/java/de/sovity/edc/e2e/UseCaseApiWrapperTest.java b/tests/src/test/java/de/sovity/edc/e2e/UseCaseApiWrapperTest.java index 521a670af..e9f521f16 100644 --- a/tests/src/test/java/de/sovity/edc/e2e/UseCaseApiWrapperTest.java +++ b/tests/src/test/java/de/sovity/edc/e2e/UseCaseApiWrapperTest.java @@ -66,7 +66,7 @@ class UseCaseApiWrapperTest { @BeforeEach void setup(@Provider ConnectorRemote providerConnector) { // We use the provider EDC as data sink / data source (it has the test-backend-controller extension) - dataAddress = new MockDataAddressRemote(providerConnector.getConfig().getDefaultEndpoint()); + dataAddress = new MockDataAddressRemote(providerConnector.getConfig().getDefaultApiUrl()); } @DisabledOnGithub @@ -194,6 +194,6 @@ private void createContractDefinition(EdcClient providerClient) { } private String getProtocolEndpoint(ConnectorRemote connector) { - return connector.getConfig().getProtocolEndpoint().getUri().toString(); + return connector.getConfig().getProtocolApiUrl(); } } diff --git a/utils/test-utils/build.gradle.kts b/utils/test-utils/build.gradle.kts index bfff302da..79b41f7fb 100644 --- a/utils/test-utils/build.gradle.kts +++ b/utils/test-utils/build.gradle.kts @@ -13,6 +13,7 @@ dependencies { api(libs.edc.junit) api(libs.awaitility.java) api(libs.postgres) + api(project(":config")) api(project(":extensions:wrapper:clients:java-client")) api(project(":utils:json-and-jsonld-utils")) diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/ConnectorRemote.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/ConnectorRemote.java index ddc180bad..63d8ed811 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/ConnectorRemote.java +++ b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/ConnectorRemote.java @@ -16,7 +16,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import de.sovity.edc.extension.e2e.connector.config.ConnectorRemoteConfig; -import de.sovity.edc.extension.e2e.connector.config.api.auth.NoneAuthProvider; import io.restassured.http.Header; import io.restassured.specification.RequestSpecification; import jakarta.json.Json; @@ -32,8 +31,8 @@ import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.monitor.ConsoleMonitor; import org.eclipse.edc.spi.result.Failure; +import org.eclipse.edc.util.string.StringUtils; -import java.net.URI; import java.time.Duration; import java.util.Map; import java.util.UUID; @@ -132,12 +131,12 @@ public void createContractDefinition( .contentType(JSON); } - public JsonArray getCatalogDatasets(URI providerProtocolEndpoint) { + public JsonArray getCatalogDatasets(String providerProtocolApiUrl) { var datasetReference = new AtomicReference(); var requestBody = createObjectBuilder() .add(CONTEXT, createObjectBuilder().add(EDC_PREFIX, EDC_NAMESPACE)) .add(TYPE, EDC_NAMESPACE + "CatalogRequest") - .add(EDC_NAMESPACE + "counterPartyAddress", providerProtocolEndpoint.toString()) + .add(EDC_NAMESPACE + "counterPartyAddress", providerProtocolApiUrl) .add(EDC_NAMESPACE + "protocol", "dataspace-protocol-http") .build(); @@ -164,8 +163,8 @@ public JsonArray getCatalogDatasets(URI providerProtocolEndpoint) { return datasetReference.get(); } - public JsonObject getDatasetForAsset(String assetId, URI providerProtocolEndpoint) { - var datasets = getCatalogDatasets(providerProtocolEndpoint); + public JsonObject getDatasetForAsset(String assetId, String providerProtocolApiUrl) { + var datasets = getCatalogDatasets(providerProtocolApiUrl); return datasets.stream() .map(JsonValue::asJsonObject) .filter(it -> assetId.equals(getDatasetContractId(it).assetIdPart())) @@ -175,7 +174,7 @@ public JsonObject getDatasetForAsset(String assetId, URI providerProtocolEndpoin public String negotiateContract( String providerParticipantId, - URI providerProtocolEndpoint, + String providerProtocolApiUrl, String offerId, String assetId, JsonObject policy) { @@ -184,7 +183,7 @@ public String negotiateContract( .add(TYPE, EDC_NAMESPACE + "ContractRequest") .add(EDC_NAMESPACE + "consumerId", config.getParticipantId()) .add(EDC_NAMESPACE + "providerId", providerParticipantId) - .add(EDC_NAMESPACE + "connectorAddress", providerProtocolEndpoint.toString()) + .add(EDC_NAMESPACE + "connectorAddress", providerProtocolApiUrl) .add(EDC_NAMESPACE + "protocol", "dataspace-protocol-http") .add(EDC_NAMESPACE + "offer", createObjectBuilder() .add(EDC_NAMESPACE + "offerId", offerId) @@ -253,12 +252,12 @@ public String getParticipantId() { public String initiateTransfer( String contractAgreementId, String assetId, - URI providerProtocolApi, + String providerProtocolApiUrl, JsonObject destination) { var requestBody = createObjectBuilder() .add(TYPE, EDC_NAMESPACE + "TransferRequest") .add(EDC_NAMESPACE + "protocol", "dataspace-protocol-http") - .add(EDC_NAMESPACE + "connectorAddress", providerProtocolApi.toString()) + .add(EDC_NAMESPACE + "connectorAddress", providerProtocolApiUrl) .add(EDC_NAMESPACE + "connectorId", config.getParticipantId()) .add(EDC_NAMESPACE + "assetId", assetId) .add(EDC_NAMESPACE + "dataDestination", destination) @@ -279,16 +278,16 @@ public String initiateTransfer( public String consumeOffer( String providerId, - URI providerProtocolApi, + String providerProtocolApiUrl, String assetId, JsonObject destination) { - var dataset = getDatasetForAsset(assetId, providerProtocolApi); + var dataset = getDatasetForAsset(assetId, providerProtocolApiUrl); var contractId = getDatasetContractId(dataset); var policy = dataset.getJsonArray(ODRL_POLICY_ATTRIBUTE).get(0).asJsonObject(); var contractAgreementId = negotiateContract( providerId, - providerProtocolApi, + providerProtocolApiUrl, contractId.toString(), contractId.assetIdPart(), policy); @@ -296,7 +295,7 @@ public String consumeOffer( var transferProcessId = initiateTransfer( contractAgreementId, assetId, - providerProtocolApi, + providerProtocolApiUrl, destination); assertThat(transferProcessId).isNotNull(); @@ -338,24 +337,15 @@ public void createDataOffer( } public RequestSpecification prepareManagementApiCall() { - var managementConfig = config.getManagementEndpoint(); - var managementBaseUri = managementConfig.getUri().toString(); - if (managementConfig.authProvider() instanceof NoneAuthProvider) { - return given().baseUri(managementBaseUri); - } - return given() - .baseUri(managementBaseUri) - .header(getAuthHeader()); - } + var apiUrl = config.getManagementApiUrl(); + var request = given().baseUri(apiUrl); - private Header getAuthHeader() { - var authProvider = config.getManagementEndpoint().authProvider(); - if ("".equals(authProvider.getAuthorizationHeader())) { - return null; + var header = config.getManagementApiAuthHeader().get(); + if (header != null) { + request = request.header(new Header(header.getLeft(), header.getRight())); } - return new Header( - authProvider.getAuthorizationHeader(), - authProvider.getAuthorizationHeaderValue()); + + return request; } diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/MockDataAddressRemote.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/MockDataAddressRemote.java index 00e68aeb0..248fffd3f 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/MockDataAddressRemote.java +++ b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/MockDataAddressRemote.java @@ -14,7 +14,6 @@ package de.sovity.edc.extension.e2e.connector; -import de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroupConfig; import jakarta.json.JsonObject; import lombok.RequiredArgsConstructor; @@ -25,7 +24,7 @@ @RequiredArgsConstructor public class MockDataAddressRemote { - private final EdcApiGroupConfig defaultEndpoint; + private final String defaultApiUrl; public String getDataSinkUrl() { return getMockBackendUrl("data-sink"); @@ -44,7 +43,7 @@ public String getDataSourceQueryParamsUrl() { } public String getMockBackendUrl(String path) { - return "%s/test-backend/%s".formatted(defaultEndpoint.getUri().toString(), path); + return "%s/test-backend/%s".formatted(defaultApiUrl, path); } public JsonObject getDataSinkJsonLd() { diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorConfig.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorConfig.java index 383ce8c93..b2213340a 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorConfig.java +++ b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorConfig.java @@ -14,27 +14,63 @@ package de.sovity.edc.extension.e2e.connector.config; -import de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroupConfig; +import de.sovity.edc.utils.config.ConfigProps; +import de.sovity.edc.utils.config.ConfigUtils; +import de.sovity.edc.utils.config.model.ConfigProp; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.Getter; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.http.Header; import java.util.Map; +import java.util.function.Supplier; @Data +@Builder @AllArgsConstructor public class ConnectorConfig { - private String participantId; - private EdcApiGroupConfig defaultEndpoint; - private EdcApiGroupConfig managementEndpoint; - private EdcApiGroupConfig protocolEndpoint; + /** + * Connector Properties after applying defaults from {@link ConfigProps} + */ private Map properties; - public void setProperty(String key, String value) { - properties.put(key, value); + @Builder.Default + private Supplier> managementApiAuthHeader = () -> Pair.of("X-Api-Key", getManagementApiKey()); + + public ConnectorConfig setProperty(ConfigProp property, String value) { + properties.put(property.getProperty(), value); + return this; + } + + public ConnectorConfig setProperty(String property, String value) { + properties.put(property, value); + return this; + } + + public String getDefaultApiUrl() { + return ConfigUtils.getDefaultApiUrl(properties); + } + + public String getManagementApiUrl() { + return ConfigUtils.getManagementApiUrl(properties); + } + + public String getManagementApiKey() { + return ConfigUtils.getManagementApiKey(properties); + } + + public String getProtocolApiUrl() { + return ConfigUtils.getProtocolApiUrl(properties); + } + + public String getPublicApiUrl() { + return ConfigUtils.getPublicApiUrl(properties); } - public void setProperties(Map properties) { - this.properties.putAll(properties); + public String getParticipantId() { + return ConfigProps.EDC_PARTICIPANT_ID.getRaw(properties); } } diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorConfigFactory.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorConfigFactory.java index b2fab5ea9..1c8bc476f 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorConfigFactory.java +++ b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorConfigFactory.java @@ -15,6 +15,8 @@ package de.sovity.edc.extension.e2e.connector.config; import de.sovity.edc.extension.e2e.db.TestDatabase; +import de.sovity.edc.utils.config.ConfigProps; +import de.sovity.edc.utils.config.ConfigService; import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.val; @@ -22,11 +24,10 @@ import java.io.IOException; import java.net.ServerSocket; import java.util.HashMap; +import java.util.Map; import java.util.Random; import java.util.UUID; -import static de.sovity.edc.extension.e2e.connector.config.DatasourceConfigUtils.configureDatasources; -import static de.sovity.edc.extension.e2e.connector.config.api.EdcApiConfigFactory.configureApi; import static org.eclipse.edc.junit.testfixtures.TestUtils.MAX_TCP_PORT; @NoArgsConstructor(access = AccessLevel.PRIVATE) @@ -36,9 +37,36 @@ public class ConnectorConfigFactory { public static ConnectorConfig forTestDatabase(String participantId, TestDatabase testDatabase) { val firstPort = getFreePortRange(5); - var config = basicEdcConfig(participantId, firstPort); - config.setProperties(configureDatasources(testDatabase.getJdbcCredentials())); - return config; + var propertiesInput = new HashMap<>(Map.of( + ConfigProps.MY_EDC_FIRST_PORT, String.valueOf(firstPort), + ConfigProps.EDC_API_AUTH_KEY, "api-key-%s".formatted(UUID.randomUUID().toString()), + ConfigProps.MY_EDC_C2C_IAM_TYPE, "mock-iam", + ConfigProps.MY_EDC_PARTICIPANT_ID, participantId, + ConfigProps.MY_EDC_NETWORK_TYPE, ConfigProps.NetworkType.UNIT_TEST + )); + + propertiesInput.putAll(Map.of( + ConfigProps.MY_EDC_JDBC_URL, testDatabase.getJdbcCredentials().jdbcUrl(), + ConfigProps.MY_EDC_JDBC_USER, testDatabase.getJdbcCredentials().jdbcUser(), + ConfigProps.MY_EDC_JDBC_PASSWORD, testDatabase.getJdbcCredentials().jdbcPassword(), + ConfigProps.EDC_FLYWAY_CLEAN_ENABLE, "true", + ConfigProps.EDC_FLYWAY_CLEAN, "true" + )); + + propertiesInput.putAll(Map.of( + ConfigProps.MY_EDC_TITLE, "Connector Title %s".formatted(participantId), + ConfigProps.MY_EDC_DESCRIPTION, "Connector Description %s".formatted(participantId), + ConfigProps.MY_EDC_CURATOR_URL, "http://curator.%s".formatted(participantId), + ConfigProps.MY_EDC_CURATOR_NAME, "Curator Name %s".formatted(participantId), + ConfigProps.MY_EDC_MAINTAINER_URL, "http://maintainer.%s".formatted(participantId), + ConfigProps.MY_EDC_MAINTAINER_NAME, "Maintainer Name %s".formatted(participantId) + )); + + var properties = ConfigService.applyDefaultsStatic(propertiesInput, ConfigProps.ALL_CE_PROPS); + + return ConnectorConfig.builder() + .properties(properties) + .build(); } public static synchronized int getFreePortRange(int size) { @@ -70,46 +98,4 @@ private static boolean canUsePort(int port) { return false; } } - - public static ConnectorConfig basicEdcConfig(String participantId, int firstPort) { - var apiKey = UUID.randomUUID().toString(); - var apiConfig = configureApi(firstPort, apiKey); - - var properties = new HashMap(); - properties.put("edc.participant.id", participantId); - properties.put("edc.api.auth.key", apiKey); - properties.put("edc.dsp.callback.address", apiConfig.getProtocolApiGroup().getUri().toString()); - properties.putAll(apiConfig.getProperties()); - - properties.put("edc.jsonld.https.enabled", "true"); - properties.put("edc.last.commit.info", "test env commit message"); - properties.put("edc.build.date", "2023-05-08T15:30:00Z"); - - properties.put("my.edc.participant.id", participantId); - properties.put("my.edc.title", "Connector Title %s".formatted(participantId)); - properties.put("my.edc.description", "Connector Description %s".formatted(participantId)); - properties.put("my.edc.curator.url", "http://curator.%s".formatted(participantId)); - properties.put("my.edc.curator.name", "Curator Name %s".formatted(participantId)); - properties.put("my.edc.maintainer.url", "http://maintainer.%s".formatted(participantId)); - properties.put("my.edc.maintainer.name", "Maintainer Name %s".formatted(participantId)); - - properties.put("my.edc.datasource.placeholder.baseurl", apiConfig.getProtocolApiGroup().getUri().toString()); - - properties.put("web.http.port", String.valueOf(apiConfig.getDefaultApiGroup().port())); - properties.put("web.http.path", String.valueOf(apiConfig.getDefaultApiGroup().path())); - properties.put("web.http.protocol.port", String.valueOf(apiConfig.getProtocolApiGroup().port())); - properties.put("web.http.protocol.path", String.valueOf(apiConfig.getProtocolApiGroup().path())); - properties.put("web.http.management.port", String.valueOf(apiConfig.getManagementApiGroup().port())); - properties.put("web.http.management.path", String.valueOf(apiConfig.getManagementApiGroup().path())); - properties.put("web.http.control.port", String.valueOf(apiConfig.getControlApiGroup().port())); - properties.put("web.http.control.path", String.valueOf(apiConfig.getControlApiGroup().path())); - - return new ConnectorConfig( - participantId, - apiConfig.getDefaultApiGroup(), - apiConfig.getManagementApiGroup(), - apiConfig.getProtocolApiGroup(), - properties - ); - } } diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorRemoteConfig.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorRemoteConfig.java index 8577b1d92..f4e877720 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorRemoteConfig.java +++ b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorRemoteConfig.java @@ -14,16 +14,46 @@ package de.sovity.edc.extension.e2e.connector.config; -import de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroupConfig; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; -import lombok.RequiredArgsConstructor; +import lombok.NonNull; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.function.Supplier; @Getter -@RequiredArgsConstructor +@Builder +@AllArgsConstructor(access = AccessLevel.PRIVATE) public class ConnectorRemoteConfig { + @NonNull private final String participantId; - private final EdcApiGroupConfig defaultEndpoint; - private final EdcApiGroupConfig managementEndpoint; - private final EdcApiGroupConfig protocolEndpoint; + + @NonNull + private final String defaultApiUrl; + + @NonNull + private final String managementApiUrl; + + @NonNull + private final Supplier> managementApiAuthHeader; + + @NonNull + private final String protocolApiUrl; + + @NonNull + private final String publicApiUrl; + + public static ConnectorRemoteConfig fromConnectorConfig(ConnectorConfig connectorConfig) { + return builder() + .participantId(connectorConfig.getParticipantId()) + .managementApiUrl(connectorConfig.getManagementApiUrl()) + .managementApiAuthHeader(connectorConfig.getManagementApiAuthHeader()) + .protocolApiUrl(connectorConfig.getProtocolApiUrl()) + .publicApiUrl(connectorConfig.getPublicApiUrl()) + .defaultApiUrl(connectorConfig.getDefaultApiUrl()) + .build(); + } } diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorRemoteConfigFactory.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorRemoteConfigFactory.java deleted file mode 100644 index e3d9c4440..000000000 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/ConnectorRemoteConfigFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2023 sovity 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: - * sovity GmbH - init - * - */ - -package de.sovity.edc.extension.e2e.connector.config; - -import de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroup; -import de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroupConfig; -import de.sovity.edc.extension.e2e.connector.config.api.auth.ApiKeyAuthProvider; -import de.sovity.edc.extension.e2e.connector.config.api.auth.NoneAuthProvider; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -import static de.sovity.edc.extension.e2e.connector.config.api.EdcApiConfigFactory.fromUri; -import static de.sovity.edc.extension.e2e.env.EnvUtil.getEnvVar; -import static de.sovity.edc.extension.e2e.env.EnvUtil.getEnvVarUri; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class ConnectorRemoteConfigFactory { - public static final String EDC_DEFAULT_URL = "%s_EDC_DEFAULT_URL"; - public static final String EDC_MANAGEMENT_URL = "%s_EDC_MANAGEMENT_URL"; - public static final String EDC_PROTOCOL_URL = "%s_EDC_PROTOCOL_URL"; - public static final String EDC_MANAGEMENT_AUTH_HEADER = "%s_EDC_MANAGEMENT_AUTH_HEADER"; - public static final String EDC_MANAGEMENT_AUTH_VALUE = "%s_EDC_MANAGEMENT_AUTH_VALUE"; - public static final String TEST_BACKEND_DEFAULT_ENDPOINT = "TEST_BACKEND_DEFAULT_ENDPOINT"; - - /** - * Access a locally launched connector - * - * @param connectorConfig connector config - * @return connector remote config - */ - public static ConnectorRemoteConfig fromConnectorConfig(ConnectorConfig connectorConfig) { - return new ConnectorRemoteConfig( - connectorConfig.getParticipantId(), - connectorConfig.getDefaultEndpoint(), - connectorConfig.getManagementEndpoint(), - connectorConfig.getProtocolEndpoint() - ); - } - - /** - * Access a connector started externally, e.g. by a Github Pipeline - * - * @param participantId participant id (prefix for env vars) - * @return connector remote config - */ - public static ConnectorRemoteConfig getFromEnv(String participantId) { - return new ConnectorRemoteConfig( - participantId, - getDefaultApiGroupConfig(participantId), - getManagementApiGroupConfig(participantId), - getProtocolApiGroupConfig(participantId) - ); - } - - private static EdcApiGroupConfig getDefaultApiGroupConfig(String participantId) { - var uri = getEnvVarUri(EDC_DEFAULT_URL.formatted(participantId)); - return fromUri(EdcApiGroup.DEFAULT, uri, new NoneAuthProvider()); - } - - private static EdcApiGroupConfig getProtocolApiGroupConfig(String participantId) { - var uri = getEnvVarUri(EDC_PROTOCOL_URL.formatted(participantId)); - return fromUri(EdcApiGroup.PROTOCOL, uri, new NoneAuthProvider()); - } - - private static EdcApiGroupConfig getManagementApiGroupConfig(String participantId) { - var uri = getEnvVarUri(EDC_MANAGEMENT_URL.formatted(participantId)); - var auth = new ApiKeyAuthProvider( - getEnvVar(EDC_MANAGEMENT_AUTH_HEADER.formatted(participantId)), - getEnvVar(EDC_MANAGEMENT_AUTH_VALUE.formatted(participantId))); - return fromUri(EdcApiGroup.MANAGEMENT, uri, auth); - } -} diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiConfig.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiConfig.java deleted file mode 100644 index 4aca4ef89..000000000 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiConfig.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 sovity 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: - * sovity GmbH - init - * - */ - -package de.sovity.edc.extension.e2e.connector.config.api; - - -import lombok.Builder; -import lombok.Value; - -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -@Value -@Builder -public class EdcApiConfig { - EdcApiGroupConfig defaultApiGroup; - EdcApiGroupConfig protocolApiGroup; - EdcApiGroupConfig managementApiGroup; - EdcApiGroupConfig controlApiGroup; - - public Map getProperties() { - return Stream.of(defaultApiGroup, protocolApiGroup, managementApiGroup, controlApiGroup) - .map(EdcApiGroupConfig::getProperties) - .flatMap(map -> map.entrySet().stream()) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } -} diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiConfigFactory.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiConfigFactory.java deleted file mode 100644 index 5f5f26302..000000000 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiConfigFactory.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2023 sovity 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: - * sovity GmbH - init - * - */ - -package de.sovity.edc.extension.e2e.connector.config.api; - -import de.sovity.edc.extension.e2e.connector.config.api.auth.ApiKeyAuthProvider; -import de.sovity.edc.extension.e2e.connector.config.api.auth.AuthProvider; -import de.sovity.edc.extension.e2e.connector.config.api.auth.NoneAuthProvider; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; - -import java.net.URI; - -import static de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroup.CONTROL; -import static de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroup.DEFAULT; -import static de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroup.MANAGEMENT; -import static de.sovity.edc.extension.e2e.connector.config.api.EdcApiGroup.PROTOCOL; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class EdcApiConfigFactory { - private static final String BASE_URL = "http://localhost"; - - /** - * Configures EDC API Endpoints by conventions with given port offset. - * - * @param firstPort port offset - * @param managementApiKey management API key - * @return {@link EdcApiConfig} - */ - public static EdcApiConfig configureApi(int firstPort, String managementApiKey) { - var defaultApiGroup = unprotected(DEFAULT, "/api", firstPort + 1); - var managementApiGroup = apiKeyAuth(MANAGEMENT, "/api/management", firstPort + 2, managementApiKey); - var protocolApiGroup = unprotected(PROTOCOL, "/api/dsp", firstPort + 3); - var unprotected = unprotected(CONTROL, "/api/control", firstPort + 4); - - return EdcApiConfig.builder() - .defaultApiGroup(defaultApiGroup) - .protocolApiGroup(protocolApiGroup) - .managementApiGroup(managementApiGroup) - .controlApiGroup(unprotected) - .build(); - } - - public static EdcApiGroupConfig fromUri(EdcApiGroup edcApiGroup, URI uri, AuthProvider authProvider) { - return new EdcApiGroupConfig( - edcApiGroup, - "%s://%s".formatted(uri.getScheme(), uri.getHost()), - uri.getPort(), - uri.getPath(), - authProvider - ); - } - - private static EdcApiGroupConfig unprotected( - EdcApiGroup edcApiGroup, - String path, - int port) { - return new EdcApiGroupConfig( - edcApiGroup, - BASE_URL, - port, - path, - new NoneAuthProvider() - ); - } - - private static EdcApiGroupConfig apiKeyAuth( - EdcApiGroup apiGroup, - String path, - int port, - String apiKey) { - return new EdcApiGroupConfig( - apiGroup, - BASE_URL, - port, - path, - new ApiKeyAuthProvider("X-Api-Key", apiKey)); - } -} diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiGroup.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiGroup.java deleted file mode 100644 index 46bc7dcb6..000000000 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiGroup.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2023 sovity 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: - * sovity GmbH - init - * - */ - -package de.sovity.edc.extension.e2e.connector.config.api; - - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Map; - -@Getter -@RequiredArgsConstructor -public enum EdcApiGroup { - DEFAULT(""), - PROTOCOL("protocol"), - MANAGEMENT("management"), - CONTROL("control"); - - private final String name; - - public Map getProperties(String path, int port) { - if (this == EdcApiGroup.DEFAULT) { - return Map.of( - "web.http.path", path, - "web.http.port", String.valueOf(port) - ); - } else { - return Map.of( - "web.http.%s.path".formatted(name), path, - "web.http.%s.port".formatted(name), String.valueOf(port)); - } - } -} diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiGroupConfig.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiGroupConfig.java deleted file mode 100644 index af579097e..000000000 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/EdcApiGroupConfig.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 sovity 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: - * sovity GmbH - init - * - */ - -package de.sovity.edc.extension.e2e.connector.config.api; - -import de.sovity.edc.extension.e2e.connector.config.api.auth.AuthProvider; -import lombok.With; - -import java.net.URI; -import java.util.Map; - -public record EdcApiGroupConfig( - EdcApiGroup edcApiGroup, - String baseUrl, - int port, - String path, - @With - AuthProvider authProvider -) { - - public URI getUri() { - return URI.create("%s:%s%s".formatted(baseUrl, port, path)); - } - - public Map getProperties() { - return edcApiGroup.getProperties(path, port); - } -} diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/ApiKeyAuthProvider.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/ApiKeyAuthProvider.java deleted file mode 100644 index 1b5919dfe..000000000 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/connector/config/api/auth/ApiKeyAuthProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2023 sovity 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: - * sovity GmbH - init - * - */ - -package de.sovity.edc.extension.e2e.connector.config.api.auth; - - -public record ApiKeyAuthProvider( - String headerName, - String apiKey) implements AuthProvider { - @Override - public String getAuthorizationHeader() { - return headerName; - } - - @Override - public String getAuthorizationHeaderValue() { - return apiKey; - } -} diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eScenario.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eScenario.java index faafe0d28..24e4335e6 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eScenario.java +++ b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eScenario.java @@ -73,13 +73,13 @@ public E2eScenario(ConnectorConfig consumerConfig, ConnectorConfig providerConfi this.mockServer = mockServer; consumerClient = EdcClient.builder() - .managementApiUrl(consumerConfig.getManagementEndpoint().getUri().toString()) - .managementApiKey(consumerConfig.getProperties().get("edc.api.auth.key")) + .managementApiUrl(consumerConfig.getManagementApiUrl()) + .managementApiKey(consumerConfig.getManagementApiKey()) .build(); providerClient = EdcClient.builder() - .managementApiUrl(providerConfig.getManagementEndpoint().getUri().toString()) - .managementApiKey(providerConfig.getProperties().get("edc.api.auth.key")) + .managementApiUrl(providerConfig.getManagementApiUrl()) + .managementApiKey(providerConfig.getManagementApiKey()) .build(); } @@ -171,7 +171,7 @@ public IdResponseDto createContractDefinition(String policyId, String assetId) { } public UiContractNegotiation negotiateAssetAndAwait(String assetId) { - val connectorEndpoint = providerConfig.getProtocolEndpoint().getUri().toString(); + val connectorEndpoint = providerConfig.getProtocolApiUrl(); val offers = consumerClient.uiApi().getCatalogPageDataOffers(connectorEndpoint); val offersContainingContract = offers.stream() diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eTestExtension.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eTestExtension.java index 54571fabd..e33abddaa 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eTestExtension.java +++ b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eTestExtension.java @@ -17,11 +17,9 @@ import de.sovity.edc.client.EdcClient; import de.sovity.edc.extension.e2e.connector.ConnectorRemote; import de.sovity.edc.extension.e2e.connector.config.ConnectorConfig; -import de.sovity.edc.extension.e2e.connector.config.ConnectorRemoteConfig; import de.sovity.edc.extension.e2e.db.EdcRuntimeExtensionWithTestDatabase; import de.sovity.edc.extension.utils.Lazy; import lombok.val; -import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterTestExecutionCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; @@ -36,6 +34,7 @@ import java.util.stream.Stream; import static de.sovity.edc.extension.e2e.connector.config.ConnectorConfigFactory.forTestDatabase; +import static de.sovity.edc.extension.e2e.connector.config.ConnectorRemoteConfig.fromConnectorConfig; import static org.eclipse.edc.junit.testfixtures.TestUtils.getFreePort; import static org.mockserver.stop.Stop.stopQuietly; @@ -162,7 +161,7 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte } else if (ConnectorConfig.class.equals(type)) { return consumerConfig; } else if (ConnectorRemote.class.equals(type)) { - return newConnectorRemote(config.getConsumerParticipantId(), consumerConfig); + return new ConnectorRemote(fromConnectorConfig(consumerConfig)); } else { return consumerExtension.resolveParameter(parameterContext, extensionContext); } @@ -174,7 +173,7 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte } else if (ConnectorConfig.class.equals(type)) { return providerConfig; } else if (ConnectorRemote.class.equals(type)) { - return newConnectorRemote(config.getProviderParticipantId(), providerConfig); + return new ConnectorRemote(fromConnectorConfig(providerConfig)); } else { return providerExtension.resolveParameter(parameterContext, extensionContext); } @@ -190,15 +189,6 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte "The parameters must be annotated by the EDC side: @Provider or @Consumer or be one of the supported classes."); } - private @NotNull ConnectorRemote newConnectorRemote(String participantId, ConnectorConfig config) { - return new ConnectorRemote( - new ConnectorRemoteConfig( - participantId, - config.getDefaultEndpoint(), - config.getManagementEndpoint(), - config.getProtocolEndpoint())); - } - private static boolean isProvider(ParameterContext parameterContext) { return parameterContext.getParameter().getDeclaredAnnotation(Provider.class) != null; } @@ -209,8 +199,8 @@ private static boolean isConsumer(ParameterContext parameterContext) { private EdcClient newEdcClient(ConnectorConfig consumerConfig) { return EdcClient.builder() - .managementApiUrl(consumerConfig.getManagementEndpoint().getUri().toString()) - .managementApiKey(consumerConfig.getProperties().get("edc.api.auth.key")) + .managementApiUrl(consumerConfig.getManagementApiUrl()) + .managementApiKey(consumerConfig.getManagementApiKey()) .build(); } } diff --git a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eTestExtensionConfig.java b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eTestExtensionConfig.java index 1bb12cea1..9cac7681d 100644 --- a/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eTestExtensionConfig.java +++ b/utils/test-utils/src/main/java/de/sovity/edc/extension/e2e/extension/E2eTestExtensionConfig.java @@ -33,14 +33,14 @@ public class E2eTestExtensionConfig { private String providerParticipantId = "provider"; @Builder.Default - private Consumer configCustomizer = (it) -> { + private Consumer configCustomizer = it -> { }; @Builder.Default - private Consumer consumerConfigCustomizer = (it) -> { + private Consumer consumerConfigCustomizer = it -> { }; @Builder.Default - private Consumer providerConfigCustomizer = (it) -> { + private Consumer providerConfigCustomizer = it -> { }; }