This is an automated email from the ASF dual-hosted git repository.

dimas 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 d95bd6b1e Extract root Principal setup code into a common util class 
(#3446)
d95bd6b1e is described below

commit d95bd6b1e3d77b5db7769e866c0474f08accad2c
Author: Dmitri Bourlatchkov <[email protected]>
AuthorDate: Fri Jan 23 10:12:45 2026 -0500

    Extract root Principal setup code into a common util class (#3446)
    
    * Add `AuthBootstrapUtil` to contain the canonical setup code
      for the "root" Polaris Principal and default roles.
    
    * This class is not meant for reuse outside the Polaris codebase.
---
 .../maintenance/TestCatalogMaintenance.java        |   4 +-
 .../nosql/metastore/NoSqlMetaStoreManager.java     |  83 ---------------
 .../metastore/NoSqlMetaStoreManagerFactory.java    |  79 +-------------
 .../jdbc/JdbcMetaStoreManagerFactory.java          |  40 ++-----
 .../polaris/core/auth/AuthBootstrapUtil.java       | 115 +++++++++++++++++++++
 .../AtomicOperationMetaStoreManager.java           |  64 ------------
 .../core/persistence/PolarisMetaStoreManager.java  |   6 +-
 .../TransactionalMetaStoreManagerImpl.java         |  73 -------------
 8 files changed, 135 insertions(+), 329 deletions(-)

diff --git 
a/persistence/nosql/persistence/metastore-maintenance/src/test/java/org/apache/polaris/persistence/nosql/metastore/maintenance/TestCatalogMaintenance.java
 
b/persistence/nosql/persistence/metastore-maintenance/src/test/java/org/apache/polaris/persistence/nosql/metastore/maintenance/TestCatalogMaintenance.java
index d5f311054..84ffa51a8 100644
--- 
a/persistence/nosql/persistence/metastore-maintenance/src/test/java/org/apache/polaris/persistence/nosql/metastore/maintenance/TestCatalogMaintenance.java
+++ 
b/persistence/nosql/persistence/metastore-maintenance/src/test/java/org/apache/polaris/persistence/nosql/metastore/maintenance/TestCatalogMaintenance.java
@@ -248,12 +248,12 @@ public class TestCatalogMaintenance {
             // 8 stale objects:
             // - 1 namespace (catalog state)
             // - 1 table (catalog state)
-            // - 1 grants (realm setup) - including 1 ACLs
+            // - 2 grants (realm setup) - including 2 ACLs
             // - 1 principal
             // - 1 principal role
             // - 1 catalog role
             // - 1 catalog
-            Optional.of(8L));
+            Optional.of(10L));
 
     checkEntities("real state after grace", entities);
   }
diff --git 
a/persistence/nosql/persistence/metastore/src/main/java/org/apache/polaris/persistence/nosql/metastore/NoSqlMetaStoreManager.java
 
