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

wangchao316 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 7c0a6209b9 [IOTDB-3975]refactoring cache from authorityFetcher (#6791)
7c0a6209b9 is described below

commit 7c0a6209b9870513fdcd70d2e5eb8123b32ea055
Author: Yifu Zhou <[email protected]>
AuthorDate: Wed Jul 27 19:42:36 2022 +0800

    [IOTDB-3975]refactoring cache from authorityFetcher (#6791)
    
    [IOTDB-3975]refactoring cache from authorityFetcher (#6791)
---
 .../apache/iotdb/db/auth/AuthorizerManager.java    |   6 +-
 .../apache/iotdb/db/auth/BasicAuthorityCache.java  | 104 +++++++++++++++++++++
 .../iotdb/db/auth/ClusterAuthorityFetcher.java     |  89 +++---------------
 .../{IAuthorityFetcher.java => IAuthorCache.java}  |  20 ++--
 .../apache/iotdb/db/auth/IAuthorityFetcher.java    |   2 +
 .../iotdb/db/auth/StandaloneAuthorityFetcher.java  |  15 +--
 .../iotdb/db/auth/AuthorizerManagerTest.java       |  22 +++--
 7 files changed, 150 insertions(+), 108 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/auth/AuthorizerManager.java 
b/server/src/main/java/org/apache/iotdb/db/auth/AuthorizerManager.java
index d8114f01ca..319c6f34b1 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/AuthorizerManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/AuthorizerManager.java
@@ -63,9 +63,9 @@ public class AuthorizerManager implements IAuthorizer {
       iAuthorizer = BasicAuthorizer.getInstance();
       authReadWriteLock = new ReentrantReadWriteLock();
       if (conf.getConfig().isClusterMode()) {
-        authorityFetcher = ClusterAuthorityFetcher.getInstance();
+        authorityFetcher = new ClusterAuthorityFetcher(new 
BasicAuthorityCache());
       } else {
-        authorityFetcher = StandaloneAuthorityFetcher.getInstance();
+        authorityFetcher = new StandaloneAuthorityFetcher();
       }
     } catch (AuthException e) {
       logger.error(e.getMessage());
@@ -384,7 +384,7 @@ public class AuthorizerManager implements IAuthorizer {
   }
 
   public boolean invalidateCache(String username, String roleName) {
-    return ClusterAuthorityFetcher.getInstance().invalidateCache(username, 
roleName);
+    return authorityFetcher.getAuthorCache().invalidateCache(username, 
roleName);
   }
 
   public SettableFuture<ConfigTaskResult> queryPermission(AuthorStatement 
authorStatement) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/auth/BasicAuthorityCache.java 
b/server/src/main/java/org/apache/iotdb/db/auth/BasicAuthorityCache.java
new file mode 100644
index 0000000000..49e5a7596e
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/auth/BasicAuthorityCache.java
@@ -0,0 +1,104 @@
+/*
+ * 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.iotdb.db.auth;
+
+import org.apache.iotdb.commons.auth.entity.Role;
+import org.apache.iotdb.commons.auth.entity.User;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+public class BasicAuthorityCache implements IAuthorCache {
+  private static final Logger logger = 
LoggerFactory.getLogger(BasicAuthorityCache.class);
+
+  private IoTDBDescriptor conf = IoTDBDescriptor.getInstance();
+
+  private Cache<String, User> userCache =
+      Caffeine.newBuilder()
+          .maximumSize(conf.getConfig().getAuthorCacheSize())
+          .expireAfterAccess(conf.getConfig().getAuthorCacheExpireTime(), 
TimeUnit.MINUTES)
+          .build();
+
+  private Cache<String, Role> roleCache =
+      Caffeine.newBuilder()
+          .maximumSize(conf.getConfig().getAuthorCacheSize())
+          .expireAfterAccess(conf.getConfig().getAuthorCacheExpireTime(), 
TimeUnit.MINUTES)
+          .build();
+
+  @Override
+  public User getUserCache(String userName) {
+    return userCache.getIfPresent(userName);
+  }
+
+  @Override
+  public Role getRoleCache(String roleName) {
+    return roleCache.getIfPresent(roleName);
+  }
+
+  @Override
+  public void putUserCache(String userName, User user) {
+    userCache.put(userName, user);
+  }
+
+  @Override
+  public void putRoleCache(String roleName, Role role) {
+    roleCache.put(roleName, role);
+  }
+
+  /**
+   * Initialize user and role cache information.
+   *
+   * <p>If the permission information of the role changes, only the role cache 
information is
+   * cleared. During permission checking, if the role belongs to a user, the 
user will be
+   * initialized.
+   */
+  @Override
+  public boolean invalidateCache(String userName, String roleName) {
+    if (userName != null) {
+      if (userCache.getIfPresent(userName) != null) {
+        List<String> roleList = userCache.getIfPresent(userName).getRoleList();
+        if (!roleList.isEmpty()) {
+          roleCache.invalidateAll(roleList);
+        }
+        userCache.invalidate(userName);
+      }
+      if (userCache.getIfPresent(userName) != null) {
+        logger.error("datanode cache initialization failed");
+        return false;
+      }
+    }
+    if (roleName != null) {
+      if (roleCache.getIfPresent(roleName) != null) {
+        roleCache.invalidate(roleName);
+      }
+      if (roleCache.getIfPresent(roleName) != null) {
+        logger.error("datanode cache initialization failed");
+        return false;
+      }
+    }
+    return true;
+  }
+}
diff --git 
a/server/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java 
b/server/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java
index 4a9883e4bc..750b5f9236 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/ClusterAuthorityFetcher.java
@@ -35,7 +35,6 @@ import 
org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp;
 import org.apache.iotdb.db.client.ConfigNodeClient;
 import org.apache.iotdb.db.client.ConfigNodeInfo;
 import org.apache.iotdb.db.client.DataNodeClientPoolFactory;
-import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.mpp.plan.execution.config.ConfigTaskResult;
 import org.apache.iotdb.db.mpp.plan.statement.sys.AuthorStatement;
 import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
@@ -43,8 +42,6 @@ import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.StatementExecutionException;
 import org.apache.iotdb.rpc.TSStatusCode;
 
-import com.github.benmanes.caffeine.cache.Cache;
-import com.github.benmanes.caffeine.cache.Caffeine;
 import com.google.common.util.concurrent.SettableFuture;
 import org.apache.thrift.TException;
 import org.slf4j.Logger;
@@ -56,44 +53,24 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
 public class ClusterAuthorityFetcher implements IAuthorityFetcher {
-
   private static final Logger logger = 
LoggerFactory.getLogger(ClusterAuthorityFetcher.class);
 
-  private IoTDBDescriptor conf = IoTDBDescriptor.getInstance();
-
-  private Cache<String, User> userCache =
-      Caffeine.newBuilder()
-          .maximumSize(conf.getConfig().getAuthorCacheSize())
-          .expireAfterAccess(conf.getConfig().getAuthorCacheExpireTime(), 
TimeUnit.MINUTES)
-          .build();
-
-  private Cache<String, Role> roleCache =
-      Caffeine.newBuilder()
-          .maximumSize(conf.getConfig().getAuthorCacheSize())
-          .expireAfterAccess(conf.getConfig().getAuthorCacheExpireTime(), 
TimeUnit.MINUTES)
-          .build();
+  private IAuthorCache iAuthorCache;
 
   private static final IClientManager<PartitionRegionId, ConfigNodeClient>
       CONFIG_NODE_CLIENT_MANAGER =
           new IClientManager.Factory<PartitionRegionId, ConfigNodeClient>()
               .createClientManager(new 
DataNodeClientPoolFactory.ConfigNodeClientPoolFactory());
 
-  private static final class ClusterAuthorityFetcherHolder {
-    private static final ClusterAuthorityFetcher INSTANCE = new 
ClusterAuthorityFetcher();
-
-    private ClusterAuthorityFetcherHolder() {}
-  }
-
-  public static ClusterAuthorityFetcher getInstance() {
-    return ClusterAuthorityFetcher.ClusterAuthorityFetcherHolder.INSTANCE;
+  public ClusterAuthorityFetcher(IAuthorCache iAuthorCache) {
+    this.iAuthorCache = iAuthorCache;
   }
 
   @Override
   public TSStatus checkUserPrivileges(String username, List<String> allPath, 
int permission) {
-    User user = userCache.getIfPresent(username);
+    User user = iAuthorCache.getUserCache(username);
     if (user != null) {
       for (String path : allPath) {
         try {
@@ -103,12 +80,12 @@ public class ClusterAuthorityFetcher implements 
IAuthorityFetcher {
             }
             boolean status = false;
             for (String roleName : user.getRoleList()) {
-              Role role = roleCache.getIfPresent(roleName);
+              Role role = iAuthorCache.getRoleCache(roleName);
               // It is detected that the role of the user does not exist in 
the cache, indicating
               // that the permission information of the role has changed.
               // The user cache needs to be initialized
               if (role == null) {
-                invalidateCache(username, "");
+                iAuthorCache.invalidateCache(username, "");
                 return checkPath(username, allPath, permission);
               }
               status = role.checkPrivilege(path, permission);
@@ -196,9 +173,14 @@ public class ClusterAuthorityFetcher implements 
IAuthorityFetcher {
     return future;
   }
 
+  @Override
+  public IAuthorCache getAuthorCache() {
+    return iAuthorCache;
+  }
+
   @Override
   public TSStatus checkUser(String username, String password) {
-    User user = userCache.getIfPresent(username);
+    User user = iAuthorCache.getUserCache(username);
     if (user != null) {
       if (password != null && AuthUtils.validatePassword(password, 
user.getPassword())) {
         return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
@@ -225,7 +207,7 @@ public class ClusterAuthorityFetcher implements 
IAuthorityFetcher {
         }
       }
       if (status.getStatus().getCode() == 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-        userCache.put(username, cacheUser(status));
+        iAuthorCache.putUserCache(username, cacheUser(status));
         return status.getStatus();
       } else {
         return status.getStatus();
@@ -248,46 +230,13 @@ public class ClusterAuthorityFetcher implements 
IAuthorityFetcher {
               TSStatusCode.EXECUTE_STATEMENT_ERROR, "Failed to connect to 
config node."));
     }
     if (permissionInfoResp.getStatus().getCode() == 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-      userCache.put(username, cacheUser(permissionInfoResp));
+      iAuthorCache.putUserCache(username, cacheUser(permissionInfoResp));
       return permissionInfoResp.getStatus();
     } else {
       return permissionInfoResp.getStatus();
     }
   }
 
-  /**
-   * Initialize user and role cache information.
-   *
-   * <p>If the permission information of the role changes, only the role cache 
information is
-   * cleared. During permission checking, if the role belongs to a user, the 
user will be
-   * initialized.
-   */
-  public boolean invalidateCache(String username, String roleName) {
-    if (username != null) {
-      if (userCache.getIfPresent(username) != null) {
-        List<String> roleList = userCache.getIfPresent(username).getRoleList();
-        if (!roleList.isEmpty()) {
-          roleCache.invalidateAll(roleList);
-        }
-        userCache.invalidate(username);
-      }
-      if (userCache.getIfPresent(username) != null) {
-        logger.error("datanode cache initialization failed");
-        return false;
-      }
-    }
-    if (roleName != null) {
-      if (roleCache.getIfPresent(roleName) != null) {
-        roleCache.invalidate(roleName);
-      }
-      if (roleCache.getIfPresent(roleName) != null) {
-        logger.error("datanode cache initialization failed");
-        return false;
-      }
-    }
-    return true;
-  }
-
   /** cache user */
   public User cacheUser(TPermissionInfoResp tPermissionInfoResp) {
     User user = new User();
@@ -303,7 +252,7 @@ public class ClusterAuthorityFetcher implements 
IAuthorityFetcher {
     user.setPrivilegeList(pathPrivilegeList);
     user.setRoleList(tPermissionInfoResp.getUserInfo().getRoleList());
     for (String roleName : tPermissionInfoResp.getRoleInfo().keySet()) {
-      roleCache.put(roleName, cacheRole(roleName, tPermissionInfoResp));
+      iAuthorCache.putRoleCache(roleName, cacheRole(roleName, 
tPermissionInfoResp));
     }
     return user;
   }
@@ -353,12 +302,4 @@ public class ClusterAuthorityFetcher implements 
IAuthorityFetcher {
         AuthUtils.strToPermissions(authorStatement.getPrivilegeList()),
         authorStatement.getNodeName() == null ? "" : 
authorStatement.getNodeName().getFullPath());
   }
-
-  public Cache<String, User> getUserCache() {
-    return userCache;
-  }
-
-  public Cache<String, Role> getRoleCache() {
-    return roleCache;
-  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/auth/IAuthorityFetcher.java 
b/server/src/main/java/org/apache/iotdb/db/auth/IAuthorCache.java
similarity index 57%
copy from server/src/main/java/org/apache/iotdb/db/auth/IAuthorityFetcher.java
copy to server/src/main/java/org/apache/iotdb/db/auth/IAuthorCache.java
index bae7751fbd..eb75b2ad5a 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/IAuthorityFetcher.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/IAuthorCache.java
@@ -19,21 +19,17 @@
 
 package org.apache.iotdb.db.auth;
 
-import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.db.mpp.plan.execution.config.ConfigTaskResult;
-import org.apache.iotdb.db.mpp.plan.statement.sys.AuthorStatement;
+import org.apache.iotdb.commons.auth.entity.Role;
+import org.apache.iotdb.commons.auth.entity.User;
 
-import com.google.common.util.concurrent.SettableFuture;
+public interface IAuthorCache {
+  User getUserCache(String userName);
 
-import java.util.List;
+  Role getRoleCache(String roleName);
 
-public interface IAuthorityFetcher {
+  void putUserCache(String userName, User user);
 
-  TSStatus checkUser(String username, String password);
+  void putRoleCache(String roleName, Role role);
 
-  TSStatus checkUserPrivileges(String username, List<String> allPath, int 
permission);
-
-  SettableFuture<ConfigTaskResult> operatePermission(AuthorStatement 
authorStatement);
-
-  SettableFuture<ConfigTaskResult> queryPermission(AuthorStatement 
authorStatement);
+  boolean invalidateCache(String userName, String roleName);
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/auth/IAuthorityFetcher.java 
b/server/src/main/java/org/apache/iotdb/db/auth/IAuthorityFetcher.java
index bae7751fbd..a8d58c8877 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/IAuthorityFetcher.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/IAuthorityFetcher.java
@@ -36,4 +36,6 @@ public interface IAuthorityFetcher {
   SettableFuture<ConfigTaskResult> operatePermission(AuthorStatement 
authorStatement);
 
   SettableFuture<ConfigTaskResult> queryPermission(AuthorStatement 
authorStatement);
+
+  IAuthorCache getAuthorCache();
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/auth/StandaloneAuthorityFetcher.java 
b/server/src/main/java/org/apache/iotdb/db/auth/StandaloneAuthorityFetcher.java
index 663fd9c3c2..d6f82c86bc 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/auth/StandaloneAuthorityFetcher.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/auth/StandaloneAuthorityFetcher.java
@@ -41,16 +41,6 @@ public class StandaloneAuthorityFetcher implements 
IAuthorityFetcher {
 
   private LocalConfigNode localConfigNode = LocalConfigNode.getInstance();
 
-  private static final class StandaloneAuthorityFetcherHolder {
-    private static final StandaloneAuthorityFetcher INSTANCE = new 
StandaloneAuthorityFetcher();
-
-    private StandaloneAuthorityFetcherHolder() {}
-  }
-
-  public static StandaloneAuthorityFetcher getInstance() {
-    return 
StandaloneAuthorityFetcher.StandaloneAuthorityFetcherHolder.INSTANCE;
-  }
-
   @Override
   public TSStatus checkUser(String username, String password) {
     try {
@@ -128,4 +118,9 @@ public class StandaloneAuthorityFetcher implements 
IAuthorityFetcher {
     }
     return future;
   }
+
+  @Override
+  public IAuthorCache getAuthorCache() {
+    throw new UnsupportedOperationException("AuthorCache in Standalone is not 
supported.");
+  }
 }
diff --git 
a/server/src/test/java/org/apache/iotdb/db/auth/AuthorizerManagerTest.java 
b/server/src/test/java/org/apache/iotdb/db/auth/AuthorizerManagerTest.java
index 16f1305c84..6a356d00fa 100644
--- a/server/src/test/java/org/apache/iotdb/db/auth/AuthorizerManagerTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/auth/AuthorizerManagerTest.java
@@ -41,7 +41,7 @@ import java.util.Set;
 
 public class AuthorizerManagerTest {
 
-  ClusterAuthorityFetcher authorityFetcher = 
ClusterAuthorityFetcher.getInstance();
+  ClusterAuthorityFetcher authorityFetcher = new ClusterAuthorityFetcher(new 
BasicAuthorityCache());
 
   @Test
   public void permissionCacheTest() {
@@ -90,8 +90,10 @@ public class AuthorizerManagerTest {
     result.setRoleInfo(new HashMap<>());
 
     // User authentication permission without role
-    authorityFetcher.getUserCache().put(user.getName(), 
authorityFetcher.cacheUser(result));
-    User user1 = authorityFetcher.getUserCache().getIfPresent(user.getName());
+    authorityFetcher
+        .getAuthorCache()
+        .putUserCache(user.getName(), authorityFetcher.cacheUser(result));
+    User user1 = 
authorityFetcher.getAuthorCache().getUserCache(user.getName());
     assert user1 != null;
     Assert.assertEquals(user.getName(), user1.getName());
     Assert.assertEquals(user.getPassword(), user1.getPassword());
@@ -113,7 +115,7 @@ public class AuthorizerManagerTest {
             .getCode());
 
     // Authenticate users with roles
-    authorityFetcher.invalidateCache(user.getName(), "");
+    authorityFetcher.getAuthorCache().invalidateCache(user.getName(), "");
     tUserResp.setPrivilegeList(new ArrayList<>());
     tUserResp.setRoleList(user.getRoleList());
 
@@ -131,8 +133,10 @@ public class AuthorizerManagerTest {
       tRoleRespMap.put(role.getName(), tRoleResp);
     }
     result.setRoleInfo(tRoleRespMap);
-    authorityFetcher.getUserCache().put(user.getName(), 
authorityFetcher.cacheUser(result));
-    Role role3 = authorityFetcher.getRoleCache().getIfPresent(role1.getName());
+    authorityFetcher
+        .getAuthorCache()
+        .putUserCache(user.getName(), authorityFetcher.cacheUser(result));
+    Role role3 = 
authorityFetcher.getAuthorCache().getRoleCache(role1.getName());
     Assert.assertEquals(role1.getName(), role3.getName());
     Assert.assertEquals(role1.getPrivilegeList(), role3.getPrivilegeList());
 
@@ -151,10 +155,10 @@ public class AuthorizerManagerTest {
                 "user", Collections.singletonList("root.ln"), 
PrivilegeType.CREATE_USER.ordinal())
             .getCode());
 
-    authorityFetcher.invalidateCache(user.getName(), "");
+    authorityFetcher.getAuthorCache().invalidateCache(user.getName(), "");
 
-    user1 = authorityFetcher.getUserCache().getIfPresent(user.getName());
-    role1 = authorityFetcher.getRoleCache().getIfPresent(role1.getName());
+    user1 = authorityFetcher.getAuthorCache().getUserCache(user.getName());
+    role1 = authorityFetcher.getAuthorCache().getRoleCache(role1.getName());
 
     Assert.assertNull(user1);
     Assert.assertNull(role1);

Reply via email to