You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polaris.apache.org by ad...@apache.org on 2026/04/30 20:09:09 UTC
(polaris) branch main updated: Source RootCredentialsSet from Quarkus config (#4319)
This is an automated email from the ASF dual-hosted git repository.
adutra pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push:
new 67c9964b34 Source RootCredentialsSet from Quarkus config (#4319)
67c9964b34 is described below
commit 67c9964b34f10e7ed1a06cce5e9ff90d3a46b7da
Author: Alexandre Dutra <ad...@apache.org>
AuthorDate: Thu Apr 30 22:09:04 2026 +0200
Source RootCredentialsSet from Quarkus config (#4319)
This change makes it possible to source root credentials for bootstrapping from any valid Quarkus/SmallRye configuration source, and not only environment variables or system properties.
While storing root credentials in `application.properties` might not be very convenient, if for nothing else this change makes tests easier to write, cf. `RealmContextFilterTest`.
---
.../polaris/service/config/ServiceProducers.java | 36 +++++++++---------
...moryAtomicOperationMetaStoreManagerFactory.java | 8 ++--
.../InMemoryPolarisMetaStoreManagerFactory.java | 16 ++++----
.../service/context/RealmContextFilterTest.java | 43 ++--------------------
.../org/apache/polaris/service/TestServices.java | 3 +-
5 files changed, 36 insertions(+), 70 deletions(-)
diff --git a/runtime/service/src/main/java/org/apache/polaris/service/config/ServiceProducers.java b/runtime/service/src/main/java/org/apache/polaris/service/config/ServiceProducers.java
index 3e636a4822..a99736801c 100644
--- a/runtime/service/src/main/java/org/apache/polaris/service/config/ServiceProducers.java
+++ b/runtime/service/src/main/java/org/apache/polaris/service/config/ServiceProducers.java
@@ -31,6 +31,7 @@ import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.Produces;
import jakarta.inject.Singleton;
import java.time.Clock;
+import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.polaris.core.PolarisCallContext;
import org.apache.polaris.core.PolarisDefaultDiagServiceImpl;
@@ -86,6 +87,7 @@ import org.apache.polaris.service.storage.aws.S3AccessConfig;
import org.apache.polaris.service.storage.aws.StsClientsPool;
import org.apache.polaris.service.task.TaskHandlerConfiguration;
import org.apache.polaris.service.tracing.RequestIdFilter;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.context.ManagedExecutor;
import org.eclipse.microprofile.context.ThreadContext;
import org.jboss.resteasy.reactive.server.core.CurrentRequestManager;
@@ -119,6 +121,13 @@ public class ServiceProducers {
return new PolarisDefaultDiagServiceImpl();
}
+ @Produces
+ @ApplicationScoped
+ public RootCredentialsSet rootCredentialsSet(
+ @ConfigProperty(name = RootCredentialsSet.SYSTEM_PROPERTY) Optional<String> credentials) {
+ return credentials.map(RootCredentialsSet::fromString).orElse(RootCredentialsSet.EMPTY);
+ }
+
// Polaris core beans - request scope
@Produces
@@ -272,16 +281,15 @@ public class ServiceProducers {
@Observes Startup event,
Bootstrapper bootstrapper,
PersistenceConfiguration config,
- RealmContextConfiguration realmContextConfiguration) {
- var rootCredentialsSet = RootCredentialsSet.fromEnvironment();
+ RealmContextConfiguration realmContextConfiguration,
+ RootCredentialsSet rootCredentialsSet) {
var rootCredentials = rootCredentialsSet.credentials();
if (config.isAutoBootstrap()) {
var realmIds = realmContextConfiguration.realms();
LOGGER.info(
- "Bootstrapping realm(s) {}, if necessary, from root credentials set provided via the environment variable {} or Java system property {} ...",
+ "Bootstrapping realm(s) {}, if necessary, from root credentials set provided via the {} configuration property ...",
realmIds.stream().map(r -> "'" + r + "'").collect(Collectors.joining(", ")),
- RootCredentialsSet.ENVIRONMENT_VARIABLE,
RootCredentialsSet.SYSTEM_PROPERTY);
var result = bootstrapper.bootstrapRealms(realmIds, rootCredentialsSet);
@@ -291,17 +299,13 @@ public class ServiceProducers {
var principalSecrets = secrets.getPrincipalSecrets();
var log =
- LOGGER
- .atInfo()
- .addArgument(realm)
- .addArgument(RootCredentialsSet.ENVIRONMENT_VARIABLE)
- .addArgument(RootCredentialsSet.SYSTEM_PROPERTY);
+ LOGGER.atInfo().addArgument(realm).addArgument(RootCredentialsSet.SYSTEM_PROPERTY);
if (rootCredentials.containsKey(realm)) {
log.log(
- "Realm '{}' automatically bootstrapped, credentials taken from root credentials set provided via the environment variable {} or Java system property {}, not printed to stdout.");
+ "Realm '{}' automatically bootstrapped, credentials taken from root credentials set provided via the {} configuration property, not printed to stdout.");
} else {
log.log(
- "Realm '{}' automatically bootstrapped, credentials were not present in root credentials set provided via the environment variable {} or Java system property {}, see separate message printed to stdout.");
+ "Realm '{}' automatically bootstrapped, credentials were not present in root credentials set provided via the {} configuration property, see separate message printed to stdout.");
String msg =
String.format(
"realm: %1s root principal credentials: %2s:%3s",
@@ -321,19 +325,17 @@ public class ServiceProducers {
if (!unusedRealmSecrets.isEmpty()) {
// This is intentionally an error to highlight the importance of the situation.
LOGGER.error(
- "The realms {} are already fully bootstrapped but the secrets are still available via the environment variable {} or Java system property {}. "
- + "Remove this security sensitive information from the environment / Java system properties!",
+ "The realms {} are already fully bootstrapped but the secrets are still available via the {} configuration property. "
+ + "Remove this security sensitive information from the application configuration!",
unusedRealmSecrets,
- RootCredentialsSet.ENVIRONMENT_VARIABLE,
RootCredentialsSet.SYSTEM_PROPERTY);
}
} else if (!rootCredentials.isEmpty()) {
// This is intentionally an error to highlight the importance of the situation.
LOGGER.error(
- "Secrets for the realms {} are available via the environment variable {} or Java system property {}. "
- + "Remove this security sensitive information from the environment / Java system properties!",
+ "Secrets for the realms {} are available via the {} configuration property. "
+ + "Remove this security sensitive information from the application configuration!",
rootCredentials.keySet(),
- RootCredentialsSet.ENVIRONMENT_VARIABLE,
RootCredentialsSet.SYSTEM_PROPERTY);
}
}
diff --git a/runtime/service/src/main/java/org/apache/polaris/service/persistence/InMemoryAtomicOperationMetaStoreManagerFactory.java b/runtime/service/src/main/java/org/apache/polaris/service/persistence/InMemoryAtomicOperationMetaStoreManagerFactory.java
index fb45bc6c00..662b735785 100644
--- a/runtime/service/src/main/java/org/apache/polaris/service/persistence/InMemoryAtomicOperationMetaStoreManagerFactory.java
+++ b/runtime/service/src/main/java/org/apache/polaris/service/persistence/InMemoryAtomicOperationMetaStoreManagerFactory.java
@@ -25,6 +25,7 @@ import java.time.Clock;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.persistence.AtomicOperationMetaStoreManager;
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
+import org.apache.polaris.core.persistence.bootstrap.RootCredentialsSet;
import org.apache.polaris.core.storage.PolarisStorageIntegrationProvider;
/**
@@ -38,15 +39,16 @@ public class InMemoryAtomicOperationMetaStoreManagerFactory
@SuppressWarnings("unused") // Required by CDI
protected InMemoryAtomicOperationMetaStoreManagerFactory() {
- this(null, null, null);
+ this(null, null, null, null);
}
@Inject
public InMemoryAtomicOperationMetaStoreManagerFactory(
Clock clock,
PolarisDiagnostics diagnostics,
- PolarisStorageIntegrationProvider storageIntegration) {
- super(clock, diagnostics, storageIntegration);
+ PolarisStorageIntegrationProvider storageIntegration,
+ RootCredentialsSet rootCredentialsSet) {
+ super(clock, diagnostics, storageIntegration, rootCredentialsSet);
}
@Override
diff --git a/runtime/service/src/main/java/org/apache/polaris/service/persistence/InMemoryPolarisMetaStoreManagerFactory.java b/runtime/service/src/main/java/org/apache/polaris/service/persistence/InMemoryPolarisMetaStoreManagerFactory.java
index 3e8b6e538b..e08fd12082 100644
--- a/runtime/service/src/main/java/org/apache/polaris/service/persistence/InMemoryPolarisMetaStoreManagerFactory.java
+++ b/runtime/service/src/main/java/org/apache/polaris/service/persistence/InMemoryPolarisMetaStoreManagerFactory.java
@@ -45,20 +45,23 @@ public class InMemoryPolarisMetaStoreManagerFactory
extends LocalPolarisMetaStoreManagerFactory<TreeMapMetaStore> {
private final PolarisStorageIntegrationProvider storageIntegration;
+ private final RootCredentialsSet rootCredentialsSet;
private final Set<String> bootstrappedRealms = new HashSet<>();
@SuppressWarnings("unused") // Required by CDI
protected InMemoryPolarisMetaStoreManagerFactory() {
- this(null, null, null);
+ this(null, null, null, null);
}
@Inject
public InMemoryPolarisMetaStoreManagerFactory(
Clock clock,
PolarisDiagnostics diagnostics,
- PolarisStorageIntegrationProvider storageIntegration) {
+ PolarisStorageIntegrationProvider storageIntegration,
+ RootCredentialsSet rootCredentialsSet) {
super(clock, diagnostics);
this.storageIntegration = storageIntegration;
+ this.rootCredentialsSet = rootCredentialsSet;
}
@Override
@@ -81,7 +84,7 @@ public class InMemoryPolarisMetaStoreManagerFactory
RealmContext realmContext) {
String realmId = realmContext.getRealmIdentifier();
if (!bootstrappedRealms.contains(realmId)) {
- bootstrapRealmsFromEnvironment(List.of(realmId));
+ bootstrapRealms(List.of(realmId), rootCredentialsSet);
}
return super.getOrCreateMetaStoreManager(realmContext);
}
@@ -90,16 +93,11 @@ public class InMemoryPolarisMetaStoreManagerFactory
public synchronized TransactionalPersistence getOrCreateSession(RealmContext realmContext) {
String realmId = realmContext.getRealmIdentifier();
if (!bootstrappedRealms.contains(realmId)) {
- bootstrapRealmsFromEnvironment(List.of(realmId));
+ bootstrapRealms(List.of(realmId), rootCredentialsSet);
}
return super.getOrCreateSession(realmContext);
}
- private void bootstrapRealmsFromEnvironment(List<String> realms) {
- RootCredentialsSet rootCredentialsSet = RootCredentialsSet.fromEnvironment();
- this.bootstrapRealms(realms, rootCredentialsSet);
- }
-
@Override
public Map<String, PrincipalSecretsResult> bootstrapRealms(
Iterable<String> realms, RootCredentialsSet rootCredentialsSet) {
diff --git a/runtime/service/src/test/java/org/apache/polaris/service/context/RealmContextFilterTest.java b/runtime/service/src/test/java/org/apache/polaris/service/context/RealmContextFilterTest.java
index 39d54a6bc3..71f34a8a02 100644
--- a/runtime/service/src/test/java/org/apache/polaris/service/context/RealmContextFilterTest.java
+++ b/runtime/service/src/test/java/org/apache/polaris/service/context/RealmContextFilterTest.java
@@ -22,7 +22,6 @@ package org.apache.polaris.service.context;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
-import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import io.quarkus.test.common.http.TestHTTPEndpoint;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.QuarkusTestProfile;
@@ -30,7 +29,6 @@ import io.quarkus.test.junit.TestProfile;
import io.restassured.http.ContentType;
import io.restassured.specification.RequestSpecification;
import jakarta.ws.rs.core.Response;
-import java.util.List;
import java.util.Map;
import org.apache.polaris.service.catalog.api.IcebergRestOAuth2Api;
import org.junit.jupiter.api.Test;
@@ -48,44 +46,9 @@ class RealmContextFilterTest {
"polaris.realm-context.header-name",
REALM_HEADER,
"polaris.realm-context.realms",
- "realm1,realm2");
- }
-
- @Override
- public List<TestResourceEntry> testResources() {
- // `org.apache.polaris.core.persistence.bootstrap.RootCredentialsSet` retrieves the
- // environmental provides values from, 1st, a system property and, if not present, from an
- // environment variable. But `RootCredentialsSet` does not query the configuration backend.
- //
- // The fact that `RootCredentialsSet` could retrieve 'polaris.bootstrap.credentials' for this
- // test via system properties was leveraging an implementation detail in Quarkus.
- // Configs do no longer become system properties in Quarkus/smallrye-config.
- //
- // The test-profile effectively ensures that this test runs "alone", so updating and restoring
- // the relevant system property for `RootCredentialsSet` is safe.
- return List.of(new TestResourceEntry(RealmContextFilterTestResource.class));
- }
- }
-
- public static class RealmContextFilterTestResource
- implements QuarkusTestResourceLifecycleManager {
- private String oldProperty;
-
- @Override
- public Map<String, String> start() {
- oldProperty = System.getProperty("polaris.bootstrap.credentials");
- System.setProperty(
- "polaris.bootstrap.credentials", "realm1,client1,secret1;realm2,client2,secret2");
- return Map.of();
- }
-
- @Override
- public void stop() {
- if (oldProperty == null) {
- System.clearProperty("polaris.bootstrap.credentials");
- } else {
- System.setProperty("polaris.bootstrap.credentials", oldProperty);
- }
+ "realm1,realm2",
+ "polaris.bootstrap.credentials",
+ "realm1,client1,secret1;realm2,client2,secret2");
}
}
diff --git a/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
index 1bd6997a21..3cac9befee 100644
--- a/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
+++ b/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
@@ -51,6 +51,7 @@ import org.apache.polaris.core.identity.provider.ServiceIdentityProvider;
import org.apache.polaris.core.persistence.BasePersistence;
import org.apache.polaris.core.persistence.MetaStoreManagerFactory;
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
+import org.apache.polaris.core.persistence.bootstrap.RootCredentialsSet;
import org.apache.polaris.core.persistence.cache.EntityCache;
import org.apache.polaris.core.persistence.dao.entity.CreatePrincipalResult;
import org.apache.polaris.core.persistence.resolver.ResolutionManifestFactory;
@@ -206,7 +207,7 @@ public record TestServices(
() -> GoogleCredentials.create(new AccessToken(GCP_ACCESS_TOKEN, new Date())));
InMemoryPolarisMetaStoreManagerFactory metaStoreManagerFactory =
new InMemoryPolarisMetaStoreManagerFactory(
- clock, diagnostics, storageIntegrationProvider);
+ clock, diagnostics, storageIntegrationProvider, RootCredentialsSet.EMPTY);
StorageCredentialCacheConfig storageCredentialCacheConfig = () -> 10_000;
StorageCredentialCache storageCredentialCache =