b/persistence/nosql/persistence/metastore/src/main/java/org/apache/polaris/persistence/nosql/metastore/NoSqlMetaStoreManager.java
index 9338f2a5a..e35e34dde 100644
--- 
a/persistence/nosql/persistence/metastore/src/main/java/org/apache/polaris/persistence/nosql/metastore/NoSqlMetaStoreManager.java
+++ 
b/persistence/nosql/persistence/metastore/src/main/java/org/apache/polaris/persistence/nosql/metastore/NoSqlMetaStoreManager.java
@@ -92,89 +92,6 @@ record NoSqlMetaStoreManager(
 
   // Realms
 
-  @Nonnull
-  @Override
-  public BaseResult bootstrapPolarisService(@Nonnull PolarisCallContext 
callCtx) {
-    bootstrapPolarisServiceInternal(ms(callCtx));
-    return new BaseResult(BaseResult.ReturnStatus.SUCCESS);
-  }
-
-  Optional<CreatePrincipalResult> 
bootstrapPolarisServiceInternal(NoSqlMetaStore ms) {
-    // This function is idempotent, already existing entities will not be 
created again.
-
-    // Create the root-container, if not already present
-    var rootContainer =
-        ms.lookupRoot()
-            .orElseGet(
-                () -> {
-                  var newRoot =
-                      new PolarisBaseEntity(
-                          PolarisEntityConstants.getNullId(),
-                          PolarisEntityConstants.getRootEntityId(),
-                          PolarisEntityType.ROOT,
-                          PolarisEntitySubType.NULL_SUBTYPE,
-                          PolarisEntityConstants.getRootEntityId(),
-                          PolarisEntityConstants.getRootContainerName());
-                  ms.createEntity(newRoot);
-                  return newRoot;
-                });
-
-    // Create the root-principal, if not already present
-    var rootPrincipal =
-        ms.lookupEntityByName(
-            0L,
-            0L,
-            PolarisEntityType.PRINCIPAL.getCode(),
-            PolarisEntityConstants.getRootPrincipalName());
-    var createPrincipalResult = Optional.<CreatePrincipalResult>empty();
-    if (rootPrincipal == null) {
-      var rootPrincipalId = ms.generateNewId();
-      rootPrincipal =
-          new PolarisBaseEntity(
-              PolarisEntityConstants.getNullId(),
-              rootPrincipalId,
-              PolarisEntityType.PRINCIPAL,
-              PolarisEntitySubType.NULL_SUBTYPE,
-              PolarisEntityConstants.getRootEntityId(),
-              PolarisEntityConstants.getRootPrincipalName());
-
-      createPrincipalResult = Optional.of(ms.createPrincipal(rootPrincipal, 
rootCredentialsSet));
-    }
-
-    // Create the service-admin principal-role, if not already present
-    var serviceAdminPrincipalRole =
-        ms.lookupEntityByName(
-            0L,
-            0L,
-            PolarisEntityType.PRINCIPAL_ROLE.getCode(),
-            PolarisEntityConstants.getNameOfPrincipalServiceAdminRole());
-    if (serviceAdminPrincipalRole == null) {
-      // now create the account admin principal role
-      var serviceAdminPrincipalRoleId = ms.generateNewId();
-      serviceAdminPrincipalRole =
-          new PolarisBaseEntity(
-              PolarisEntityConstants.getNullId(),
-              serviceAdminPrincipalRoleId,
-              PolarisEntityType.PRINCIPAL_ROLE,
-              PolarisEntitySubType.NULL_SUBTYPE,
-              PolarisEntityConstants.getRootEntityId(),
-              PolarisEntityConstants.getNameOfPrincipalServiceAdminRole());
-      ms.createEntity(serviceAdminPrincipalRole);
-    }
-
-    // Persisting already existing grants is an idempotent operation
-    ms.persistGrantsOrRevokes(
-        true,
-        // we also need to grant usage on the account-admin principal to the 
principal
-        new SecurableGranteePrivilegeTuple(
-            serviceAdminPrincipalRole, rootPrincipal, 
PolarisPrivilege.PRINCIPAL_ROLE_USAGE),
-        // grant SERVICE_MANAGE_ACCESS on the rootContainer to the 
serviceAdminPrincipalRole
-        new SecurableGranteePrivilegeTuple(
-            rootContainer, serviceAdminPrincipalRole, 
PolarisPrivilege.SERVICE_MANAGE_ACCESS));
-
-    return createPrincipalResult;
-  }
-
   @Nonnull
   @Override
   public BaseResult purge(@Nonnull PolarisCallContext callCtx) {
diff --git 
a/persistence/nosql/persistence/metastore/src/main/java/org/apache/polaris/persistence/nosql/metastore/NoSqlMetaStoreManagerFactory.java
 
b/persistence/nosql/persistence/metastore/src/main/java/org/apache/polaris/persistence/nosql/metastore/NoSqlMetaStoreManagerFactory.java
index 6fffd8faa..04ed314f9 100644
--- 
a/persistence/nosql/persistence/metastore/src/main/java/org/apache/polaris/persistence/nosql/metastore/NoSqlMetaStoreManagerFactory.java
+++ 
b/persistence/nosql/persistence/metastore/src/main/java/org/apache/polaris/persistence/nosql/metastore/NoSqlMetaStoreManagerFactory.java
@@ -20,6 +20,7 @@ package org.apache.polaris.persistence.nosql.metastore;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkState;
+import static 
org.apache.polaris.core.auth.AuthBootstrapUtil.createPolarisPrincipalForRealm;
 import static 
org.apache.polaris.persistence.nosql.coretypes.refs.References.realmReferenceNames;
 import static 
org.apache.polaris.persistence.nosql.realms.api.RealmDefinition.RealmStatus.ACTIVE;
 import static 
org.apache.polaris.persistence.nosql.realms.api.RealmDefinition.RealmStatus.CREATED;
@@ -37,21 +38,16 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
+import org.apache.polaris.core.PolarisCallContext;
 import org.apache.polaris.core.PolarisDiagnostics;
 import org.apache.polaris.core.config.RealmConfig;
 import org.apache.polaris.core.context.RealmContext;
-import org.apache.polaris.core.entity.PolarisBaseEntity;
-import org.apache.polaris.core.entity.PolarisEntity;
-import org.apache.polaris.core.entity.PolarisEntityConstants;
-import org.apache.polaris.core.entity.PolarisEntityType;
-import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
 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.BaseResult;
-import org.apache.polaris.core.persistence.dao.entity.CreatePrincipalResult;
 import org.apache.polaris.core.persistence.dao.entity.PrincipalSecretsResult;
 import org.apache.polaris.core.storage.PolarisStorageIntegrationProvider;
 import org.apache.polaris.persistence.nosql.api.Persistence;
@@ -275,9 +271,8 @@ class NoSqlMetaStoreManagerFactory implements 
MetaStoreManagerFactory {
             rootCredentialsSet,
             clock);
 
-    var secretsResult =
-        bootstrapServiceAndCreatePolarisPrincipalForRealm(
-            realmId, metaStoreManager, metaStore, rootCredentialsSet);
+    PolarisCallContext ctx = new PolarisCallContext(() -> realmId, metaStore);
+    var secretsResult = createPolarisPrincipalForRealm(metaStoreManager, ctx);
 
     realmManagement.update(
         realmDesc, 
RealmDefinition.builder().from(realmDesc).status(ACTIVE).build());
@@ -286,70 +281,4 @@ class NoSqlMetaStoreManagerFactory implements 
MetaStoreManagerFactory {
 
     return secretsResult;
   }
-
-  /**
-   * This method bootstraps service for a given realm: i.e., creates all the 
required entities in
-   * the metastore and creates a root service principal. After that, we rotate 
the root principal
-   * credentials and print them to stdout
-   */
-  private PrincipalSecretsResult 
bootstrapServiceAndCreatePolarisPrincipalForRealm(
-      String realmId,
-      NoSqlMetaStoreManager metaStoreManager,
-      NoSqlMetaStore metaStore,
-      RootCredentialsSet rootCredentialsSet) {
-    var createPrincipalResult = 
metaStoreManager.bootstrapPolarisServiceInternal(metaStore);
-
-    var rootPrincipal =
-        createPrincipalResult
-            .map(result -> (PolarisBaseEntity) result.getPrincipal())
-            .orElseGet(
-                () ->
-                    metaStoreManager
-                        .readEntityByName(
-                            metaStore,
-                            null,
-                            PolarisEntityType.PRINCIPAL,
-                            PolarisEntityConstants.getRootPrincipalName())
-                        .getEntity());
-
-    var clientId =
-        PolarisEntity.of(rootPrincipal)
-            .getInternalPropertiesAsMap()
-            .get(PolarisEntityConstants.getClientIdPropertyName());
-    checkState(clientId != null, "Root principal has no client-ID");
-    var secrets = metaStore.loadPrincipalSecrets(clientId);
-
-    var principalSecrets = 
createPrincipalResult.map(CreatePrincipalResult::getPrincipalSecrets);
-    if (principalSecrets.isPresent()) {
-      LOGGER.debug(
-          "Root principal created for realm '{}', directly returning 
credentials for client-ID '{}'",
-          realmId,
-          principalSecrets.get().getPrincipalClientId());
-      return new PrincipalSecretsResult(principalSecrets.get());
-    }
-
-    var providedCredentials = rootCredentialsSet.credentials().get(realmId);
-    if (providedCredentials != null) {
-      LOGGER.debug(
-          "Root principal for realm '{}' already exists, credentials provided 
externally, returning credentials for client-ID '{}'",
-          realmId,
-          providedCredentials.clientId());
-      return new PrincipalSecretsResult(
-          new PolarisPrincipalSecrets(
-              rootPrincipal.getId(),
-              providedCredentials.clientId(),
-              providedCredentials.clientSecret(),
-              providedCredentials.clientSecret()));
-    }
-
-    // Have to rotate the secrets to retain the idempotency of this function
-    var result =
-        metaStoreManager.rotatePrincipalSecrets(
-            metaStore, secrets.getPrincipalId(), false, 
secrets.getMainSecretHash());
-    LOGGER.debug(
-        "Rotating credentials for root principal for realm '{}', client-ID is 
'{}'",
-        realmId,
-        result.getPrincipalSecrets().getPrincipalClientId());
-    return result;
-  }
 }
diff --git 
a/persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/JdbcMetaStoreManagerFactory.java
 
b/persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/JdbcMetaStoreManagerFactory.java
index 690eb5ae3..26f38fc31 100644
--- 
a/persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/JdbcMetaStoreManagerFactory.java
+++ 
b/persistence/relational-jdbc/src/main/java/org/apache/polaris/persistence/relational/jdbc/JdbcMetaStoreManagerFactory.java
@@ -18,6 +18,8 @@
  */
 package org.apache.polaris.persistence.relational.jdbc;
 
+import static 
org.apache.polaris.core.auth.AuthBootstrapUtil.createPolarisPrincipalForRealm;
+
 import io.smallrye.common.annotation.Identifier;
 import jakarta.annotation.Nullable;
 import jakarta.enterprise.context.ApplicationScoped;
@@ -176,8 +178,14 @@ public class JdbcMetaStoreManagerFactory implements 
MetaStoreManagerFactory {
         }
         initializeForRealm(
             datasourceOperations, realmContext, 
bootstrapOptions.rootCredentialsSet());
+
+        PolarisMetaStoreManager metaStoreManager =
+            metaStoreManagerMap.get(realmContext.getRealmIdentifier());
+        BasePersistence metaStore = 
sessionSupplierMap.get(realmContext.getRealmIdentifier()).get();
+        PolarisCallContext polarisContext = new 
PolarisCallContext(realmContext, metaStore);
+
         PrincipalSecretsResult secretsResult =
-            bootstrapServiceAndCreatePolarisPrincipalForRealm(realmContext);
+            createPolarisPrincipalForRealm(metaStoreManager, polarisContext);
         results.put(realm, secretsResult);
       }
     }
