Copilot commented on code in PR #9812:
URL: https://github.com/apache/gravitino/pull/9812#discussion_r2732136910


##########
server-common/build.gradle.kts:
##########
@@ -40,6 +40,7 @@ dependencies {
   implementation(libs.bundles.kerby)
   implementation(libs.bundles.log4j)
   implementation(libs.bundles.metrics)
+  implementation(libs.caffeine)

Review Comment:
   There is a discrepancy between the PR title which references "#9770" and the 
PR description which states "Fix: #9970". Please verify which issue number is 
correct and update the title or description accordingly to ensure proper issue 
tracking.



##########
server-common/src/main/java/org/apache/gravitino/server/authorization/jcasbin/JcasbinAuthorizer.java:
##########
@@ -488,7 +514,7 @@ private void loadRolePrivilege(
   }
 
   private void loadOwnerPolicy(String metalake, MetadataObject metadataObject, 
Long metadataId) {
-    if (ownerRel.containsKey(metadataId)) {
+    if (ownerRel.getIfPresent(metadataId) != null) {
       LOG.debug("Metadata {} OWNER has bean loaded.", metadataId);

Review Comment:
   Typo in log message: "bean" should be "been".
   ```suggestion
         LOG.debug("Metadata {} OWNER has been loaded.", metadataId);
   ```



##########
server-common/src/main/java/org/apache/gravitino/server/authorization/jcasbin/JcasbinAuthorizer.java:
##########
@@ -83,14 +84,40 @@ public class JcasbinAuthorizer implements 
GravitinoAuthorizer {
    * loadedRoles is used to cache roles that have loaded permissions. When the 
permissions of a role
    * are updated, they should be removed from it.
    */
-  private Set<Long> loadedRoles = ConcurrentHashMap.newKeySet();
+  private Cache<Long, Boolean> loadedRoles;
 
-  private Map<Long, Long> ownerRel = new ConcurrentHashMap<>();
+  private Cache<Long, Optional<Long>> ownerRel;
 
   private Executor executor = null;
 
   @Override
   public void initialize() {
+    long cacheExpirationSecs =
+        GravitinoEnv.getInstance()
+            .config()
+            .get(Configs.GRAVITINO_AUTHORIZATION_CACHE_EXPIRATION_SECS);
+    long roleCacheSize =
+        
GravitinoEnv.getInstance().config().get(Configs.GRAVITINO_AUTHORIZATION_ROLE_CACHE_SIZE);
+    long ownerCacheSize =
+        
GravitinoEnv.getInstance().config().get(Configs.GRAVITINO_AUTHORIZATION_OWNER_CACHE_SIZE);
+    loadedRoles =
+        Caffeine.newBuilder()
+            .expireAfterWrite(cacheExpirationSecs, TimeUnit.SECONDS)
+            .maximumSize(roleCacheSize)
+            .executor(Runnable::run)
+            .removalListener(
+                (roleId, value, cause) -> {
+                  if (roleId != null) {
+                    allowEnforcer.deleteRole(String.valueOf(roleId));
+                    denyEnforcer.deleteRole(String.valueOf(roleId));
+                  }
+                })
+            .build();
+    ownerRel =
+        Caffeine.newBuilder()
+            .expireAfterWrite(cacheExpirationSecs, TimeUnit.SECONDS)
+            .maximumSize(ownerCacheSize)
+            .build();
     executor =
         Executors.newFixedThreadPool(
             GravitinoEnv.getInstance()

Review Comment:
   The removal listener for the `loadedRoles` cache references `allowEnforcer` 
and `denyEnforcer`, but these enforcers are initialized after the cache (line 
131). This creates a potential issue where if cache eviction happens during 
initialization or immediately after, the enforcers would be null, leading to a 
NullPointerException.
   
   To fix this, either:
   1. Initialize the enforcers before the caches, or
   2. Add null checks in the removal listener before attempting to delete roles



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to