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

dlmarion pushed a commit to branch 2.1
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/2.1 by this push:
     new cd27402d50 Reduce calls to ZooCache to get table information when we 
already have it (#4685)
cd27402d50 is described below

commit cd27402d50a862afc1441f6a3b51b0f9bd37f625
Author: Dave Marion <dlmar...@apache.org>
AuthorDate: Mon Jun 24 13:40:16 2024 -0400

    Reduce calls to ZooCache to get table information when we already have it 
(#4685)
    
    Related to #4684
    
    
    Co-authored-by: Keith Turner <ktur...@apache.org>
---
 .../accumulo/core/util/tables/TableZooHelper.java  | 20 +++++++
 .../server/client/ClientServiceHandler.java        |  5 +-
 .../server/security/AuditedSecurityOperation.java  |  7 ++-
 .../server/security/SecurityOperation.java         |  5 +-
 .../apache/accumulo/manager/tableOps/Utils.java    | 32 +++++++++--
 .../manager/tableOps/clone/ClonePermissions.java   |  4 +-
 .../manager/tableOps/clone/CloneZookeeper.java     |  4 +-
 .../manager/tableOps/create/PopulateZookeeper.java |  2 +-
 .../manager/tableOps/create/SetupPermissions.java  |  3 +-
 .../manager/tableOps/rename/RenameTable.java       |  2 +-
 .../tableImport/ImportPopulateZookeeper.java       |  2 +-
 .../tableImport/ImportSetupPermissions.java        |  2 +-
 .../org/apache/accumulo/test/CreateTableIT.java    | 67 ++++++++++++++++++++++
 13 files changed, 132 insertions(+), 23 deletions(-)

diff --git 
a/core/src/main/java/org/apache/accumulo/core/util/tables/TableZooHelper.java 
b/core/src/main/java/org/apache/accumulo/core/util/tables/TableZooHelper.java
index 6345f9d5dd..de53d2bf1e 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/util/tables/TableZooHelper.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/util/tables/TableZooHelper.java
@@ -31,11 +31,14 @@ import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.NamespaceNotFoundException;
 import org.apache.accumulo.core.client.TableNotFoundException;
 import org.apache.accumulo.core.clientImpl.ClientContext;
+import org.apache.accumulo.core.clientImpl.Namespace;
 import org.apache.accumulo.core.clientImpl.Namespaces;
 import org.apache.accumulo.core.data.NamespaceId;
 import org.apache.accumulo.core.data.TableId;
 import org.apache.accumulo.core.fate.zookeeper.ZooCache;
 import org.apache.accumulo.core.manager.state.tables.TableState;
+import org.apache.accumulo.core.metadata.MetadataTable;
+import org.apache.accumulo.core.metadata.RootTable;
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
@@ -59,6 +62,12 @@ public class TableZooHelper implements AutoCloseable {
    *         getCause() of NamespaceNotFoundException
    */
   public TableId getTableId(String tableName) throws TableNotFoundException {
+    if (MetadataTable.NAME.equals(tableName)) {
+      return MetadataTable.ID;
+    }
+    if (RootTable.NAME.equals(tableName)) {
+      return RootTable.ID;
+    }
     try {
       return 
_getTableIdDetectNamespaceNotFound(EXISTING_TABLE_NAME.validate(tableName));
     } catch (NamespaceNotFoundException e) {
@@ -90,6 +99,12 @@ public class TableZooHelper implements AutoCloseable {
   }
 
   public String getTableName(TableId tableId) throws TableNotFoundException {
+    if (MetadataTable.ID.equals(tableId)) {
+      return MetadataTable.NAME;
+    }
+    if (RootTable.ID.equals(tableId)) {
+      return RootTable.NAME;
+    }
     String tableName = getTableMap().getIdtoNameMap().get(tableId);
     if (tableName == null) {
       throw new TableNotFoundException(tableId.canonical(), null, null);
@@ -185,6 +200,11 @@ public class TableZooHelper implements AutoCloseable {
   public NamespaceId getNamespaceId(TableId tableId) throws 
TableNotFoundException {
     checkArgument(context != null, "instance is null");
     checkArgument(tableId != null, "tableId is null");
+
+    if (MetadataTable.ID.equals(tableId) || RootTable.ID.equals(tableId)) {
+      return Namespace.ACCUMULO.id();
+    }
+
     ZooCache zc = context.getZooCache();
     byte[] n = zc.get(context.getZooKeeperRoot() + Constants.ZTABLES + "/" + 
tableId
         + Constants.ZTABLE_NAMESPACE);
diff --git 
a/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java
 
b/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java
index 76f0692eb8..466bc53257 100644
--- 
a/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java
+++ 
b/server/base/src/main/java/org/apache/accumulo/server/client/ClientServiceHandler.java
@@ -216,12 +216,11 @@ public class ClientServiceHandler implements 
ClientService.Iface {
     NamespaceId namespaceId;
     try {
       namespaceId = context.getNamespaceId(tableId);
+      security.grantTablePermission(credentials, user, tableId, tableName,
+          TablePermission.getPermissionById(permission), namespaceId);
     } catch (TableNotFoundException e) {
       throw new TException(e);
     }
-
-    security.grantTablePermission(credentials, user, tableId,
-        TablePermission.getPermissionById(permission), namespaceId);
   }
 
   @Override
diff --git 
a/server/base/src/main/java/org/apache/accumulo/server/security/AuditedSecurityOperation.java
 
b/server/base/src/main/java/org/apache/accumulo/server/security/AuditedSecurityOperation.java
index 3718a91b62..e4f61ed9ce 100644
--- 
a/server/base/src/main/java/org/apache/accumulo/server/security/AuditedSecurityOperation.java
+++ 
b/server/base/src/main/java/org/apache/accumulo/server/security/AuditedSecurityOperation.java
@@ -622,10 +622,10 @@ public class AuditedSecurityOperation extends 
SecurityOperation {
 
   @Override
   public void grantTablePermission(TCredentials credentials, String user, 
TableId tableId,
-      TablePermission permission, NamespaceId namespaceId) throws 
ThriftSecurityException {
-    String tableName = getTableName(tableId);
+      String tableName, TablePermission permission, NamespaceId namespaceId)
+      throws ThriftSecurityException, TableNotFoundException {
     try {
-      super.grantTablePermission(credentials, user, tableId, permission, 
namespaceId);
+      super.grantTablePermission(credentials, user, tableId, tableName, 
permission, namespaceId);
       audit(credentials, GRANT_TABLE_PERMISSION_AUDIT_TEMPLATE, permission, 
tableName, user);
     } catch (ThriftSecurityException ex) {
       audit(credentials, ex, GRANT_TABLE_PERMISSION_AUDIT_TEMPLATE, 
permission, tableName, user);
@@ -750,4 +750,5 @@ public class AuditedSecurityOperation extends 
SecurityOperation {
       throw e;
     }
   }
+
 }
diff --git 
a/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
 
b/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
index 36277652fd..dd59cebd93 100644
--- 
a/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
+++ 
b/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
@@ -743,8 +743,9 @@ public class SecurityOperation {
     }
   }
 
-  public void grantTablePermission(TCredentials c, String user, TableId 
tableId,
-      TablePermission permission, NamespaceId namespaceId) throws 
ThriftSecurityException {
+  public void grantTablePermission(TCredentials c, String user, TableId 
tableId, String tableName,
+      TablePermission permission, NamespaceId namespaceId)
+      throws ThriftSecurityException, TableNotFoundException {
     if (!canGrantTable(c, user, tableId, namespaceId)) {
       throw new ThriftSecurityException(c.getPrincipal(), 
SecurityErrorCode.PERMISSION_DENIED);
     }
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java
index def74371c2..4942b8efec 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java
@@ -49,22 +49,42 @@ import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.Text;
 import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.NoNodeException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Preconditions;
+
 public class Utils {
   private static final byte[] ZERO_BYTE = {'0'};
   private static final Logger log = LoggerFactory.getLogger(Utils.class);
 
-  public static void checkTableDoesNotExist(ServerContext context, String 
tableName,
+  public static void checkTableNameDoesNotExist(ServerContext context, String 
tableName,
       TableId tableId, TableOperation operation) throws 
AcceptableThriftTableOperationException {
 
-    TableId id = context.getTableNameToIdMap().get(tableName);
-
-    if (id != null && !id.equals(tableId)) {
-      throw new AcceptableThriftTableOperationException(null, tableName, 
operation,
-          TableOperationExceptionType.EXISTS, null);
+    try {
+      for (String tid : context.getZooReader()
+          .getChildren(context.getZooKeeperRoot() + Constants.ZTABLES)) {
+        String zTablePath = context.getZooKeeperRoot() + Constants.ZTABLES + 
"/" + tid;
+        try {
+          byte[] tname = context.getZooReader().getData(zTablePath + 
Constants.ZTABLE_NAME);
+          Preconditions.checkState(tname != null, "Malformed table entry in 
ZooKeeper at %s",
+              zTablePath);
+          if (tableName.equals(new String(tname, UTF_8))) {
+            throw new AcceptableThriftTableOperationException(tid, tableName, 
operation,
+                TableOperationExceptionType.EXISTS, null);
+          }
+        } catch (NoNodeException nne) {
+          log.trace("skipping tableId {}, either being created or has been 
deleted.", tid, nne);
+          continue;
+        }
+      }
+    } catch (KeeperException | InterruptedException e) {
+      log.error("Error checking to see if tableId {} exists in ZooKeeper", 
tableId, e);
+      throw new AcceptableThriftTableOperationException(null, tableName, 
TableOperation.CREATE,
+          TableOperationExceptionType.OTHER, e.getMessage());
     }
+
   }
 
   public static <T extends AbstractId<T>> T getNextId(String name, 
ServerContext context,
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/clone/ClonePermissions.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/clone/ClonePermissions.java
index 7ac8d6fd0b..76389668d0 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/clone/ClonePermissions.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/clone/ClonePermissions.java
@@ -50,8 +50,8 @@ class ClonePermissions extends ManagerRepo {
     for (TablePermission permission : TablePermission.values()) {
       try {
         environment.getContext().getSecurityOperation().grantTablePermission(
-            environment.getContext().rpcCreds(), cloneInfo.user, 
cloneInfo.tableId, permission,
-            cloneInfo.namespaceId);
+            environment.getContext().rpcCreds(), cloneInfo.user, 
cloneInfo.tableId,
+            cloneInfo.tableName, permission, cloneInfo.namespaceId);
       } catch (ThriftSecurityException e) {
         LoggerFactory.getLogger(ClonePermissions.class).error("{}", 
e.getMessage(), e);
         throw e;
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/clone/CloneZookeeper.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/clone/CloneZookeeper.java
index cfc10d015c..917b8f6995 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/clone/CloneZookeeper.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/clone/CloneZookeeper.java
@@ -59,8 +59,8 @@ class CloneZookeeper extends ManagerRepo {
     try {
       // write tableName & tableId to zookeeper
 
-      Utils.checkTableDoesNotExist(environment.getContext(), 
cloneInfo.tableName, cloneInfo.tableId,
-          TableOperation.CLONE);
+      Utils.checkTableNameDoesNotExist(environment.getContext(), 
cloneInfo.tableName,
+          cloneInfo.tableId, TableOperation.CLONE);
 
       environment.getTableManager().cloneTable(cloneInfo.srcTableId, 
cloneInfo.tableId,
           cloneInfo.tableName, cloneInfo.namespaceId, 
cloneInfo.propertiesToSet,
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/PopulateZookeeper.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/PopulateZookeeper.java
index 40ad2d276d..31a2210727 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/PopulateZookeeper.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/PopulateZookeeper.java
@@ -52,7 +52,7 @@ class PopulateZookeeper extends ManagerRepo {
     Utils.getTableNameLock().lock();
     try {
       // write tableName & tableId to zookeeper
-      Utils.checkTableDoesNotExist(manager.getContext(), 
tableInfo.getTableName(),
+      Utils.checkTableNameDoesNotExist(manager.getContext(), 
tableInfo.getTableName(),
           tableInfo.getTableId(), TableOperation.CREATE);
 
       manager.getTableManager().addTable(tableInfo.getTableId(), 
tableInfo.getNamespaceId(),
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/SetupPermissions.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/SetupPermissions.java
index 5b840c16ed..6fa7496e4b 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/SetupPermissions.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/SetupPermissions.java
@@ -45,7 +45,8 @@ class SetupPermissions extends ManagerRepo {
       for (TablePermission permission : TablePermission.values()) {
         try {
           security.grantTablePermission(env.getContext().rpcCreds(), 
tableInfo.getUser(),
-              tableInfo.getTableId(), permission, tableInfo.getNamespaceId());
+              tableInfo.getTableId(), tableInfo.getTableName(), permission,
+              tableInfo.getNamespaceId());
         } catch (ThriftSecurityException e) {
           LoggerFactory.getLogger(SetupPermissions.class).error("{}", 
e.getMessage(), e);
           throw e;
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/rename/RenameTable.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/rename/RenameTable.java
index a91b0ca8a8..5b078e2f2c 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/rename/RenameTable.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/rename/RenameTable.java
@@ -76,7 +76,7 @@ public class RenameTable extends ManagerRepo {
 
     Utils.getTableNameLock().lock();
     try {
-      Utils.checkTableDoesNotExist(manager.getContext(), newTableName, tableId,
+      Utils.checkTableNameDoesNotExist(manager.getContext(), newTableName, 
tableId,
           TableOperation.RENAME);
 
       final String newName = qualifiedNewTableName.getSecond();
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/tableImport/ImportPopulateZookeeper.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/tableImport/ImportPopulateZookeeper.java
index eb57a80032..41fc0b0f8d 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/tableImport/ImportPopulateZookeeper.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/tableImport/ImportPopulateZookeeper.java
@@ -75,7 +75,7 @@ class ImportPopulateZookeeper extends ManagerRepo {
     Utils.getTableNameLock().lock();
     try {
       // write tableName & tableId to zookeeper
-      Utils.checkTableDoesNotExist(env.getContext(), tableInfo.tableName, 
tableInfo.tableId,
+      Utils.checkTableNameDoesNotExist(env.getContext(), tableInfo.tableName, 
tableInfo.tableId,
           TableOperation.CREATE);
 
       String namespace = TableNameUtil.qualify(tableInfo.tableName).getFirst();
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/tableImport/ImportSetupPermissions.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/tableImport/ImportSetupPermissions.java
index 8f53de1011..bdcdcce98d 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/tableImport/ImportSetupPermissions.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/tableImport/ImportSetupPermissions.java
@@ -48,7 +48,7 @@ class ImportSetupPermissions extends ManagerRepo {
     for (TablePermission permission : TablePermission.values()) {
       try {
         security.grantTablePermission(env.getContext().rpcCreds(), 
tableInfo.user,
-            tableInfo.tableId, permission, tableInfo.namespaceId);
+            tableInfo.tableId, tableInfo.tableName, permission, 
tableInfo.namespaceId);
       } catch (ThriftSecurityException e) {
         LoggerFactory.getLogger(ImportSetupPermissions.class).error("{}", 
e.getMessage(), e);
         throw e;
diff --git a/test/src/main/java/org/apache/accumulo/test/CreateTableIT.java 
b/test/src/main/java/org/apache/accumulo/test/CreateTableIT.java
new file mode 100644
index 0000000000..b26271a3e4
--- /dev/null
+++ b/test/src/main/java/org/apache/accumulo/test/CreateTableIT.java
@@ -0,0 +1,67 @@
+/*
+ * 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
+ *
+ *   https://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.accumulo.test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.time.Duration;
+
+import org.apache.accumulo.core.client.Accumulo;
+import org.apache.accumulo.core.client.AccumuloClient;
+import org.apache.accumulo.harness.SharedMiniClusterBase;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class CreateTableIT extends SharedMiniClusterBase {
+
+  @Override
+  protected Duration defaultTimeout() {
+    return Duration.ofMinutes(5);
+  }
+
+  @BeforeAll
+  public static void setup() throws Exception {
+    SharedMiniClusterBase.startMiniCluster();
+  }
+
+  @AfterAll
+  public static void teardown() {
+    SharedMiniClusterBase.stopMiniCluster();
+  }
+
+  @Test
+  public void testCreateLotsOfTables() throws Exception {
+    try (AccumuloClient client = 
Accumulo.newClient().from(getClientProps()).build()) {
+
+      String[] tableNames = getUniqueNames(1000);
+
+      for (int i = 0; i < tableNames.length; i++) {
+        // Create waits for the Fate operation to complete
+        long start = System.currentTimeMillis();
+        client.tableOperations().create(tableNames[i]);
+        System.out.println("Table creation took: " + 
(System.currentTimeMillis() - start) + "ms");
+      }
+      // Confirm all 1000 user tables exist in addition to Root, Metadata,
+      // and ScanRef tables
+      assertEquals(1003, client.tableOperations().list().size());
+    }
+  }
+
+}

Reply via email to