@@ -239,36 +247,6 @@ public class JdbcMetaStoreManagerFactory implements 
MetaStoreManagerFactory {
     return entityCacheMap.get(realmContext.getRealmIdentifier());
   }
 
-  /**
-   * This method bootstraps service for a given realm: i.e. creates all the 
needed entities in the
-   * metastore and creates a root service principal.
-   */
-  private PrincipalSecretsResult 
bootstrapServiceAndCreatePolarisPrincipalForRealm(
-      RealmContext realmContext) {
-    // While bootstrapping we need to act as a fake privileged context since 
the real
-    // CallContext may not have been resolved yet.
-    PolarisMetaStoreManager metaStoreManager =
-        metaStoreManagerMap.get(realmContext.getRealmIdentifier());
-    BasePersistence metaStore = 
sessionSupplierMap.get(realmContext.getRealmIdentifier()).get();
-    PolarisCallContext polarisContext = new PolarisCallContext(realmContext, 
metaStore);
-
-    Optional<PrincipalEntity> preliminaryRootPrincipal =
-        metaStoreManager.findRootPrincipal(polarisContext);
-    if (preliminaryRootPrincipal.isPresent()) {
-      String overrideMessage =
-          "It appears this metastore manager has already been bootstrapped. "
-              + "To continue bootstrapping, please first purge the metastore 
with the `purge` command.";
-      LOGGER.error("\n\n {} \n\n", overrideMessage);
-      throw new IllegalArgumentException(overrideMessage);
-    }
-
-    metaStoreManager.bootstrapPolarisService(polarisContext);
-
-    PrincipalEntity rootPrincipal =
-        metaStoreManager.findRootPrincipal(polarisContext).orElseThrow();
-    return metaStoreManager.loadPrincipalSecrets(polarisContext, 
rootPrincipal.getClientId());
-  }
-
   /**
    * In this method we check if Service was bootstrapped for a given realm, 
i.e. that all the
    * entities were created (root principal, root principal role, etc) If 
service was not
diff --git 
a/polaris-core/src/main/java/org/apache/polaris/core/auth/AuthBootstrapUtil.java
 
b/polaris-core/src/main/java/org/apache/polaris/core/auth/AuthBootstrapUtil.java
new file mode 100644
index 000000000..fe730fbd6
--- /dev/null
+++ 
b/polaris-core/src/main/java/org/apache/polaris/core/auth/AuthBootstrapUtil.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.polaris.core.auth;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.base.Preconditions;
+import java.util.Optional;
+import org.apache.polaris.core.PolarisCallContext;
+import org.apache.polaris.core.entity.PolarisBaseEntity;
+import org.apache.polaris.core.entity.PolarisEntityConstants;
+import org.apache.polaris.core.entity.PolarisEntitySubType;
+import org.apache.polaris.core.entity.PolarisEntityType;
+import org.apache.polaris.core.entity.PolarisPrivilege;
+import org.apache.polaris.core.entity.PrincipalEntity;
+import org.apache.polaris.core.entity.PrincipalRoleEntity;
+import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
+import org.apache.polaris.core.persistence.dao.entity.CreatePrincipalResult;
+import org.apache.polaris.core.persistence.dao.entity.GenerateEntityIdResult;
+import org.apache.polaris.core.persistence.dao.entity.PrincipalSecretsResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class for sharing root Polaris Principal setup code among all 
persistence
+ * implementations.
+ *
+ * <p>Note: this class is not meant to be reused outside of Polaris code.
+ */
+public class AuthBootstrapUtil {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(AuthBootstrapUtil.class);
+
+  private AuthBootstrapUtil() {}
+
+  public static PrincipalSecretsResult createPolarisPrincipalForRealm(
+      PolarisMetaStoreManager metaStoreManager, PolarisCallContext ctx) {
+
+    Optional<PrincipalEntity> preliminaryRootPrincipal = 
metaStoreManager.findRootPrincipal(ctx);
+    if (preliminaryRootPrincipal.isPresent()) {
+      String overrideMessage =
+          "It appears this metastore manager has already been bootstrapped. "
+              + "To continue bootstrapping, please first purge the metastore 
with the `purge` command.";
+      LOGGER.error("\n\n {} \n\n", overrideMessage);
+      throw new IllegalArgumentException(overrideMessage);
+    }
+
+    // Create a root container entity that can represent the securable for any 
top-level grants.
+    PolarisBaseEntity rootContainer =
+        new PolarisBaseEntity(
+            PolarisEntityConstants.getNullId(),
+            PolarisEntityConstants.getRootEntityId(),
+            PolarisEntityType.ROOT,
+            PolarisEntitySubType.NULL_SUBTYPE,
+            PolarisEntityConstants.getRootEntityId(),
+            PolarisEntityConstants.getRootContainerName());
+    metaStoreManager.createEntityIfNotExists(ctx, null, rootContainer);
+
+    CreatePrincipalResult principalResult =
+        metaStoreManager.createPrincipal(
+            ctx,
+            new PrincipalEntity.Builder()
+                .setId(generateId(metaStoreManager, ctx))
+                .setName(PolarisEntityConstants.getRootPrincipalName())
+                .setCreateTimestamp(System.currentTimeMillis())
+                .build());
+    checkState(principalResult.isSuccess(), "Unable to create root principal");
+    PrincipalEntity rootPrincipal = principalResult.getPrincipal();
+
+    // now create the account admin principal role
+    PrincipalRoleEntity serviceAdminPrincipalRole =
+        new PrincipalRoleEntity.Builder()
+            .setId(generateId(metaStoreManager, ctx))
+            
.setName(PolarisEntityConstants.getNameOfPrincipalServiceAdminRole())
+            .setCreateTimestamp(System.currentTimeMillis())
+            .build();
+    metaStoreManager.createEntityIfNotExists(ctx, null, 
serviceAdminPrincipalRole);
+
+    // we also need to grant usage on the account-admin principal to the 
principal
+    metaStoreManager.grantPrivilegeOnSecurableToRole(
+        ctx, rootPrincipal, null, serviceAdminPrincipalRole, 
PolarisPrivilege.PRINCIPAL_ROLE_USAGE);
+
+    // grant SERVICE_MANAGE_ACCESS on the rootContainer to the 
serviceAdminPrincipalRole
+    metaStoreManager.grantPrivilegeOnSecurableToRole(
+        ctx,
+        serviceAdminPrincipalRole,
+        null,
+        rootContainer,
+        PolarisPrivilege.SERVICE_MANAGE_ACCESS);
+
+    return metaStoreManager.loadPrincipalSecrets(ctx, 
rootPrincipal.getClientId());
+  }
+
+  private static long generateId(PolarisMetaStoreManager metaStoreManager, 
PolarisCallContext ctx) {
+    GenerateEntityIdResult res = metaStoreManager.generateNewEntityId(ctx);
+    Preconditions.checkState(res.isSuccess(), "Unable to generate id for 
polaris entity");
+    return res.getId();
+  }
+}
diff --git 
a/polaris-core/src/main/java/org/apache/polaris/core/persistence/AtomicOperationMetaStoreManager.java
 
b/polaris-core/src/main/java/org/apache/polaris/core/persistence/AtomicOperationMetaStoreManager.java
index 60085193c..84341f793 100644
--- 
a/polaris-core/src/main/java/org/apache/polaris/core/persistence/AtomicOperationMetaStoreManager.java
+++ 
b/polaris-core/src/main/java/org/apache/polaris/core/persistence/AtomicOperationMetaStoreManager.java
@@ -54,7 +54,6 @@ import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
 import org.apache.polaris.core.entity.PolarisPrivilege;
 import org.apache.polaris.core.entity.PolarisTaskConstants;
 import org.apache.polaris.core.entity.PrincipalEntity;
-import org.apache.polaris.core.entity.PrincipalRoleEntity;
 import org.apache.polaris.core.persistence.dao.entity.BaseResult;
 import org.apache.polaris.core.persistence.dao.entity.ChangeTrackingResult;
 import org.apache.polaris.core.persistence.dao.entity.CreateCatalogResult;
@@ -560,69 +559,6 @@ public class AtomicOperationMetaStoreManager extends 
BaseMetaStoreManager {
     return new CreateCatalogResult(catalog, adminRole);
   }
 
-  /** {@inheritDoc} */
-  @Override
-  public @Nonnull BaseResult bootstrapPolarisService(@Nonnull 
PolarisCallContext callCtx) {
-    // get meta store we should be using
-    BasePersistence ms = callCtx.getMetaStore();
-
-    // Create a root container entity that can represent the securable for any 
top-level grants.
-    PolarisBaseEntity rootContainer =
-        new PolarisBaseEntity(
-            PolarisEntityConstants.getNullId(),
-            PolarisEntityConstants.getRootEntityId(),
-            PolarisEntityType.ROOT,
-            PolarisEntitySubType.NULL_SUBTYPE,
-            PolarisEntityConstants.getRootEntityId(),
-            PolarisEntityConstants.getRootContainerName());
-    this.persistNewEntity(callCtx, ms, rootContainer);
-
-    // Now bootstrap the service by creating the root principal and the 
service_admin principal
-    // role. The principal role will be granted to that root principal and the 
root catalog admin
-    // of the root catalog will be granted to that principal role.
-    long rootPrincipalId = ms.generateNewId(callCtx);
-    PrincipalEntity rootPrincipal =
-        new PrincipalEntity.Builder()
-            .setId(rootPrincipalId)
-            .setName(PolarisEntityConstants.getRootPrincipalName())
-            .setCreateTimestamp(System.currentTimeMillis())
-            .build();
-    this.createPrincipal(callCtx, rootPrincipal);
-
-    // now create the account admin principal role
-    long serviceAdminPrincipalRoleId = ms.generateNewId(callCtx);
-    PrincipalRoleEntity serviceAdminPrincipalRole =
-        new PrincipalRoleEntity.Builder()
-            .setId(serviceAdminPrincipalRoleId)
-            
.setName(PolarisEntityConstants.getNameOfPrincipalServiceAdminRole())
-            .setCreateTimestamp(System.currentTimeMillis())
-            .build();
-    this.persistNewEntity(callCtx, ms, serviceAdminPrincipalRole);
-
-    // we also need to grant usage on the account-admin principal to the 
principal
-    this.persistNewGrantRecord(
-        callCtx,
-        ms,
-        serviceAdminPrincipalRole,
-        rootPrincipal,
-        PolarisPrivilege.PRINCIPAL_ROLE_USAGE);
-
-    // grant SERVICE_MANAGE_ACCESS on the rootContainer to the 
serviceAdminPrincipalRole
-    this.persistNewGrantRecord(
-        callCtx,
-        ms,
-        rootContainer,
-        serviceAdminPrincipalRole,
-        PolarisPrivilege.SERVICE_MANAGE_ACCESS);
-
-    // TODO: Make idempotent by being able to continue where it left off for 
the context's realm.
-    // In the meantime, if a realm was only partially initialized before the 
server crashed,
-    // it's fine to purge the realm and retry the bootstrap.
-
-    // all good
-    return new BaseResult(BaseResult.ReturnStatus.SUCCESS);
-  }
-
   @Override
   public @Nonnull BaseResult purge(@Nonnull PolarisCallContext callCtx) {
     // get meta store we should be using
diff --git 
a/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolarisMetaStoreManager.java
 
b/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolarisMetaStoreManager.java
index efa73a60b..423295d3a 100644
--- 
a/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolarisMetaStoreManager.java
+++ 
b/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolarisMetaStoreManager.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import org.apache.polaris.core.PolarisCallContext;
+import org.apache.polaris.core.auth.AuthBootstrapUtil;
 import org.apache.polaris.core.auth.PolarisGrantManager;
 import org.apache.polaris.core.auth.PolarisSecretsManager;
 import org.apache.polaris.core.entity.LocationBasedEntity;
@@ -73,7 +74,10 @@ public interface PolarisMetaStoreManager
    * @return the result of the bootstrap attempt
    */
   @Nonnull
-  BaseResult bootstrapPolarisService(@Nonnull PolarisCallContext callCtx);
+  default BaseResult bootstrapPolarisService(@Nonnull PolarisCallContext 
callCtx) {
+    AuthBootstrapUtil.createPolarisPrincipalForRealm(this, callCtx);
+    return new BaseResult(BaseResult.ReturnStatus.SUCCESS);
+  }
 
   /**
    * Purge all metadata associated with the Polaris service, resetting the 
metastore to the state it
diff --git 
a/polaris-core/src/main/java/org/apache/polaris/core/persistence/transactional/TransactionalMetaStoreManagerImpl.java
 
b/polaris-core/src/main/java/org/apache/polaris/core/persistence/transactional/TransactionalMetaStoreManagerImpl.java
index 458963541..eab383593 100644
--- 
a/polaris-core/src/main/java/org/apache/polaris/core/persistence/transactional/TransactionalMetaStoreManagerImpl.java
+++ 
b/polaris-core/src/main/java/org/apache/polaris/core/persistence/transactional/TransactionalMetaStoreManagerImpl.java
@@ -53,7 +53,6 @@ import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
 import org.apache.polaris.core.entity.PolarisPrivilege;
 import org.apache.polaris.core.entity.PolarisTaskConstants;
 import org.apache.polaris.core.entity.PrincipalEntity;
-import org.apache.polaris.core.entity.PrincipalRoleEntity;
 import org.apache.polaris.core.persistence.BaseMetaStoreManager;
 import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
 import org.apache.polaris.core.persistence.PolarisObjectMapperUtil;
@@ -534,78 +533,6 @@ public class TransactionalMetaStoreManagerImpl extends 
BaseMetaStoreManager {
     return new CreateCatalogResult(catalog, adminRole);
   }
 
-  /**
-   * Bootstrap Polaris catalog service
-   *
-   * @param callCtx call context
-   * @param ms meta store in read/write mode
-   */
-  private void bootstrapPolarisService(
-      @Nonnull PolarisCallContext callCtx, @Nonnull TransactionalPersistence 
ms) {
-
-    // Create a root container entity that can represent the securable for any 
top-level grants.
-    PolarisBaseEntity rootContainer =
-        new PolarisBaseEntity(
-            PolarisEntityConstants.getNullId(),
-            PolarisEntityConstants.getRootEntityId(),
-            PolarisEntityType.ROOT,
-            PolarisEntitySubType.NULL_SUBTYPE,
-            PolarisEntityConstants.getRootEntityId(),
-            PolarisEntityConstants.getRootContainerName());
-    this.persistNewEntity(callCtx, ms, rootContainer);
-
-    // Now bootstrap the service by creating the root principal and the 
service_admin principal
-    // role. The principal role will be granted to that root principal and the 
root catalog admin
-    // of the root catalog will be granted to that principal role.
-    long rootPrincipalId = ms.generateNewIdInCurrentTxn(callCtx);
-    PrincipalEntity rootPrincipal =
-        new PrincipalEntity.Builder()
-            .setId(rootPrincipalId)
-            .setName(PolarisEntityConstants.getRootPrincipalName())
-            .setCreateTimestamp(System.currentTimeMillis())
-            .build();
-    this.createPrincipal(callCtx, ms, rootPrincipal);
-
-    // now create the account admin principal role
-    long serviceAdminPrincipalRoleId = ms.generateNewIdInCurrentTxn(callCtx);
-    PrincipalRoleEntity serviceAdminPrincipalRole =
-        new PrincipalRoleEntity.Builder()
-            .setId(serviceAdminPrincipalRoleId)
-            
.setName(PolarisEntityConstants.getNameOfPrincipalServiceAdminRole())
-            .setCreateTimestamp(System.currentTimeMillis())
-            .build();
-    this.persistNewEntity(callCtx, ms, serviceAdminPrincipalRole);
-
-    // we also need to grant usage on the account-admin principal to the 
principal
-    this.persistNewGrantRecord(
-        callCtx,
-        ms,
-        serviceAdminPrincipalRole,
-        rootPrincipal,
-        PolarisPrivilege.PRINCIPAL_ROLE_USAGE);
-
-    // grant SERVICE_MANAGE_ACCESS on the rootContainer to the 
serviceAdminPrincipalRole
-    this.persistNewGrantRecord(
-        callCtx,
-        ms,
-        rootContainer,
-        serviceAdminPrincipalRole,
-        PolarisPrivilege.SERVICE_MANAGE_ACCESS);
-  }
-
-  /** {@inheritDoc} */
-  @Override
-  public @Nonnull BaseResult bootstrapPolarisService(@Nonnull 
PolarisCallContext callCtx) {
-    // get meta store we should be using
-    TransactionalPersistence ms = ((TransactionalPersistence) 
callCtx.getMetaStore());
-
-    // run operation in a read/write transaction
-    ms.runActionInTransaction(callCtx, () -> 
this.bootstrapPolarisService(callCtx, ms));
-
-    // all good
-    return new BaseResult(BaseResult.ReturnStatus.SUCCESS);
-  }
-
   @Override
   public @Nonnull BaseResult purge(@Nonnull PolarisCallContext callCtx) {
     // get meta store we should be using

Reply via email to