diff --git a/docs/developer/README.md b/docs/developer/README.md index f721e91803e..8c4fdfac399 100644 --- a/docs/developer/README.md +++ b/docs/developer/README.md @@ -11,6 +11,7 @@ ## Guides - [Customize Policy Engine](policy-engine.md) - [Performance Tuning](performance-tuning.md) +- [Sql persistence](sql-persistence.md) ## Build and testing - [OpenApi Spec Generation](openapi.md) diff --git a/docs/developer/sql-persistence.md b/docs/developer/sql-persistence.md new file mode 100644 index 00000000000..0cb54b8afc4 --- /dev/null +++ b/docs/developer/sql-persistence.md @@ -0,0 +1,41 @@ +# SQL persistence + +Every store in the EDC, intended as persistence for state, comes out of the box with two implementations: +- in-memory +- sql (postgresql dialect) + +By default, the `in-memory` stores are provided by the dependency injection, the `sql` implementations can be used by +simply registering the relative extensions (e.g. `asset-index-sql`, `contract-negotiation-store-sql`, ...). + +## Configuration + +### DataSources + +For using `sql` extensions, a `DataSource` is needed, and it should be registered on the `DataSourceRegistry` service. + +The `sql-pool-apache-commons` extension takes care to create and register pooled data sources starting from configuration. +It expects at least one data source called `default` that can be configured with `Vault` keys: +``` +edc.datasource.default.url=... +edc.datasource.default.name=... +edc.datasource.default.password=... +``` +(note: if no vault entries are found for such keys, they will be obtained from the configuration). + +Other datasources can be defined using the same settings structure: +``` +edc.datasource..url=... +edc.datasource..name=... +edc.datasource..password=... +``` + +`` can be a string that then can be used by the stores configuration to use specific data sources. + +### Using custom datasource in stores + +Using a custom datasource in a store can be done by configuring the setting: +``` +edc.sql.store..datasource= +``` + +This way the `` (that could be `asset`, `contractnegotiation`...) will use the `` datasource. diff --git a/extensions/common/sql/sql-core/src/main/java/org/eclipse/edc/sql/configuration/DataSourceName.java b/extensions/common/sql/sql-core/src/main/java/org/eclipse/edc/sql/configuration/DataSourceName.java new file mode 100644 index 00000000000..761e7d1ee6b --- /dev/null +++ b/extensions/common/sql/sql-core/src/main/java/org/eclipse/edc/sql/configuration/DataSourceName.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.sql.configuration; + +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.configuration.Config; + +import static org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry.DEFAULT_DATASOURCE; + +/** + * This interface is only functional to the migration from the old format to the new one. + * Ref. https://github.com/eclipse-edc/Connector/issues/3811 + */ +public interface DataSourceName { + + /** + * Extracts datasource name from configuration considering deprecated key as fallback. + * + * @param key the setting key. + * @param deprecatedKey the deprecate setting key. + * @param config the config. + * @param monitor the monitor. + * @return the datasource name + * @deprecated will be removed together with the deprecated settings. + */ + @Deprecated(since = "0.8.1") + static String getDataSourceName(String key, String deprecatedKey, Config config, Monitor monitor) { + var datasourceName = config.getString(key, null); + + if (datasourceName != null) { + return datasourceName; + } + + var name = config.getString(deprecatedKey, null); + + if (name != null) { + monitor.warning("Datasource name setting key %s has been deprecated, please switch to %s".formatted(deprecatedKey, key)); + return name; + } + + return DEFAULT_DATASOURCE; + } + +} diff --git a/extensions/common/sql/sql-pool/sql-pool-apache-commons/src/main/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtension.java b/extensions/common/sql/sql-pool/sql-pool-apache-commons/src/main/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtension.java index ce88f2f3d2e..4bcfe82c19f 100644 --- a/extensions/common/sql/sql-pool/sql-pool-apache-commons/src/main/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtension.java +++ b/extensions/common/sql/sql-pool/sql-pool-apache-commons/src/main/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtension.java @@ -27,17 +27,13 @@ import org.eclipse.edc.sql.datasource.ConnectionFactoryDataSource; import org.eclipse.edc.sql.datasource.ConnectionPoolDataSource; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; +import java.util.Optional; import java.util.Properties; import java.util.function.BiFunction; import java.util.function.Consumer; -import java.util.function.Supplier; import javax.sql.DataSource; import static java.util.Optional.ofNullable; @@ -48,24 +44,32 @@ public class CommonsConnectionPoolServiceExtension implements ServiceExtension { public static final String NAME = "Commons Connection Pool"; public static final String EDC_DATASOURCE_PREFIX = "edc.datasource"; + private static final String EDC_DATASOURCE_CONFIG_CONTEXT = EDC_DATASOURCE_PREFIX + "."; + + @Setting(value = "JDBC url", required = true, context = EDC_DATASOURCE_CONFIG_CONTEXT) + public static final String URL = "url"; + @Setting(value = "Username to be used for the JDBC connection. Can be omitted if not required, or if the user is encoded in the JDBC url.", context = EDC_DATASOURCE_CONFIG_CONTEXT) + public static final String USER = "user"; + @Setting(value = "Username to be used for the JDBC connection. Can be omitted if not required, or if the password is encoded in the JDBC url.", context = EDC_DATASOURCE_CONFIG_CONTEXT) + public static final String PASSWORD = "password"; + + @Setting(value = "Pool max idle connections", type = "int", context = EDC_DATASOURCE_CONFIG_CONTEXT) public static final String POOL_CONNECTIONS_MAX_IDLE = "pool.connections.max-idle"; + @Setting(value = "Pool max total connections", type = "int", context = EDC_DATASOURCE_CONFIG_CONTEXT) public static final String POOL_CONNECTIONS_MAX_TOTAL = "pool.connections.max-total"; + @Setting(value = "Pool min idle connections", type = "int", context = EDC_DATASOURCE_CONFIG_CONTEXT) public static final String POOL_CONNECTIONS_MIN_IDLE = "pool.connections.min-idle"; + @Setting(value = "Pool test on borrow", type = "boolean", context = EDC_DATASOURCE_CONFIG_CONTEXT) public static final String POOL_CONNECTION_TEST_ON_BORROW = "pool.connection.test.on-borrow"; + @Setting(value = "Pool test on create", type = "boolean", context = EDC_DATASOURCE_CONFIG_CONTEXT) public static final String POOL_CONNECTION_TEST_ON_CREATE = "pool.connection.test.on-create"; + @Setting(value = "Pool test on return", type = "boolean", context = EDC_DATASOURCE_CONFIG_CONTEXT) public static final String POOL_CONNECTION_TEST_ON_RETURN = "pool.connection.test.on-return"; + @Setting(value = "Pool test while idle", type = "boolean", context = EDC_DATASOURCE_CONFIG_CONTEXT) public static final String POOL_CONNECTION_TEST_WHILE_IDLE = "pool.connection.test.while-idle"; + @Setting(value = "Pool test query", context = EDC_DATASOURCE_CONFIG_CONTEXT) public static final String POOL_CONNECTION_TEST_QUERY = "pool.connection.test.query"; - @Setting(required = true) - public static final String URL = "url"; - - @Setting(value = "Username to be used for the JDBC connection. Can be omitted if not required, or if the user is encoded in the JDBC url.") - public static final String USER = "user"; - @Setting(value = "Username to be used for the JDBC connection. Can be omitted if not required, or if the password is encoded in the JDBC url.") - public static final String PASSWORD = "password"; - - private final List commonsConnectionPools = new LinkedList<>(); @Inject private DataSourceRegistry dataSourceRegistry; @@ -78,6 +82,8 @@ public class CommonsConnectionPoolServiceExtension implements ServiceExtension { @Inject private Vault vault; + private final List commonsConnectionPools = new LinkedList<>(); + @Override public String name() { return NAME; @@ -85,17 +91,14 @@ public String name() { @Override public void initialize(ServiceExtensionContext context) { - var config = context.getConfig(EDC_DATASOURCE_PREFIX); - - var namedConnectionPools = createConnectionPools(config); - - for (var entry : namedConnectionPools.entrySet()) { - var dataSourceName = entry.getKey(); - var commonsConnectionPool = entry.getValue(); - commonsConnectionPools.add(commonsConnectionPool); - var connectionPoolDataSource = new ConnectionPoolDataSource(commonsConnectionPool); + context.getConfig(EDC_DATASOURCE_PREFIX).partition().forEach(config -> { + var dataSourceName = config.currentNode(); + var dataSource = createDataSource(config); + var connectionPool = createConnectionPool(dataSource, config); + commonsConnectionPools.add(connectionPool); + var connectionPoolDataSource = new ConnectionPoolDataSource(connectionPool); dataSourceRegistry.register(dataSourceName, connectionPoolDataSource); - } + }); } @Override @@ -103,88 +106,51 @@ public void shutdown() { commonsConnectionPools.forEach(CommonsConnectionPool::close); } - public List getCommonsConnectionPools() { - return commonsConnectionPools; - } - - private @NotNull Supplier<@Nullable String> readFromConfig(Config config, String value) { - return () -> { - var entry = EDC_DATASOURCE_PREFIX + "." + config.currentNode() + "." + value; - monitor.warning("Database configuration value '%s' not found in vault, will fall back to Config. Please consider putting database configuration into the vault.".formatted(entry)); - return config.getString(value, null); - }; - } - - private void setIfProvidedString(String key, Consumer setter, Config config) { - setIfProvided(key, setter, config::getString); - } - - private void setIfProvidedBoolean(String key, Consumer setter, Config config) { - setIfProvided(key, setter, config::getBoolean); - } - - private void setIfProvidedInt(String key, Consumer setter, Config config) { - setIfProvided(key, setter, config::getInteger); - } - - private void setIfProvided(String key, Consumer setter, BiFunction getter) { - var value = getter.apply(key, null); - if (value != null) { - setter.accept(value); - } - } - - private Map createConnectionPools(Config parent) { - Map commonsConnectionPools = new HashMap<>(); - for (var config : parent.partition().toList()) { - var dataSourceName = config.currentNode(); - - var dataSource = createDataSource(config); - - var commonsConnectionPool = createConnectionPool(dataSource, config); - commonsConnectionPools.put(dataSourceName, commonsConnectionPool); - } - return commonsConnectionPools; - } - private DataSource createDataSource(Config config) { var rootPath = EDC_DATASOURCE_PREFIX + "." + config.currentNode(); - // read values from the vault first, fall back to config - var urlProperty = rootPath + "." + URL; - var jdbcUrl = ofNullable(vault.resolveSecret(urlProperty)).orElseGet(readFromConfig(config, URL)); - - if (jdbcUrl == null) { - throw new EdcException("Mandatory config '%s' not found. Please provide a value for the '%s' property, either as a secret in the vault or an application property.".formatted(urlProperty, urlProperty)); - } - - var jdbcUser = ofNullable(vault.resolveSecret(rootPath + "." + USER)) - .orElseGet(readFromConfig(config, USER)); - var jdbcPassword = ofNullable(vault.resolveSecret(rootPath + "." + PASSWORD)) - .orElseGet(readFromConfig(config, PASSWORD)); + var jdbcUrl = getSecretOrSetting(rootPath, URL, config) + .orElseThrow(() -> new EdcException("Mandatory url for datasource '%s' not found. Please provide a value for it, either as a secret in the vault or an application property.".formatted(config.currentNode()))); + var jdbcUser = getSecretOrSetting(rootPath, USER, config); + var jdbcPassword = getSecretOrSetting(rootPath, PASSWORD, config); var properties = new Properties(); properties.putAll(config.getRelativeEntries()); - // only set if not-null, otherwise Properties#add throws a NPE - ofNullable(jdbcUser).ifPresent(u -> properties.put(USER, u)); - ofNullable(jdbcPassword).ifPresent(p -> properties.put(PASSWORD, p)); + jdbcUser.ifPresent(u -> properties.put(USER, u)); + jdbcPassword.ifPresent(p -> properties.put(PASSWORD, p)); return new ConnectionFactoryDataSource(connectionFactory, jdbcUrl, properties); } + private Optional getSecretOrSetting(String rootPath, String key, Config config) { + var fullKey = rootPath + "." + key; + return ofNullable(vault.resolveSecret(fullKey)) + .or(() -> { + monitor.warning("Datasource configuration value '%s' not found in vault, will fall back to Config. Please consider putting datasource configuration into the vault.".formatted(fullKey)); + return Optional.ofNullable(config.getString(key, null)); + }); + } + private CommonsConnectionPool createConnectionPool(DataSource unPooledDataSource, Config config) { var builder = CommonsConnectionPoolConfig.Builder.newInstance(); - setIfProvidedInt(POOL_CONNECTIONS_MAX_IDLE, builder::maxIdleConnections, config); - setIfProvidedInt(POOL_CONNECTIONS_MAX_TOTAL, builder::maxTotalConnections, config); - setIfProvidedInt(POOL_CONNECTIONS_MIN_IDLE, builder::minIdleConnections, config); - setIfProvidedBoolean(POOL_CONNECTION_TEST_ON_BORROW, builder::testConnectionOnBorrow, config); - setIfProvidedBoolean(POOL_CONNECTION_TEST_ON_CREATE, builder::testConnectionOnCreate, config); - setIfProvidedBoolean(POOL_CONNECTION_TEST_ON_RETURN, builder::testConnectionOnReturn, config); - setIfProvidedBoolean(POOL_CONNECTION_TEST_WHILE_IDLE, builder::testConnectionWhileIdle, config); - setIfProvidedString(POOL_CONNECTION_TEST_QUERY, builder::testQuery, config); + setIfProvided(POOL_CONNECTIONS_MAX_IDLE, config::getInteger, builder::maxIdleConnections); + setIfProvided(POOL_CONNECTIONS_MAX_TOTAL, config::getInteger, builder::maxTotalConnections); + setIfProvided(POOL_CONNECTIONS_MIN_IDLE, config::getInteger, builder::minIdleConnections); + setIfProvided(POOL_CONNECTION_TEST_ON_BORROW, config::getBoolean, builder::testConnectionOnBorrow); + setIfProvided(POOL_CONNECTION_TEST_ON_CREATE, config::getBoolean, builder::testConnectionOnCreate); + setIfProvided(POOL_CONNECTION_TEST_ON_RETURN, config::getBoolean, builder::testConnectionOnReturn); + setIfProvided(POOL_CONNECTION_TEST_WHILE_IDLE, config::getBoolean, builder::testConnectionWhileIdle); + setIfProvided(POOL_CONNECTION_TEST_QUERY, config::getString, builder::testQuery); return new CommonsConnectionPool(unPooledDataSource, builder.build(), monitor); } + + private void setIfProvided(String key, BiFunction getter, Consumer setter) { + var value = getter.apply(key, null); + if (value != null) { + setter.accept(value); + } + } } diff --git a/extensions/common/sql/sql-pool/sql-pool-apache-commons/src/test/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtensionTest.java b/extensions/common/sql/sql-pool/sql-pool-apache-commons/src/test/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtensionTest.java index 84804734df1..f16c92a4e64 100644 --- a/extensions/common/sql/sql-pool/sql-pool-apache-commons/src/test/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtensionTest.java +++ b/extensions/common/sql/sql-pool/sql-pool-apache-commons/src/test/java/org/eclipse/edc/sql/pool/commons/CommonsConnectionPoolServiceExtensionTest.java @@ -20,9 +20,9 @@ import org.eclipse.edc.spi.EdcException; import org.eclipse.edc.spi.security.Vault; import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.system.configuration.ConfigFactory; import org.eclipse.edc.sql.ConnectionFactory; +import org.eclipse.edc.sql.datasource.ConnectionPoolDataSource; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -32,6 +32,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; +import org.mockito.ArgumentCaptor; import java.util.Map; import java.util.stream.Collectors; @@ -39,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.InstanceOfAssertFactories.type; import static org.eclipse.edc.sql.pool.commons.CommonsConnectionPoolServiceExtension.EDC_DATASOURCE_PREFIX; import static org.eclipse.edc.sql.pool.commons.CommonsConnectionPoolServiceExtension.POOL_CONNECTIONS_MAX_IDLE; import static org.eclipse.edc.sql.pool.commons.CommonsConnectionPoolServiceExtension.POOL_CONNECTIONS_MAX_TOTAL; @@ -48,14 +50,12 @@ import static org.eclipse.edc.sql.pool.commons.CommonsConnectionPoolServiceExtension.POOL_CONNECTION_TEST_ON_RETURN; import static org.eclipse.edc.sql.pool.commons.CommonsConnectionPoolServiceExtension.POOL_CONNECTION_TEST_QUERY; import static org.eclipse.edc.sql.pool.commons.CommonsConnectionPoolServiceExtension.POOL_CONNECTION_TEST_WHILE_IDLE; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -//sometimes hangs and causes the test to never finish. @ExtendWith(DependencyInjectionExtension.class) class CommonsConnectionPoolServiceExtensionTest { private static final String DS_1_NAME = "ds1"; @@ -74,21 +74,16 @@ void setUp(ServiceExtensionContext context) { void initialize_withConfig(Map configuration, ThrowingConsumer checker, boolean isEnv, CommonsConnectionPoolServiceExtension extension, ServiceExtensionContext context) { - Config config; - if (isEnv) { - config = ConfigFactory.fromEnvironment(configuration); - } else { - config = ConfigFactory.fromMap(configuration); - } + var config = isEnv ? ConfigFactory.fromEnvironment(configuration) : ConfigFactory.fromMap(configuration); when(context.getConfig(EDC_DATASOURCE_PREFIX)).thenReturn(config); extension.initialize(context); - verify(dataSourceRegistry).register(eq(DS_1_NAME), any()); - - assertThat(extension.getCommonsConnectionPools()).hasSize(1).first() - .extracting(CommonsConnectionPool::getPoolConfig) - .satisfies(checker); + var captor = ArgumentCaptor.forClass(ConnectionPoolDataSource.class); + verify(dataSourceRegistry).register(eq(DS_1_NAME), captor.capture()); + assertThat(captor.getAllValues()).hasSize(1).first() + .extracting("connectionPool").asInstanceOf(type(CommonsConnectionPool.class)) + .extracting(CommonsConnectionPool::getPoolConfig).satisfies(checker); } @Test @@ -103,8 +98,10 @@ void initialize_fromVault(CommonsConnectionPoolServiceExtension extension, Servi extension.initialize(context); - verify(dataSourceRegistry).register(eq(DS_1_NAME), any()); - assertThat(extension.getCommonsConnectionPools()).hasSize(1).first() + var captor = ArgumentCaptor.forClass(ConnectionPoolDataSource.class); + verify(dataSourceRegistry).register(eq(DS_1_NAME), captor.capture()); + assertThat(captor.getAllValues()).hasSize(1).first() + .extracting("connectionPool").asInstanceOf(type(CommonsConnectionPool.class)) .satisfies(pool -> { assertThatThrownBy(pool::getConnection).isInstanceOf(EdcException.class); //we need this only to invoke the connection factory verify(connectionFactory).create(eq("jdbc://whatever"), argThat(p -> @@ -129,8 +126,10 @@ void initialize_fromVault_shouldOverrideConfig(CommonsConnectionPoolServiceExten extension.initialize(context); - verify(dataSourceRegistry).register(eq(DS_1_NAME), any()); - assertThat(extension.getCommonsConnectionPools()).hasSize(1).first() + var captor = ArgumentCaptor.forClass(ConnectionPoolDataSource.class); + verify(dataSourceRegistry).register(eq(DS_1_NAME), captor.capture()); + assertThat(captor.getAllValues()).hasSize(1).first() + .extracting("connectionPool").asInstanceOf(type(CommonsConnectionPool.class)) .satisfies(pool -> { assertThatThrownBy(pool::getConnection).isInstanceOf(EdcException.class); //we need this only to invoke the connection factory verify(connectionFactory).create(eq("jdbc://whatever"), argThat(p -> @@ -140,7 +139,6 @@ void initialize_fromVault_shouldOverrideConfig(CommonsConnectionPoolServiceExten }); } - static class ConfigProvider implements ArgumentsProvider { private final Map defaultConfig = Map.of(DS_1_NAME + ".url", DS_1_NAME); diff --git a/extensions/common/store/sql/edr-index-sql/src/main/java/org/eclipse/edc/edr/store/index/SqlEndpointDataReferenceEntryIndexExtension.java b/extensions/common/store/sql/edr-index-sql/src/main/java/org/eclipse/edc/edr/store/index/SqlEndpointDataReferenceEntryIndexExtension.java index bc80602a3b0..1ced68fa511 100644 --- a/extensions/common/store/sql/edr-index-sql/src/main/java/org/eclipse/edc/edr/store/index/SqlEndpointDataReferenceEntryIndexExtension.java +++ b/extensions/common/store/sql/edr-index-sql/src/main/java/org/eclipse/edc/edr/store/index/SqlEndpointDataReferenceEntryIndexExtension.java @@ -27,6 +27,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -34,12 +35,12 @@ @Extension(value = "SQL edr entry store") public class SqlEndpointDataReferenceEntryIndexExtension implements ServiceExtension { - /** - * Name of the datasource to use for accessing edr entries. - */ - @Setting(required = true) + @Deprecated(since = "0.8.1") public static final String DATASOURCE_SETTING_NAME = "edc.datasource.edr.name"; + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.edr.datasource"; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -60,7 +61,7 @@ public class SqlEndpointDataReferenceEntryIndexExtension implements ServiceExten @Override public void initialize(ServiceExtensionContext context) { - var dataSourceName = context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); var sqlStore = new SqlEndpointDataReferenceEntryIndex(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), getStatementImpl(), queryExecutor); diff --git a/extensions/common/store/sql/edr-index-sql/src/test/java/org/eclipse/edc/edr/store/index/sql/SqlEndpointDataReferenceEntryIndexExtensionTest.java b/extensions/common/store/sql/edr-index-sql/src/test/java/org/eclipse/edc/edr/store/index/sql/SqlEndpointDataReferenceEntryIndexExtensionTest.java index 7dc0e423f51..33717c5708a 100644 --- a/extensions/common/store/sql/edr-index-sql/src/test/java/org/eclipse/edc/edr/store/index/sql/SqlEndpointDataReferenceEntryIndexExtensionTest.java +++ b/extensions/common/store/sql/edr-index-sql/src/test/java/org/eclipse/edc/edr/store/index/sql/SqlEndpointDataReferenceEntryIndexExtensionTest.java @@ -22,14 +22,14 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.edr.store.index.SqlEndpointDataReferenceEntryIndexExtension.DATASOURCE_SETTING_NAME; +import static org.eclipse.edc.edr.store.index.SqlEndpointDataReferenceEntryIndexExtension.DATASOURCE_NAME; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -37,7 +37,6 @@ @ExtendWith(DependencyInjectionExtension.class) public class SqlEndpointDataReferenceEntryIndexExtensionTest { - @BeforeEach void setUp(ServiceExtensionContext context) { context.registerService(TypeManager.class, new JacksonTypeManager()); @@ -54,6 +53,6 @@ void shouldInitializeTheStore(SqlEndpointDataReferenceEntryIndexExtension extens var service = context.getService(EndpointDataReferenceEntryIndex.class); assertThat(service).isInstanceOf(SqlEndpointDataReferenceEntryIndex.class); - verify(config).getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + verify(config).getString(eq(DATASOURCE_NAME), any()); } } diff --git a/extensions/control-plane/store/sql/asset-index-sql/README.md b/extensions/control-plane/store/sql/asset-index-sql/README.md index 23c6fdfa0de..e655764a304 100644 --- a/extensions/control-plane/store/sql/asset-index-sql/README.md +++ b/extensions/control-plane/store/sql/asset-index-sql/README.md @@ -37,12 +37,6 @@ edc_asset ||--o{ edc_asset_property ``` --> -## Configuration - -| Key | Description | Mandatory | -|:--------------------------|:----------------------------------|-----------| -| edc.datasource.asset.name | Datasource used by this extension | X | - ## Migrate from 0.3.1 to 0.3.2 This table structure has been changed, from 3 tables (one for the asset, one for properties and one for data address) to diff --git a/extensions/control-plane/store/sql/asset-index-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/assetindex/SqlAssetIndexServiceExtension.java b/extensions/control-plane/store/sql/asset-index-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/assetindex/SqlAssetIndexServiceExtension.java index e5d9b88cec5..b0833c2df22 100644 --- a/extensions/control-plane/store/sql/asset-index-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/assetindex/SqlAssetIndexServiceExtension.java +++ b/extensions/control-plane/store/sql/asset-index-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/assetindex/SqlAssetIndexServiceExtension.java @@ -28,6 +28,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -35,12 +36,12 @@ @Extension(value = "SQL asset index") public class SqlAssetIndexServiceExtension implements ServiceExtension { - /** - * Name of the datasource to use for accessing assets. - */ - @Setting(required = true) + @Deprecated(since = "0.8.1") public static final String DATASOURCE_SETTING_NAME = "edc.datasource.asset.name"; + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.asset.datasource"; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -61,7 +62,7 @@ public class SqlAssetIndexServiceExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - var dataSourceName = context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); var sqlAssetLoader = new SqlAssetIndex(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), getDialect(), queryExecutor); diff --git a/extensions/control-plane/store/sql/asset-index-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/assetindex/SqlAssetIndexServiceExtensionTest.java b/extensions/control-plane/store/sql/asset-index-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/assetindex/SqlAssetIndexServiceExtensionTest.java index bfd2c7b5dd9..0972a8f7c98 100644 --- a/extensions/control-plane/store/sql/asset-index-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/assetindex/SqlAssetIndexServiceExtensionTest.java +++ b/extensions/control-plane/store/sql/asset-index-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/assetindex/SqlAssetIndexServiceExtensionTest.java @@ -21,14 +21,14 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.controlplane.store.sql.assetindex.SqlAssetIndexServiceExtension.DATASOURCE_SETTING_NAME; +import static org.eclipse.edc.connector.controlplane.store.sql.assetindex.SqlAssetIndexServiceExtension.DATASOURCE_NAME; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -55,6 +55,6 @@ void shouldInitializeTheStore(SqlAssetIndexServiceExtension extension, ServiceEx var dataAddressResolver = context.getService(DataAddressResolver.class); assertThat(dataAddressResolver).isInstanceOf(SqlAssetIndex.class); - verify(config).getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + verify(config).getString(eq(DATASOURCE_NAME), any()); } } diff --git a/extensions/control-plane/store/sql/contract-definition-store-sql/README.md b/extensions/control-plane/store/sql/contract-definition-store-sql/README.md index f2d12342d34..011cedf8a96 100644 --- a/extensions/control-plane/store/sql/contract-definition-store-sql/README.md +++ b/extensions/control-plane/store/sql/contract-definition-store-sql/README.md @@ -10,12 +10,6 @@ Please apply this [schema](src/main/resources/contract-definition-schema.sql) to ![ER Diagram](docs/er.png) -## Configuration - -| Key | Description | Mandatory | -|:---------------------------------------|:----------------------------------|-----------| -| edc.datasource.contractdefinition.name | Datasource used by this extension | X | - ## Create a flexible query API to accommodate `QuerySpec` _For the first version, only the `limit` and `offset` arguments from the `QuerySpec` will be used._ diff --git a/extensions/control-plane/store/sql/contract-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/contractdefinition/SqlContractDefinitionStoreExtension.java b/extensions/control-plane/store/sql/contract-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/contractdefinition/SqlContractDefinitionStoreExtension.java index 37c6bcfc643..e64f8f9e7fb 100644 --- a/extensions/control-plane/store/sql/contract-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/contractdefinition/SqlContractDefinitionStoreExtension.java +++ b/extensions/control-plane/store/sql/contract-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/contractdefinition/SqlContractDefinitionStoreExtension.java @@ -28,6 +28,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -35,12 +36,12 @@ @Extension(value = "SQL contract definition store") public class SqlContractDefinitionStoreExtension implements ServiceExtension { - /** - * Name of the datasource to use for accessing contract definitions. - */ - @Setting(required = true) + @Deprecated(since = "0.8.1") public static final String DATASOURCE_SETTING_NAME = "edc.datasource.contractdefinition.name"; + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.contractdefinition.datasource"; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -61,7 +62,7 @@ public class SqlContractDefinitionStoreExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - var dataSourceName = context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); var sqlContractDefinitionStore = new SqlContractDefinitionStore(dataSourceRegistry, dataSourceName, transactionContext, getStatementImpl(), typeManager.getMapper(), queryExecutor); diff --git a/extensions/control-plane/store/sql/contract-definition-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/contractdefinition/SqlContractDefinitionStoreExtensionTest.java b/extensions/control-plane/store/sql/contract-definition-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/contractdefinition/SqlContractDefinitionStoreExtensionTest.java index 9432d32bcbc..85de18e1f49 100644 --- a/extensions/control-plane/store/sql/contract-definition-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/contractdefinition/SqlContractDefinitionStoreExtensionTest.java +++ b/extensions/control-plane/store/sql/contract-definition-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/contractdefinition/SqlContractDefinitionStoreExtensionTest.java @@ -20,14 +20,14 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.controlplane.store.sql.contractdefinition.SqlContractDefinitionStoreExtension.DATASOURCE_SETTING_NAME; +import static org.eclipse.edc.connector.controlplane.store.sql.contractdefinition.SqlContractDefinitionStoreExtension.DATASOURCE_NAME; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -35,7 +35,6 @@ @ExtendWith(DependencyInjectionExtension.class) public class SqlContractDefinitionStoreExtensionTest { - @BeforeEach void setUp(ServiceExtensionContext context) { context.registerService(TypeManager.class, new JacksonTypeManager()); @@ -52,6 +51,6 @@ void shouldInitializeTheStore(SqlContractDefinitionStoreExtension extension, Ser var service = context.getService(ContractDefinitionStore.class); assertThat(service).isInstanceOf(ContractDefinitionStore.class); - verify(config).getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + verify(config).getString(eq(DATASOURCE_NAME), any()); } } diff --git a/extensions/control-plane/store/sql/contract-negotiation-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/contractnegotiation/SqlContractNegotiationStoreExtension.java b/extensions/control-plane/store/sql/contract-negotiation-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/contractnegotiation/SqlContractNegotiationStoreExtension.java index 8671a46fc11..84543e37bd4 100644 --- a/extensions/control-plane/store/sql/contract-negotiation-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/contractnegotiation/SqlContractNegotiationStoreExtension.java +++ b/extensions/control-plane/store/sql/contract-negotiation-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/contractnegotiation/SqlContractNegotiationStoreExtension.java @@ -21,11 +21,13 @@ import org.eclipse.edc.runtime.metamodel.annotation.Extension; 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.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -35,7 +37,11 @@ @Extension(value = "SQL contract negotiation store") public class SqlContractNegotiationStoreExtension implements ServiceExtension { - public static final String DATASOURCE_NAME_SETTING = "edc.datasource.contractnegotiation.name"; + @Deprecated(since = "0.8.1") + public static final String DATASOURCE_SETTING_NAME = "edc.datasource.contractnegotiation.name"; + + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.contractnegotiation.datasource"; @Inject private DataSourceRegistry dataSourceRegistry; @@ -60,7 +66,8 @@ public class SqlContractNegotiationStoreExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - var dataSourceName = getDataSourceName(context); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); + var sqlStore = new SqlContractNegotiationStore(dataSourceRegistry, dataSourceName, trxContext, typeManager.getMapper(), getStatementImpl(), context.getRuntimeId(), clock, queryExecutor); context.registerService(ContractNegotiationStore.class, sqlStore); @@ -76,6 +83,6 @@ private ContractNegotiationStatements getStatementImpl() { } private String getDataSourceName(ServiceExtensionContext context) { - return context.getConfig().getString(DATASOURCE_NAME_SETTING, DataSourceRegistry.DEFAULT_DATASOURCE); + return context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); } } diff --git a/extensions/control-plane/store/sql/contract-negotiation-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/contractnegotiation/SqlContractNegotiationStoreExtensionTest.java b/extensions/control-plane/store/sql/contract-negotiation-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/contractnegotiation/SqlContractNegotiationStoreExtensionTest.java index 272cc347e9d..410f0947212 100644 --- a/extensions/control-plane/store/sql/contract-negotiation-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/contractnegotiation/SqlContractNegotiationStoreExtensionTest.java +++ b/extensions/control-plane/store/sql/contract-negotiation-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/contractnegotiation/SqlContractNegotiationStoreExtensionTest.java @@ -33,7 +33,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.eclipse.edc.connector.controlplane.store.sql.contractnegotiation.SqlContractNegotiationStoreExtension.DATASOURCE_NAME_SETTING; +import static org.eclipse.edc.connector.controlplane.store.sql.contractnegotiation.SqlContractNegotiationStoreExtension.DATASOURCE_NAME; +import static org.eclipse.edc.connector.controlplane.store.sql.contractnegotiation.SqlContractNegotiationStoreExtension.DATASOURCE_SETTING_NAME; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -47,7 +50,7 @@ class SqlContractNegotiationStoreExtensionTest { void initialize(ServiceExtensionContext context, ObjectFactory factory) { var config = mock(Config.class); when(context.getConfig()).thenReturn(config); - when(config.getString(DATASOURCE_NAME_SETTING, DataSourceRegistry.DEFAULT_DATASOURCE)).thenReturn("test"); + when(config.getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE)).thenReturn("test"); context.registerService(DataSourceRegistry.class, mock(DataSourceRegistry.class)); context.registerService(TransactionContext.class, mock(TransactionContext.class)); @@ -61,7 +64,7 @@ void initialize(ServiceExtensionContext context, ObjectFactory factory) { var service = context.getService(ContractNegotiationStore.class); assertThat(service).isInstanceOf(SqlContractNegotiationStore.class); assertThat(service).extracting("statements").isInstanceOf(BaseSqlDialectStatements.class); - verify(config).getString(DATASOURCE_NAME_SETTING, DataSourceRegistry.DEFAULT_DATASOURCE); + verify(config).getString(eq(DATASOURCE_NAME), any()); } diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/README.md b/extensions/control-plane/store/sql/policy-definition-store-sql/README.md index a5ac9007a29..b183519ab10 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/README.md +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/README.md @@ -34,9 +34,3 @@ entity edc_policydefinitions { @enduml ``` --> - -## Configuration - -| Key | Description | Mandatory | -|:---------------------------|:----------------------------------|-----------| -| edc.datasource.policy.name | Datasource used by this extension | X | diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/SqlPolicyStoreExtension.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/SqlPolicyStoreExtension.java index 821c19f7def..2c0ee1b1dd2 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/SqlPolicyStoreExtension.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/SqlPolicyStoreExtension.java @@ -27,6 +27,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -34,9 +35,12 @@ @Extension("SQL policy store") public class SqlPolicyStoreExtension implements ServiceExtension { - @Setting(required = true) + @Deprecated(since = "0.8.1") public static final String DATASOURCE_SETTING_NAME = "edc.datasource.policy.name"; + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.policy.datasource"; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -56,7 +60,8 @@ public class SqlPolicyStoreExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - var dataSourceName = getDataSourceName(context); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); + var sqlPolicyStore = new SqlPolicyDefinitionStore(dataSourceRegistry, dataSourceName, transactionContext, typeManager.getMapper(), getStatementImpl(), queryExecutor); diff --git a/extensions/control-plane/store/sql/policy-definition-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/SqlPolicyDefinitionStoreExtensionTest.java b/extensions/control-plane/store/sql/policy-definition-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/SqlPolicyDefinitionStoreExtensionTest.java index 904c1019398..1dadbaca162 100644 --- a/extensions/control-plane/store/sql/policy-definition-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/SqlPolicyDefinitionStoreExtensionTest.java +++ b/extensions/control-plane/store/sql/policy-definition-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/policydefinition/SqlPolicyDefinitionStoreExtensionTest.java @@ -21,14 +21,14 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.controlplane.store.sql.policydefinition.SqlPolicyStoreExtension.DATASOURCE_SETTING_NAME; +import static org.eclipse.edc.connector.controlplane.store.sql.policydefinition.SqlPolicyStoreExtension.DATASOURCE_NAME; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -53,6 +53,6 @@ void shouldInitializeTheStore(SqlPolicyStoreExtension extension, ServiceExtensio var service = context.getService(PolicyDefinitionStore.class); assertThat(service).isInstanceOf(SqlPolicyDefinitionStore.class); - verify(config).getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + verify(config).getString(eq(DATASOURCE_NAME), any()); } } diff --git a/extensions/control-plane/store/sql/transfer-process-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/transferprocess/SqlTransferProcessStoreExtension.java b/extensions/control-plane/store/sql/transfer-process-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/transferprocess/SqlTransferProcessStoreExtension.java index 1b4542080c5..81ee4b8eaba 100644 --- a/extensions/control-plane/store/sql/transfer-process-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/transferprocess/SqlTransferProcessStoreExtension.java +++ b/extensions/control-plane/store/sql/transfer-process-store-sql/src/main/java/org/eclipse/edc/connector/controlplane/store/sql/transferprocess/SqlTransferProcessStoreExtension.java @@ -27,6 +27,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -36,8 +37,11 @@ @Extension(value = "SQL transfer process store") public class SqlTransferProcessStoreExtension implements ServiceExtension { - @Setting - public static final String DATASOURCE_NAME_SETTING = "edc.datasource.transferprocess.name"; + @Deprecated(since = "0.8.1") + public static final String DATASOURCE_SETTING_NAME = "edc.datasource.transferprocess.name"; + + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.transferprocess.datasource"; @Inject private DataSourceRegistry dataSourceRegistry; @@ -60,7 +64,8 @@ public class SqlTransferProcessStoreExtension implements ServiceExtension { @Override public void initialize(ServiceExtensionContext context) { - var dataSourceName = getDataSourceName(context); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); + var store = new SqlTransferProcessStore(dataSourceRegistry, dataSourceName, trxContext, typeManager.getMapper(), getStatementImpl(), context.getRuntimeId(), clock, queryExecutor); context.registerService(TransferProcessStore.class, store); @@ -75,7 +80,4 @@ private TransferProcessStoreStatements getStatementImpl() { return statements != null ? statements : new PostgresDialectStatements(); } - private String getDataSourceName(ServiceExtensionContext context) { - return context.getConfig().getString(DATASOURCE_NAME_SETTING, DataSourceRegistry.DEFAULT_DATASOURCE); - } } diff --git a/extensions/control-plane/store/sql/transfer-process-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/transferprocess/SqlTransferProcessStoreExtensionTest.java b/extensions/control-plane/store/sql/transfer-process-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/transferprocess/SqlTransferProcessStoreExtensionTest.java index b81a7ee36e0..f55cc38b075 100644 --- a/extensions/control-plane/store/sql/transfer-process-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/transferprocess/SqlTransferProcessStoreExtensionTest.java +++ b/extensions/control-plane/store/sql/transfer-process-store-sql/src/test/java/org/eclipse/edc/connector/controlplane/store/sql/transferprocess/SqlTransferProcessStoreExtensionTest.java @@ -21,14 +21,14 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.controlplane.store.sql.transferprocess.SqlTransferProcessStoreExtension.DATASOURCE_NAME_SETTING; +import static org.eclipse.edc.connector.controlplane.store.sql.transferprocess.SqlTransferProcessStoreExtension.DATASOURCE_NAME; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -52,6 +52,6 @@ void shouldInitializeTheStore(SqlTransferProcessStoreExtension extension, Servic var service = context.getService(TransferProcessStore.class); assertThat(service).isInstanceOf(SqlTransferProcessStore.class); - verify(config).getString(DATASOURCE_NAME_SETTING, DataSourceRegistry.DEFAULT_DATASOURCE); + verify(config).getString(eq(DATASOURCE_NAME), any()); } } diff --git a/extensions/data-plane-selector/store/sql/data-plane-instance-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/selector/store/sql/SqlDataPlaneInstanceStoreExtension.java b/extensions/data-plane-selector/store/sql/data-plane-instance-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/selector/store/sql/SqlDataPlaneInstanceStoreExtension.java index a47b069b5ff..7df92adda69 100644 --- a/extensions/data-plane-selector/store/sql/data-plane-instance-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/selector/store/sql/SqlDataPlaneInstanceStoreExtension.java +++ b/extensions/data-plane-selector/store/sql/data-plane-instance-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/selector/store/sql/SqlDataPlaneInstanceStoreExtension.java @@ -27,6 +27,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -40,8 +41,13 @@ public class SqlDataPlaneInstanceStoreExtension implements ServiceExtension { public static final String NAME = "Sql Data Plane Instance Store"; + @Deprecated(since = "0.8.1") @Setting(value = "Name of the datasource to use for accessing data plane instances") public static final String DATASOURCE_SETTING_NAME = "edc.datasource.dataplaneinstance.name"; + + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.dataplaneinstance.datasource"; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -70,7 +76,8 @@ public String name() { @Provider public DataPlaneInstanceStore dataPlaneInstanceStore(ServiceExtensionContext context) { - var dataSourceName = getDataSourceName(context); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); + sqlSchemaBootstrapper.addStatementFromResource(dataSourceName, "dataplane-instance-schema.sql"); return new SqlDataPlaneInstanceStore(dataSourceRegistry, dataSourceName, transactionContext, getStatementImpl(), typeManager.getMapper(), queryExecutor, clock, context.getRuntimeId()); @@ -83,7 +90,4 @@ private DataPlaneInstanceStatements getStatementImpl() { return statements != null ? statements : new PostgresDataPlaneInstanceStatements(); } - private String getDataSourceName(ServiceExtensionContext context) { - return context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); - } } diff --git a/extensions/data-plane-selector/store/sql/data-plane-instance-store-sql/src/test/java/org/eclipse/edc/connector/dataplane/selector/store/sql/SqlDataPlaneInstanceStoreExtensionTest.java b/extensions/data-plane-selector/store/sql/data-plane-instance-store-sql/src/test/java/org/eclipse/edc/connector/dataplane/selector/store/sql/SqlDataPlaneInstanceStoreExtensionTest.java index c9c869fdab5..2c813bc488d 100644 --- a/extensions/data-plane-selector/store/sql/data-plane-instance-store-sql/src/test/java/org/eclipse/edc/connector/dataplane/selector/store/sql/SqlDataPlaneInstanceStoreExtensionTest.java +++ b/extensions/data-plane-selector/store/sql/data-plane-instance-store-sql/src/test/java/org/eclipse/edc/connector/dataplane/selector/store/sql/SqlDataPlaneInstanceStoreExtensionTest.java @@ -19,14 +19,14 @@ import org.eclipse.edc.spi.system.ServiceExtensionContext; import org.eclipse.edc.spi.system.configuration.Config; import org.eclipse.edc.spi.types.TypeManager; -import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.edc.connector.dataplane.selector.store.sql.SqlDataPlaneInstanceStoreExtension.DATASOURCE_SETTING_NAME; +import static org.eclipse.edc.connector.dataplane.selector.store.sql.SqlDataPlaneInstanceStoreExtension.DATASOURCE_NAME; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -48,6 +48,6 @@ void shouldInitializeTheStore(ServiceExtensionContext context, SqlDataPlaneInsta var store = extension.dataPlaneInstanceStore(context); assertThat(store).isInstanceOf(SqlDataPlaneInstanceStore.class); - verify(config).getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); + verify(config).getString(eq(DATASOURCE_NAME), any()); } } diff --git a/extensions/data-plane/store/sql/accesstokendata-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/store/sql/SqlAccessTokenDataStoreExtension.java b/extensions/data-plane/store/sql/accesstokendata-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/store/sql/SqlAccessTokenDataStoreExtension.java index 4577e286cf7..7a7c8922711 100644 --- a/extensions/data-plane/store/sql/accesstokendata-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/store/sql/SqlAccessTokenDataStoreExtension.java +++ b/extensions/data-plane/store/sql/accesstokendata-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/store/sql/SqlAccessTokenDataStoreExtension.java @@ -27,6 +27,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -40,9 +41,13 @@ public class SqlAccessTokenDataStoreExtension implements ServiceExtension { public static final String NAME = "Sql AccessTokenData Store"; + @Deprecated(since = "0.8.1") @Setting(value = "Name of the datasource to use for accessing data plane store") private static final String DATASOURCE_SETTING_NAME = "edc.datasource.accesstokendata.name"; + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.accesstokendata.datasource"; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -70,7 +75,8 @@ public String name() { @Provider public AccessTokenDataStore dataPlaneStore(ServiceExtensionContext context) { - var dataSourceName = getDataSourceName(context); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); + sqlSchemaBootstrapper.addStatementFromResource(dataSourceName, "accesstoken-data-schema.sql"); return new SqlAccessTokenDataStore(dataSourceRegistry, dataSourceName, transactionContext, getStatementImpl(), typeManager.getMapper(), queryExecutor); @@ -83,7 +89,4 @@ private AccessTokenDataStatements getStatementImpl() { return statements != null ? statements : new PostgresAccessTokenDataStatements(); } - private String getDataSourceName(ServiceExtensionContext context) { - return context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); - } } diff --git a/extensions/data-plane/store/sql/data-plane-store-sql/README.md b/extensions/data-plane/store/sql/data-plane-store-sql/README.md index 5f44ca01b9d..67cc02d90d2 100644 --- a/extensions/data-plane/store/sql/data-plane-store-sql/README.md +++ b/extensions/data-plane/store/sql/data-plane-store-sql/README.md @@ -20,9 +20,3 @@ entity edc_data_plane { ``` --> - -## Configuration - -| Key | Description | Mandatory | -|:------------------------------|:----------------------------------|-----------| -| edc.datasource.dataplane.name | Datasource used by this extension | X | diff --git a/extensions/data-plane/store/sql/data-plane-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/store/sql/SqlDataPlaneStoreExtension.java b/extensions/data-plane/store/sql/data-plane-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/store/sql/SqlDataPlaneStoreExtension.java index b9a7378766b..874df08169c 100644 --- a/extensions/data-plane/store/sql/data-plane-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/store/sql/SqlDataPlaneStoreExtension.java +++ b/extensions/data-plane/store/sql/data-plane-store-sql/src/main/java/org/eclipse/edc/connector/dataplane/store/sql/SqlDataPlaneStoreExtension.java @@ -26,6 +26,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -39,9 +40,13 @@ public class SqlDataPlaneStoreExtension implements ServiceExtension { public static final String NAME = "Sql Data Plane Store"; + @Deprecated(since = "0.8.1") @Setting(value = "Name of the datasource to use for accessing data plane store") private static final String DATASOURCE_SETTING_NAME = "edc.datasource.dataplane.name"; + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.dataplane.datasource"; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -69,7 +74,8 @@ public String name() { @Provider public DataPlaneStore dataPlaneStore(ServiceExtensionContext context) { - var dataSourceName = getDataSourceName(context); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); + sqlSchemaBootstrapper.addStatementFromResource(dataSourceName, "dataplane-schema.sql"); return new SqlDataPlaneStore(dataSourceRegistry, dataSourceName, transactionContext, getStatementImpl(), typeManager.getMapper(), clock, queryExecutor, context.getRuntimeId()); @@ -81,8 +87,4 @@ public DataPlaneStore dataPlaneStore(ServiceExtensionContext context) { private DataPlaneStatements getStatementImpl() { return statements != null ? statements : new PostgresDataPlaneStatements(); } - - private String getDataSourceName(ServiceExtensionContext context) { - return context.getConfig().getString(DATASOURCE_SETTING_NAME, DataSourceRegistry.DEFAULT_DATASOURCE); - } } diff --git a/extensions/policy-monitor/store/sql/policy-monitor-store-sql/src/main/java/org/eclipse/edc/connector/policy/monitor/store/sql/SqlPolicyMonitorStoreExtension.java b/extensions/policy-monitor/store/sql/policy-monitor-store-sql/src/main/java/org/eclipse/edc/connector/policy/monitor/store/sql/SqlPolicyMonitorStoreExtension.java index fff770ea7f1..3420ebdff23 100644 --- a/extensions/policy-monitor/store/sql/policy-monitor-store-sql/src/main/java/org/eclipse/edc/connector/policy/monitor/store/sql/SqlPolicyMonitorStoreExtension.java +++ b/extensions/policy-monitor/store/sql/policy-monitor-store-sql/src/main/java/org/eclipse/edc/connector/policy/monitor/store/sql/SqlPolicyMonitorStoreExtension.java @@ -25,6 +25,7 @@ import org.eclipse.edc.spi.types.TypeManager; import org.eclipse.edc.sql.QueryExecutor; import org.eclipse.edc.sql.bootstrapper.SqlSchemaBootstrapper; +import org.eclipse.edc.sql.configuration.DataSourceName; import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; import org.eclipse.edc.transaction.spi.TransactionContext; @@ -34,9 +35,13 @@ public class SqlPolicyMonitorStoreExtension implements ServiceExtension { + @Deprecated(since = "0.8.1") @Setting(value = "Name of the datasource to use for accessing policy monitor store", defaultValue = DEFAULT_DATASOURCE) private static final String DATASOURCE_SETTING_NAME = "edc.datasource.policy-monitor.name"; + @Setting(value = "The datasource to be used", defaultValue = DataSourceRegistry.DEFAULT_DATASOURCE) + public static final String DATASOURCE_NAME = "edc.sql.store.policy-monitor.datasource"; + @Inject private DataSourceRegistry dataSourceRegistry; @@ -60,7 +65,8 @@ public class SqlPolicyMonitorStoreExtension implements ServiceExtension { @Provider public PolicyMonitorStore policyMonitorStore(ServiceExtensionContext context) { - var dataSourceName = context.getConfig().getString(DATASOURCE_SETTING_NAME, DEFAULT_DATASOURCE); + var dataSourceName = DataSourceName.getDataSourceName(DATASOURCE_NAME, DATASOURCE_SETTING_NAME, context.getConfig(), context.getMonitor()); + sqlSchemaBootstrapper.addStatementFromResource(dataSourceName, "policy-monitor-schema.sql"); return new SqlPolicyMonitorStore(dataSourceRegistry, dataSourceName, transactionContext, diff --git a/system-tests/e2e-transfer-test/runner/src/test/java/org/eclipse/edc/sql/configuration/DataSourceNameTest.java b/system-tests/e2e-transfer-test/runner/src/test/java/org/eclipse/edc/sql/configuration/DataSourceNameTest.java new file mode 100644 index 00000000000..76d4283c186 --- /dev/null +++ b/system-tests/e2e-transfer-test/runner/src/test/java/org/eclipse/edc/sql/configuration/DataSourceNameTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.sql.configuration; + +import org.eclipse.edc.spi.monitor.Monitor; +import org.eclipse.edc.spi.system.configuration.ConfigFactory; +import org.eclipse.edc.transaction.datasource.spi.DataSourceRegistry; +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; + +class DataSourceNameTest { + + private final Monitor monitor = mock(); + + @Test + void shouldReturnDefaultDatasource_whenNoConfiguration() { + var config = ConfigFactory.empty(); + + var datasourceName = DataSourceName.getDataSourceName("key", "deprecatedKey", config, monitor); + + assertThat(datasourceName).isEqualTo(DataSourceRegistry.DEFAULT_DATASOURCE); + verifyNoInteractions(monitor); + } + + @Test + void shouldReturnDatasource_whenIsInConfiguration() { + var config = ConfigFactory.fromMap(Map.of("key", "value")); + + var datasourceName = DataSourceName.getDataSourceName("key", "deprecatedKey", config, monitor); + + assertThat(datasourceName).isEqualTo("value"); + verifyNoInteractions(monitor); + } + + @Test + void shouldLogWarning_whenDeprecatedKeyIsUsed() { + var config = ConfigFactory.fromMap(Map.of("deprecatedKey", "value")); + + var datasourceName = DataSourceName.getDataSourceName("key", "deprecatedKey", config, monitor); + + assertThat(datasourceName).isEqualTo("value"); + verify(monitor).warning(anyString()); + } +}