Skip to content

Commit 43523ce

Browse files
committed
This change enables multiple datasources in Polaris, with possibility of **runtime** activation of the desired datasource.
This is achieved by: 1) Introducing a new enabler property: `polaris.persistence.relational.jdbc.datasource`, which points to a named datasource to activate. 2) Declaring, **at build time**, one named datasource for each JDBC driver shipped with the application. 3) Introducing a new `DataSourceActivator` config interceptor that will, at runtime, change the `active` setting of the target datasource to `true`, and all others to `false` (`active` is a runtime setting, contrary to `db-kind`). This change also makes the server ship with the H2 driver by default, since that's the pre-condition for an H2 datasource to be selected at runtime. This change will further enable **as future improvements**: - Using to JDBC + H2 by default for server images, while still allowing users to switch to PostgreSQL *without having to rebuild Polaris*. - Enabling the persistence to "plug" into not one, but many datasources, e.g. a specific datasource for main persistence, and a separate datasource for metrics. This was outlined in apache#3960 – but the machinery to make that happen was missing.
1 parent bec4a7e commit 43523ce

40 files changed

Lines changed: 475 additions & 172 deletions

File tree

persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/JdbcMetaStoreManagerFactory.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222

2323
import io.smallrye.common.annotation.Identifier;
2424
import jakarta.enterprise.context.ApplicationScoped;
25-
import jakarta.enterprise.inject.Instance;
26-
import jakarta.enterprise.inject.Produces;
2725
import jakarta.inject.Inject;
2826
import java.sql.SQLException;
2927
import java.time.Clock;
@@ -32,7 +30,6 @@
3230
import java.util.Optional;
3331
import java.util.Set;
3432
import java.util.concurrent.ConcurrentHashMap;
35-
import javax.sql.DataSource;
3633
import org.apache.polaris.core.PolarisCallContext;
3734
import org.apache.polaris.core.PolarisDiagnostics;
3835
import org.apache.polaris.core.config.BehaviorChangeConfiguration;
@@ -93,13 +90,6 @@ public class JdbcMetaStoreManagerFactory implements MetaStoreManagerFactory {
9390

9491
protected JdbcMetaStoreManagerFactory() {}
9592

96-
@Produces
97-
@ApplicationScoped
98-
static DatasourceOperations produceDatasourceOperations(
99-
Instance<DataSource> dataSource, RelationalJdbcConfiguration relationalJdbcConfiguration) {
100-
return new DatasourceOperations(dataSource.get(), relationalJdbcConfiguration);
101-
}
102-
10393
protected PrincipalSecretsGenerator secretsGenerator(
10494
String realmId, @Nullable RootCredentialsSet rootCredentialsSet) {
10595
if (rootCredentialsSet != null) {

persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/RelationalJdbcConfiguration.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@
2121
import java.util.Optional;
2222

2323
public interface RelationalJdbcConfiguration {
24-
// max retries before giving up
24+
/** The maximum number of retries before giving up the operation. */
2525
Optional<Integer> maxRetries();
2626

27-
// max retry duration
27+
/** The maximum retry duration in milliseconds. */
2828
Optional<Long> maxDurationInMs();
2929

30-
// initial delay
30+
/** The initial retry delay. */
3131
Optional<Long> initialDelayInMs();
3232

3333
/**
3434
* Explicitly configured database type. If not specified, the database type will be inferred from
3535
* the JDBC connection metadata. Supported values: "postgresql", "cockroachdb", "h2"
3636
*/
3737
Optional<String> databaseType();
38+
39+
/** The datasource name to use. Required. */
40+
String dataSource();
3841
}

persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/RelationalJdbcProductionReadinessChecks.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public ProductionReadinessCheck checkRelationalJdbc(
4040
return ProductionReadinessCheck.of(
4141
ProductionReadinessCheck.Error.of(
4242
"The current persistence (jdbc:h2) is intended for tests only.",
43-
"quarkus.datasource.jdbc.url"));
43+
"polaris.persistence.relational.jdbc.datasource"));
4444
}
4545
return ProductionReadinessCheck.OK;
4646
}

persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/JdbcGrantRecordsIdempotencyTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,5 +154,10 @@ public Optional<Long> initialDelayInMs() {
154154
public Optional<String> databaseType() {
155155
return Optional.of("h2");
156156
}
157+
158+
@Override
159+
public String dataSource() {
160+
return "h2";
161+
}
157162
}
158163
}

persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/MetricsReportPersistenceTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,5 +202,10 @@ public Optional<Long> initialDelayInMs() {
202202
public Optional<String> databaseType() {
203203
return Optional.empty();
204204
}
205+
206+
@Override
207+
public String dataSource() {
208+
return "h2";
209+
}
205210
}
206211
}

persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/RelationalJdbcProductionReadinessChecksTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ void jdbcWithH2ReturnsWarning() {
7272
error -> {
7373
assertThat(error.message())
7474
.isEqualTo("The current persistence (jdbc:h2) is intended for tests only.");
75-
assertThat(error.offendingProperty()).isEqualTo("quarkus.datasource.jdbc.url");
75+
assertThat(error.offendingProperty())
76+
.isEqualTo("polaris.persistence.relational.jdbc.datasource");
7677
assertThat(error.severe()).isFalse();
7778
});
7879
}

persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/SimpleRelationalJdbcConfiguration.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,10 @@ public Optional<Long> initialDelayInMs() {
5656
public Optional<String> databaseType() {
5757
return Optional.of(databaseType);
5858
}
59+
60+
@Override
61+
public String dataSource() {
62+
// The datasource name is irrelevant for tests that do not leverage CDI
63+
return "datasource1";
64+
}
5965
}

persistence/relational-jdbc/src/test/java/org/apache/polaris/persistence/relational/jdbc/idempotency/RelationalJdbcIdempotencyStorePostgresIT.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ public Optional<Long> initialDelayInMs() {
8282
public Optional<String> databaseType() {
8383
return Optional.empty();
8484
}
85+
86+
@Override
87+
public String dataSource() {
88+
return "postgres";
89+
}
8590
};
8691
DatasourceOperations ops = new DatasourceOperations(dataSource, cfg);
8792
try (InputStream is =

runtime/admin/build.gradle.kts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ dependencies {
3333

3434
compileOnly("com.fasterxml.jackson.core:jackson-annotations")
3535

36+
implementation(enforcedPlatform(libs.quarkus.bom))
37+
38+
// JDBC persistence + backends
3639
runtimeOnly(project(":polaris-relational-jdbc"))
37-
runtimeOnly("org.postgresql:postgresql")
40+
runtimeOnly("io.quarkus:quarkus-jdbc-postgresql")
3841

42+
// NoSQL persistence + backends
3943
implementation(project(":polaris-persistence-nosql-api"))
4044
implementation(project(":polaris-persistence-nosql-maintenance-api"))
4145
runtimeOnly(project(":polaris-persistence-nosql-metastore"))
@@ -46,8 +50,6 @@ dependencies {
4650

4751
runtimeOnly("io.quarkus:quarkus-mongodb-client")
4852

49-
implementation("io.quarkus:quarkus-jdbc-postgresql")
50-
implementation(enforcedPlatform(libs.quarkus.bom))
5153
implementation("io.quarkus:quarkus-picocli")
5254
implementation("io.quarkus:quarkus-container-image-docker")
5355

runtime/admin/src/main/resources/application.properties

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@ quarkus.container-image.registry=docker.io
3131
quarkus.container-image.group=apache
3232
quarkus.container-image.name=polaris-admin-tool
3333
quarkus.container-image.additional-tags=latest
34-
quarkus.datasource.db-kind=postgresql
34+
35+
# Named datasources for relational persistence backends.
36+
# Polaris ships with many built-in datasources; by using named datasources, users can configure
37+
# at runtime which datasources to use for relational persistence backends.
38+
quarkus.datasource.postgresql.db-kind=postgresql
39+
3540
# if set to true it will try to start localstack at build and run time for the local environment
3641
# https://docs.quarkiverse.io/quarkus-amazon-services/dev/amazon-rds.html#_configuration_reference for more details
3742
quarkus.rds.devservices.enabled=false
@@ -41,12 +46,13 @@ quarkus.mongodb.devservices.enabled=false
4146
# ---- Runtime Configuration ----
4247
# Below are default values for properties that can be changed in runtime.
4348

44-
# Available types:
49+
# Polaris persistence type. Available types:
4550
# - in-memory - InMemoryPolarisMetaStoreManagerFactory
4651
# - in-memory-atomic - InMemoryAtomicOperationMetaStoreManagerFactory
47-
# - relational-jdbc - JdbcMetaStoreManagerFactory
48-
# - nosql - NoSQL persistence backend, define the backend type via 'polaris.persistence.nosql.backend'
52+
# - nosql (beta) - NoSQL persistence backend, define the backend type via 'polaris.persistence.nosql.backend'
53+
# - relational-jdbc - JDBC persistence backend, define the JDBC datasource via 'polaris.persistence.relational.jdbc.datasource' and 'quarkus.datasource.<datasource-name>.*'
4954
polaris.persistence.type=relational-jdbc
55+
5056
# Database backend for 'nosql' persistence-type
5157
# Available backends:
5258
# - InMemory - for testing purposes
@@ -55,6 +61,21 @@ polaris.persistence.type=relational-jdbc
5561
# See https://quarkus.io/guides/mongodb#configuration-reference for details about these configurations.
5662
#polaris.persistence.nosql.backend=InMemory
5763

64+
# Datasource to activate for the 'relational-jdbc' persistence type.
65+
# Built-in supported datasources:
66+
# - postgresql - activates the PostgreSQL datasource (default)
67+
# Configure the necessary PostgreSQL properties starting with 'quarkus.datasource.postgresql.' in this file (see below).
68+
# See https://quarkus.io/guides/datasource#configuration-reference for details about these configurations.
69+
# Please do NOT set quarkus.datasource.active manually, Polaris will set it automatically based on
70+
# this property.
71+
polaris.persistence.relational.jdbc.datasource=postgresql
72+
73+
# Postgres datasource configuration:
74+
quarkus.datasource.postgresql.devservices.enabled=false
75+
#quarkus.datasource.postgresql.jdbc.url=jdbc:postgresql://localhost:5432/my_database
76+
#quarkus.datasource.postgresql.username=<your username>
77+
#quarkus.datasource.postgresql.password=<your password>
78+
5879
## MongoDB version store specific configuration
5980
#quarkus.mongodb.database=polaris
6081
#quarkus.mongodb.metrics.enabled=true

0 commit comments

Comments
 (0)