Repository: apache/gravitino
Pull request #6211: [#6133] Improvement(core): Supports to get Fileset schema location in the AuthorizationUtils
Author: login: Abyss-lord
Created: 2025-01-13T09:10:46Z | Merged: 2025-03-28T06:11:01Z

### What changes were proposed in this pull request?

Supports get Fileset schema location in the AuthorizationUtils

A Fileset can be uniquely identified using `metalake.catalog.schema.fileset`. The logic for retrieving the schema is as follows:

Check the type of `catalogObj.type()`:
   - If it is `RELATIONAL`, determine whether the `provider` is Hive. If it is a Hive table, retrieve its `LOCATION` property.
   - If it is `FILESET`, determine whether it implements `HasPropertyMetadata`:
     1. If it does, use the `schemaPropertiesMetadata()` method to retrieve the path.
     2. If it does not implement `HasPropertyMetadata`, check whether it contains any Fileset objects:
        1. If it does not, convert the catalog object to `FilesetCatalog` and retrieve its `LOCATION` property.
        2. If it does contain Filesets, retrieve all the Fileset instances and add their respective Fileset paths.

### Why are the changes needed?

Fix: #6133 

### Does this PR introduce _any_ user-facing change?

No

### How was this patch tested?

local test.


Diff:
diff --git a/authorizations/authorization-chain/src/test/java/org/apache/gravitino/authorization/chain/integration/test/TestChainedAuthorizationIT.java b/authorizations/authorization-chain/src/test/java/org/apache/gravitino/authorization/chain/integration/test/TestChainedAuthorizationIT.java
index a7e1dc465f8..3301e28e034 100644
--- a/authorizations/authorization-chain/src/test/java/org/apache/gravitino/authorization/chain/integration/test/TestChainedAuthorizationIT.java
+++ b/authorizations/authorization-chain/src/test/java/org/apache/gravitino/authorization/chain/integration/test/TestChainedAuthorizationIT.java
@@ -170,10 +170,8 @@ void clean() {
           RangerITEnv.rangerClient.getPoliciesInService(RangerITEnv.RANGER_HDFS_REPO_NAME);
       rangerHivePolicies.stream().forEach(policy -> LOG.info("Ranger Hive policy: {}", policy));
       rangerHdfsPolicies.stream().forEach(policy -> LOG.info("Ranger HDFS policy: {}", policy));
-      Preconditions.condition(
-          rangerHivePolicies.size() == 0, "Ranger Hive policies should be empty");
-      Preconditions.condition(
-          rangerHdfsPolicies.size() == 0, "Ranger HDFS policies should be empty");
+      Preconditions.condition(rangerHivePolicies.isEmpty(), "Ranger Hive policies should be empty");
+      Preconditions.condition(rangerHdfsPolicies.isEmpty(), "Ranger HDFS policies should be empty");
     } catch (RangerServiceException e) {
       throw new RuntimeException(e);
     }
diff --git a/authorizations/authorization-common/src/main/java/org/apache/gravitino/authorization/common/PathBasedMetadataObject.java b/authorizations/authorization-common/src/main/java/org/apache/gravitino/authorization/common/PathBasedMetadataObject.java
index 05b77755dc1..7b65fbd56f3 100644
--- a/authorizations/authorization-common/src/main/java/org/apache/gravitino/authorization/common/PathBasedMetadataObject.java
+++ b/authorizations/authorization-common/src/main/java/org/apache/gravitino/authorization/common/PathBasedMetadataObject.java
@@ -27,6 +27,13 @@
 import org.apache.gravitino.authorization.AuthorizationMetadataObject;
 
 public class PathBasedMetadataObject implements AuthorizationMetadataObject {
+
+  public static final PathType METALAKE_PATH = new PathType(MetadataObject.Type.METALAKE);
+  public static final PathType CATALOG_PATH = new PathType(MetadataObject.Type.CATALOG);
+  public static final PathType SCHEMA_PATH = new PathType(MetadataObject.Type.SCHEMA);
+  public static final PathType TABLE_PATH = new PathType(MetadataObject.Type.TABLE);
+  public static final PathType FILESET_PATH = new PathType(MetadataObject.Type.FILESET);
+
   /**
    * The type of metadata object in the underlying system. Every type will map one kind of the
    * entity of the Gravitino type system. When we store a Hive table, first, we will store the
diff --git a/authorizations/authorization-common/src/test/java/org/apache/gravitino/authorization/common/TestPathBasedMetadataObject.java b/authorizations/authorization-common/src/test/java/org/apache/gravitino/authorization/common/TestPathBasedMetadataObject.java
index 7656dabdfab..0fd40a541ed 100644
--- a/authorizations/authorization-common/src/test/java/org/apache/gravitino/authorization/common/TestPathBasedMetadataObject.java
+++ b/authorizations/authorization-common/src/test/java/org/apache/gravitino/authorization/common/TestPathBasedMetadataObject.java
@@ -18,7 +18,6 @@
  */
 package org.apache.gravitino.authorization.common;
 
-import org.apache.gravitino.MetadataObject;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -26,19 +25,11 @@ public class TestPathBasedMetadataObject {
   @Test
   public void PathBasedMetadataObjectEquals() {
     PathBasedMetadataObject pathBasedMetadataObject1 =
-        new PathBasedMetadataObject(
-            "parent",
-            "name",
-            "path",
-            PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+        new PathBasedMetadataObject("parent", "name", "path", PathBasedMetadataObject.FILESET_PATH);
     pathBasedMetadataObject1.validateAuthorizationMetadataObject();
 
     PathBasedMetadataObject pathBasedMetadataObject2 =
-        new PathBasedMetadataObject(
-            "parent",
-            "name",
-            "path",
-            PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+        new PathBasedMetadataObject("parent", "name", "path", PathBasedMetadataObject.FILESET_PATH);
     pathBasedMetadataObject2.validateAuthorizationMetadataObject();
 
     Assertions.assertEquals(pathBasedMetadataObject1, pathBasedMetadataObject2);
@@ -47,19 +38,12 @@ public void PathBasedMetadataObjectEquals() {
   @Test
   public void PathBasedMetadataObjectNotEquals() {
     PathBasedMetadataObject pathBasedMetadataObject1 =
-        new PathBasedMetadataObject(
-            "parent",
-            "name",
-            "path",
-            PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+        new PathBasedMetadataObject("parent", "name", "path", PathBasedMetadataObject.FILESET_PATH);
     pathBasedMetadataObject1.validateAuthorizationMetadataObject();
 
     PathBasedMetadataObject pathBasedMetadataObject2 =
         new PathBasedMetadataObject(
-            "parent",
-            "name",
-            "path1",
-            PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+            "parent", "name", "path1", PathBasedMetadataObject.FILESET_PATH);
     pathBasedMetadataObject2.validateAuthorizationMetadataObject();
 
     Assertions.assertNotEquals(pathBasedMetadataObject1, pathBasedMetadataObject2);
@@ -68,38 +52,25 @@ public void PathBasedMetadataObjectNotEquals() {
   @Test
   void testToString() {
     PathBasedMetadataObject pathBasedMetadataObject1 =
-        new PathBasedMetadataObject(
-            "parent",
-            "name",
-            "path",
-            PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+        new PathBasedMetadataObject("parent", "name", "path", PathBasedMetadataObject.FILESET_PATH);
     Assertions.assertEquals(
         "MetadataObject: [fullName=parent.name],  [path=path], [type=PATH]",
         pathBasedMetadataObject1.toString());
 
     PathBasedMetadataObject pathBasedMetadataObject2 =
-        new PathBasedMetadataObject(
-            "parent",
-            "name",
-            null,
-            PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+        new PathBasedMetadataObject("parent", "name", null, PathBasedMetadataObject.FILESET_PATH);
     Assertions.assertEquals(
         "MetadataObject: [fullName=parent.name],  [path=null], [type=PATH]",
         pathBasedMetadataObject2.toString());
 
     PathBasedMetadataObject pathBasedMetadataObject3 =
-        new PathBasedMetadataObject(
-            null, "name", null, PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+        new PathBasedMetadataObject(null, "name", null, PathBasedMetadataObject.FILESET_PATH);
     Assertions.assertEquals(
         "MetadataObject: [fullName=name],  [path=null], [type=PATH]",
         pathBasedMetadataObject3.toString());
 
     PathBasedMetadataObject pathBasedMetadataObject4 =
-        new PathBasedMetadataObject(
-            null,
-            "name",
-            "path",
-            PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+        new PathBasedMetadataObject(null, "name", "path", PathBasedMetadataObject.FILESET_PATH);
     Assertions.assertEquals(
         "MetadataObject: [fullName=name],  [path=path], [type=PATH]",
         pathBasedMetadataObject4.toString());
diff --git a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHDFSPlugin.java b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHDFSPlugin.java
index 6359344582c..2406fe55810 100644
--- a/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHDFSPlugin.java
+++ b/authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHDFSPlugin.java
@@ -251,17 +251,11 @@ protected void updatePolicyByMetadataObject(
    */
   @Override
   protected void removeMetadataObject(AuthorizationMetadataObject authzMetadataObject) {
-    if (authzMetadataObject
-        .type()
-        .equals(PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA))) {
+    if (authzMetadataObject.type().equals(PathBasedMetadataObject.SCHEMA_PATH)) {
       removeSchemaMetadataObject(authzMetadataObject);
-    } else if (authzMetadataObject
-        .type()
-        .equals(PathBasedMetadataObject.PathType.get(MetadataObject.Type.TABLE))) {
+    } else if (authzMetadataObject.type().equals(PathBasedMetadataObject.TABLE_PATH)) {
       removeTableMetadataObject(authzMetadataObject);
-    } else if (authzMetadataObject
-        .type()
-        .equals(PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET))) {
+    } else if (authzMetadataObject.type().equals(PathBasedMetadataObject.FILESET_PATH)) {
       removePolicyByMetadataObject(authzMetadataObject);
     } else {
       throw new IllegalArgumentException(
@@ -278,8 +272,7 @@ private void removeSchemaMetadataObject(AuthorizationMetadataObject authzMetadat
         authzMetadataObject instanceof PathBasedMetadataObject,
         "The metadata object must be a PathBasedMetadataObject");
     Preconditions.checkArgument(
-        authzMetadataObject.type()
-            == PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA),
+        authzMetadataObject.type().equals(PathBasedMetadataObject.SCHEMA_PATH),
         "The metadata object type must be a schema");
     Preconditions.checkArgument(
         authzMetadataObject.names().size() == 1, "The metadata object's size must be 1.");
@@ -305,7 +298,7 @@ private void removeSchemaMetadataObject(AuthorizationMetadataObject authzMetadat
                               AuthorizationMetadataObject.getParentFullName(names),
                               AuthorizationMetadataObject.getLastName(names),
                               locationPath,
-                              PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA));
+                              PathBasedMetadataObject.SCHEMA_PATH);
                       removeSchemaMetadataObject(schemaMetadataObject);
                     });
               });
@@ -330,7 +323,7 @@ private void removeSchemaMetadataObject(AuthorizationMetadataObject authzMetadat
                               authzMetadataObject.name(),
                               table.name(),
                               locationPath,
-                              PathBasedMetadataObject.PathType.get(MetadataObject.Type.TABLE));
+                              PathBasedMetadataObject.TABLE_PATH);
                       removeTableMetadataObject(tableMetadataObject);
                     });
               });
@@ -349,7 +342,7 @@ private void removeSchemaMetadataObject(AuthorizationMetadataObject authzMetadat
                     authzMetadataObject.name(),
                     schema.name(),
                     locationPath,
-                    PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA));
+                    PathBasedMetadataObject.SCHEMA_PATH);
             removePolicyByMetadataObject(schemaMetadataObject);
           });
     }
@@ -366,9 +359,7 @@ private void removeTableMetadataObject(AuthorizationMetadataObject authzMetadata
     Preconditions.checkArgument(
         authzMetadataObject.names().size() == 3, "The metadata object's name size must be 3");
     Preconditions.checkArgument(
-        authzMetadataObject
-            .type()
-            .equals(PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA)),
+        authzMetadataObject.type().equals(PathBasedMetadataObject.TABLE_PATH),
         "The metadata object type must be a path");
     removePolicyByMetadataObject(authzMetadataObject);
   }
@@ -466,27 +457,20 @@ public List<AuthorizationSecurableObject> translatePrivilege(SecurableObject sec
                 case USE_SCHEMA:
                   switch (securableObject.type()) {
                     case METALAKE:
+                      extractMetalakeLocations(
+                          securableObject, identifier, rangerSecurableObjects, rangerPrivileges);
+                      break;
                     case CATALOG:
                     case SCHEMA:
                       AuthorizationUtils.getMetadataObjectLocation(
                               identifier, MetadataObjectUtil.toEntityType(securableObject))
                           .forEach(
                               locationPath -> {
-                                PathBasedMetadataObject pathBaseMetadataObject =
-                                    new PathBasedMetadataObject(
-                                        securableObject.parent(),
-                                        securableObject.name(),
-                                        locationPath,
-                                        PathBasedMetadataObject.PathType.get(
-                                            securableObject.type()));
-                                pathBaseMetadataObject.validateAuthorizationMetadataObject();
-                                rangerSecurableObjects.add(
-                                    generateAuthorizationSecurableObject(
-                                        pathBaseMetadataObject.names(),
-                                        locationPath,
-                                        PathBasedMetadataObject.PathType.get(
-                                            securableObject.type()),
-                                        rangerPrivileges));
+                                createPathBasedMetadataObject(
+                                    securableObject,
+                                    locationPath,
+                                    rangerSecurableObjects,
+                                    rangerPrivileges);
                               });
                       break;
                     default:
@@ -499,27 +483,19 @@ public List<AuthorizationSecurableObject> translatePrivilege(SecurableObject sec
                 case CREATE_SCHEMA:
                   switch (securableObject.type()) {
                     case METALAKE:
+                      extractMetalakeLocations(
+                          securableObject, identifier, rangerSecurableObjects, rangerPrivileges);
+                      break;
                     case CATALOG:
                       AuthorizationUtils.getMetadataObjectLocation(
                               identifier, MetadataObjectUtil.toEntityType(securableObject))
                           .forEach(
-                              locationPath -> {
-                                PathBasedMetadataObject pathBaseMetadataObject =
-                                    new PathBasedMetadataObject(
-                                        securableObject.parent(),
-                                        securableObject.name(),
-                                        locationPath,
-                                        PathBasedMetadataObject.PathType.get(
-                                            securableObject.type()));
-                                pathBaseMetadataObject.validateAuthorizationMetadataObject();
-                                rangerSecurableObjects.add(
-                                    generateAuthorizationSecurableObject(
-                                        pathBaseMetadataObject.names(),
-                                        locationPath,
-                                        PathBasedMetadataObject.PathType.get(
-                                            securableObject.type()),
-                                        rangerPrivileges));
-                              });
+                              locationPath ->
+                                  createPathBasedMetadataObject(
+                                      securableObject,
+                                      locationPath,
+                                      rangerSecurableObjects,
+                                      rangerPrivileges));
                       break;
                     default:
                       throw new AuthorizationPluginException(
@@ -556,8 +532,7 @@ public List<AuthorizationSecurableObject> translatePrivilege(SecurableObject sec
                                     generateAuthorizationSecurableObject(
                                         pathBasedMetadataObject.names(),
                                         getAuthorizationPath(pathBasedMetadataObject),
-                                        PathBasedMetadataObject.PathType.get(
-                                            MetadataObject.Type.FILESET),
+                                        PathBasedMetadataObject.FILESET_PATH,
                                         rangerPrivileges));
                               });
                       break;
@@ -579,6 +554,42 @@ public List<AuthorizationSecurableObject> translatePrivilege(SecurableObject sec
     return rangerSecurableObjects;
   }
 
+  private void extractMetalakeLocations(
+      SecurableObject securableObject,
+      NameIdentifier identifier,
+      List<AuthorizationSecurableObject> rangerSecurableObjects,
+      Set<AuthorizationPrivilege> rangerPrivileges) {
+    NameIdentifier[] catalogs =
+        GravitinoEnv.getInstance()
+            .catalogDispatcher()
+            .listCatalogs(Namespace.of(identifier.name()));
+    for (NameIdentifier catalog : catalogs) {
+      AuthorizationUtils.getMetadataObjectLocation(catalog, Entity.EntityType.CATALOG)
+          .forEach(
+              locationPath ->
+                  createPathBasedMetadataObject(
+                      securableObject, locationPath, rangerSecurableObjects, rangerPrivileges));
+    }
+  }
+
+  private void createPathBasedMetadataObject(
+      SecurableObject securableObject,
+      String locationPath,
+      List<AuthorizationSecurableObject> rangerSecurableObjects,
+      Set<AuthorizationPrivilege> rangerPrivileges) {
+    PathBasedMetadataObject pathBaseMetadataObject =
+        new PathBasedMetadataObject(
+            securableObject.parent(),
+            securableObject.name(),
+            locationPath,
+            PathBasedMetadataObject.PathType.get(securableObject.type()));
+    pathBaseMetadataObject.validateAuthorizationMetadataObject();
+    rangerSecurableObjects.add(
+        generateAuthorizationSecurableObject(
+            pathBaseMetadataObject.names(), locationPath,
+            PathBasedMetadataObject.PathType.get(securableObject.type()), rangerPrivileges));
+  }
+
   @Override
   public List<AuthorizationSecurableObject> translateOwner(MetadataObject gravitinoMetadataObject) {
     List<AuthorizationSecurableObject> rangerSecurableObjects = new ArrayList<>();
@@ -600,7 +611,7 @@ public List<AuthorizationSecurableObject> translateOwner(MetadataObject gravitin
                       generateAuthorizationSecurableObject(
                           pathBasedMetadataObject.names(),
                           getAuthorizationPath(pathBasedMetadataObject),
-                          PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET),
+                          PathBasedMetadataObject.FILESET_PATH,
                           ownerMappingRule()));
                 });
         break;
@@ -686,7 +697,7 @@ public Boolean onMetadataUpdated(MetadataObjectChange... changes) throws Runtime
                           changeMetadataObject.metadataObject().parent(),
                           changeMetadataObject.metadataObject().name(),
                           locationPath,
-                          PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET));
+                          PathBasedMetadataObject.FILESET_PATH);
                   pathBaseMetadataObject.validateAuthorizationMetadataObject();
                   authzMetadataObjects.add(pathBaseMetadataObject);
                 });
diff --git a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerAuthorizationHDFSPluginIT.java b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerAuthorizationHDFSPluginIT.java
index b643948490d..9b399eeabbb 100644
--- a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerAuthorizationHDFSPluginIT.java
+++ b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerAuthorizationHDFSPluginIT.java
@@ -85,8 +85,7 @@ public void testTranslateMetadataObject() {
                     Assertions.assertEquals(
                         metalake.fullName(), pathBasedMetadataObject.fullName());
                     Assertions.assertEquals(
-                        PathBasedMetadataObject.PathType.get(MetadataObject.Type.METALAKE),
-                        pathBasedMetadataObject.type());
+                        PathBasedMetadataObject.METALAKE_PATH, pathBasedMetadataObject.type());
                     Assertions.assertEquals("/test", pathBasedMetadataObject.path());
                   });
 
@@ -100,8 +99,7 @@ public void testTranslateMetadataObject() {
                         (PathBasedMetadataObject) securableObject;
                     Assertions.assertEquals(catalog.fullName(), pathBasedMetadataObject.fullName());
                     Assertions.assertEquals(
-                        PathBasedMetadataObject.PathType.get(MetadataObject.Type.CATALOG),
-                        pathBasedMetadataObject.type());
+                        PathBasedMetadataObject.CATALOG_PATH, pathBasedMetadataObject.type());
                     Assertions.assertEquals("/test", pathBasedMetadataObject.path());
                   });
 
@@ -115,8 +113,7 @@ public void testTranslateMetadataObject() {
                         (PathBasedMetadataObject) securableObject;
                     Assertions.assertEquals(schema.fullName(), pathBasedMetadataObject.fullName());
                     Assertions.assertEquals(
-                        PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA),
-                        pathBasedMetadataObject.type());
+                        PathBasedMetadataObject.SCHEMA_PATH, pathBasedMetadataObject.type());
                     Assertions.assertEquals("/test", pathBasedMetadataObject.path());
                   });
 
@@ -131,8 +128,7 @@ public void testTranslateMetadataObject() {
                         (PathBasedMetadataObject) securableObject;
                     Assertions.assertEquals(table.fullName(), pathBasedMetadataObject.fullName());
                     Assertions.assertEquals(
-                        PathBasedMetadataObject.PathType.get(MetadataObject.Type.TABLE),
-                        securableObject.type());
+                        PathBasedMetadataObject.TABLE_PATH, securableObject.type());
                     Assertions.assertEquals("/test", pathBasedMetadataObject.path());
                   });
 
@@ -147,8 +143,7 @@ public void testTranslateMetadataObject() {
                         (PathBasedMetadataObject) securableObject;
                     Assertions.assertEquals(fileset.fullName(), pathBasedMetadataObject.fullName());
                     Assertions.assertEquals(
-                        PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET),
-                        securableObject.type());
+                        PathBasedMetadataObject.FILESET_PATH, securableObject.type());
                     Assertions.assertEquals("/test", pathBasedMetadataObject.path());
                   });
         });
@@ -211,8 +206,7 @@ public void testTranslatePrivilege() {
                 PathBasedSecurableObject pathBasedSecurableObject =
                     (PathBasedSecurableObject) securableObject;
                 Assertions.assertEquals(
-                    PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET),
-                    pathBasedSecurableObject.type());
+                    PathBasedMetadataObject.FILESET_PATH, pathBasedSecurableObject.type());
                 Assertions.assertEquals("/test", pathBasedSecurableObject.path());
                 Assertions.assertEquals(2, pathBasedSecurableObject.privileges().size());
               });
@@ -252,8 +246,7 @@ public void testTranslateOwner() {
                 Assertions.assertEquals(1, filesetOwner.size());
                 Assertions.assertEquals("/test", pathBasedSecurableObject.path());
                 Assertions.assertEquals(
-                    PathBasedMetadataObject.PathType.get(MetadataObject.Type.FILESET),
-                    pathBasedSecurableObject.type());
+                    PathBasedMetadataObject.FILESET_PATH, pathBasedSecurableObject.type());
                 Assertions.assertEquals(3, pathBasedSecurableObject.privileges().size());
               });
         });
diff --git a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
index cbae0a5c917..4df0270c6c0 100644
--- a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
+++ b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
@@ -22,13 +22,11 @@
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
-import java.util.stream.Collectors;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.gravitino.Catalog;
 import org.apache.gravitino.Entity;
@@ -62,6 +60,9 @@
 /* The utilization class of authorization module*/
 public class AuthorizationUtils {
   private static final Logger LOG = LoggerFactory.getLogger(AuthorizationUtils.class);
+  private static final String FILESET_CATALOG_LOCATION = "location";
+  private static final String FILESET_SCHEMA_LOCATION = "location";
+  private static final String HIVE_LOCATION = "location";
   static final String USER_DOES_NOT_EXIST_MSG = "User %s does not exist in the metalake %s";
   static final String GROUP_DOES_NOT_EXIST_MSG = "Group %s does not exist in the metalake %s";
   static final String ROLE_DOES_NOT_EXIST_MSG = "Role %s does not exist in the metalake %s";
@@ -427,30 +428,15 @@ private static String getHiveDefaultLocation(String metalakeName, String catalog
   public static List<String> getMetadataObjectLocation(
       NameIdentifier ident, Entity.EntityType type) {
     List<String> locations = new ArrayList<>();
+
+    // If we don't enable authorization, the location should return empty collection.
+    if (GravitinoEnv.getInstance().accessControlDispatcher() == null) {
+      return locations;
+    }
+
     try {
       switch (type) {
         case METALAKE:
-          {
-            NameIdentifier[] identifiers =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .listCatalogs(Namespace.of(ident.name()));
-            Arrays.stream(identifiers)
-                .collect(Collectors.toList())
-                .forEach(
-                    identifier -> {
-                      Catalog catalogObj =
-                          GravitinoEnv.getInstance().catalogDispatcher().loadCatalog(identifier);
-                      if (catalogObj.provider().equals("hive")) {
-                        // The Hive default schema location is Hive warehouse directory
-                        String defaultSchemaLocation =
-                            getHiveDefaultLocation(ident.name(), catalogObj.name());
-                        if (defaultSchemaLocation != null && !defaultSchemaLocation.isEmpty()) {
-                          locations.add(defaultSchemaLocation);
-                        }
-                      }
-                    });
-          }
           break;
         case CATALOG:
           {
@@ -466,30 +452,54 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
-                String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HIVE_LOCATION)) {
+                String schemaLocation = schema.properties().get(HIVE_LOCATION);
                 if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
                   LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if ("hadoop".equals(catalogObj.provider())) {
+                if (schema.properties().containsKey(FILESET_SCHEMA_LOCATION)) {
+                  String schemaLocation = schema.properties().get(FILESET_SCHEMA_LOCATION);
+                  if (StringUtils.isNotBlank(schemaLocation)) {
+                    locations.add(schemaLocation);
+                  } else if (catalogObj.properties().containsKey(FILESET_CATALOG_LOCATION)) {
+                    String catalogLocation = schema.properties().get(FILESET_CATALOG_LOCATION);
+                    if (StringUtils.isNotBlank(catalogLocation)) {
+                      schemaLocation = catalogLocation + "/" + schema.name();
+                      locations.add(schemaLocation);
+                    }
+                  } else {
+                    LOG.warn("Schema {} location is not found", ident);
+                  }
+                }
+              }
+              break;
+
+            default:
+              LOG.warn("Unsupported catalog type {}", catalogObj.type());
+              break;
           }
           break;
+
         case TABLE:
           {
-            Catalog catalogObj =
+            catalogObj =
                 GravitinoEnv.getInstance()
                     .catalogDispatcher()
                     .loadCatalog(
@@ -517,6 +527,9 @@ public static List<String> getMetadataObjectLocation(
               filesetLocation != null, String.format("Fileset %s location is not found", ident));
           locations.add(filesetLocation);
           break;
+        case TOPIC:
+          // Topic doesn't have locations now.
+          break;
         default:
           throw new AuthorizationPluginException(
               "Failed to get location paths for metadata object %s type %s", ident, type);
@@ -527,9 +540,4 @@ public static List<String> getMetadataObjectLocation(
 
     return locations;
   }
-
-  private static NameIdentifier getObjectNameIdentifier(
-      String metalake, MetadataObject metadataObject) {
-    return NameIdentifier.parse(String.format("%s.%s", metalake, metadataObject.fullName()));
-  }
 }


Reviews:
user: login: xunliu
body: @Abyss-lord 
I think we needs to consider to add an integration test, It's include Schema is Fileset.
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-01-14T02:20:37Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-01-14T06:29:48Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-01-14T06:32:51Z
user: login: yuqi1129
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-01-14T07:27:00Z
user: login: Abyss-lord
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-01-14T09:28:02Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-01-14T09:46:18Z
user: login: Abyss-lord
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-01-14T09:50:21Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-01-14T11:16:06Z
user: login: Abyss-lord
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-01-14T15:41:04Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-08T09:41:26Z
user: login: yuqi1129
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-10T01:42:03Z
user: login: yuqi1129
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-10T01:42:45Z
user: login: tengqm
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-17T04:00:20Z
user: login: yuqi1129
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T08:37:41Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T12:29:17Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T12:45:49Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T12:47:32Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T12:48:14Z
user: login: yuqi1129
body: LGTM except a minor one. 
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T14:32:03Z
user: login: roryqi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T02:03:42Z
user: login: yuqi1129
body: LGTM
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T06:10:00Z
user: login: yuqi1129
body: LGTM
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-28T06:10:14Z

Review comments:
diff_hunk: @@ -23,4 +23,6 @@ public class Constants {
 
   public static final String BUILTIN_LOCAL_FS_PROVIDER = "builtin-local";
   public static final String BUILTIN_HDFS_FS_PROVIDER = "builtin-hdfs";
+  public static final String LOCATION = "location";
path: catalogs/catalog-common/src/main/java/org/apache/gravitino/catalog/hadoop/Constants.java
user: login: xunliu
body: We already have `LOCATION` in the `HiveConstants`.
created_at: 2025-01-13T12:17:35Z
author_association: MEMBER
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
+                HasPropertyMetadata catalogObjWithProperties = (HasPropertyMetadata) catalogObj;
+                Map<String, String> properties = schema.properties();
+                String schemaLocation =
+                    (String)
+                        catalogObjWithProperties
+                            .schemaPropertiesMetadata()
+                            .getOrDefault(properties, Constants.LOCATION);
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: roryqi
body: This location should be only used by Hadoop Catalog.
created_at: 2025-01-14T06:29:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: roryqi
body: Why do we need to judge `HasPropertyMetdatadata`?
created_at: 2025-01-14T06:32:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -107,6 +108,17 @@ public static Namespace ofFileset(String metalake, String catalog, String schema
     return Namespace.of(metalake, catalog, schema);
   }
 
+  /**
+   * Create a namespace for fileset from a schema name identifier.
+   *
+   * @param ident The schema name identifier.
+   * @return A namespace for fileset.
+   */
+  public static Namespace toFileset(NameIdentifier ident) {
path: core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java
user: login: yuqi1129
body: We could not get the actual meaning from the method name, what about `toFilesetNamespace` or something similar?
.
Parameter name `ident` can be replace with `schemaIdent` to improve the readiabitily. 
created_at: 2025-01-14T07:11:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
+                HasPropertyMetadata catalogObjWithProperties = (HasPropertyMetadata) catalogObj;
+                Map<String, String> properties = schema.properties();
+                String schemaLocation =
+                    (String)
+                        catalogObjWithProperties
+                            .schemaPropertiesMetadata()
+                            .getOrDefault(properties, Constants.LOCATION);
+                if (StringUtils.isNotBlank(schemaLocation)) {
+                  locations.add(normalizeFilesetLocation(schemaLocation));
+                }
+              } else {
+                FilesetCatalog filesetCatalog = catalogObj.asFilesetCatalog();
+                String catalogObjLocation = catalogObj.properties().get(Constants.LOCATION);
+                Namespace namespace = NamespaceUtil.toFileset(ident);
+                NameIdentifier[] nameIdentifiers = filesetCatalog.listFilesets(namespace);
+                if (nameIdentifiers.length == 0) {
+                  LOG.warn(
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: yuqi1129
body: I'm unclear why we will use `catalogLocation` when is no fileset loaded? Another point, I think we can't guarantee that `catalogObjLocation` is found and it can be a null value. 
created_at: 2025-01-14T07:26:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: Abyss-lord
body: @jerqi Is the fileset catalog guaranteed to implement the `HasPropertyMetadata` interface?
created_at: 2025-01-14T09:28:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: roryqi
body: Some of the fileset catalogs have the property `location` although they implement the `HasPropertyMetdata` interface.
created_at: 2025-01-14T09:46:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: Abyss-lord
body: The current processing logic is
1. If the provider is Hadoop, use `HasPropertyMetadata` to get the location of the Schema.
2. In other cases, consider adding paths to all filesets below the Schema.
WDYT, @jerqi 
created_at: 2025-01-14T09:50:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: roryqi
body: The 2 seems weird for me. Is this consistent with Hive schema implement.
created_at: 2025-01-14T11:16:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: Abyss-lord
body: > The 2 seems weird for me. Is this consistent with Hive schema implement.

If it's not a Hadoop fileset, can we only get the path from the fileset.
created_at: 2025-01-14T15:41:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: roryqi
body: Now, we only have Hadoop fileset.
created_at: 2025-02-08T09:41:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -107,6 +108,17 @@ public static Namespace ofFileset(String metalake, String catalog, String schema
     return Namespace.of(metalake, catalog, schema);
   }
 
+  /**
+   * Create a namespace for fileset from a schema name identifier.
+   *
+   * @param ident The schema name identifier.
+   * @return A namespace for fileset.
+   */
+  public static Namespace toFileset(NameIdentifier ident) {
path: core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java
user: login: yuqi1129
body: @Abyss-lord 
Have you resolved this comment? I noticed that you marked it as resolved.
created_at: 2025-02-10T01:42:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
+              if ("hive".equals(catalogObj.provider())
+                  && schema.properties().containsKey(HiveConstants.LOCATION)) {
                 String schemaLocation = schema.properties().get(HiveConstants.LOCATION);
-                if (schemaLocation != null && schemaLocation.isEmpty()) {
+                if (StringUtils.isNotBlank(schemaLocation)) {
                   locations.add(schemaLocation);
                 } else {
-                  LOG.warn("Schema %s location is not found", ident);
+                  LOG.warn("Schema {} location is not found", ident);
                 }
               }
-            }
-            // TODO: [#6133] Supports get Fileset schema location in the AuthorizationUtils
+              break;
+
+            case FILESET:
+              if (catalogObj instanceof HasPropertyMetadata) {
+                HasPropertyMetadata catalogObjWithProperties = (HasPropertyMetadata) catalogObj;
+                Map<String, String> properties = schema.properties();
+                String schemaLocation =
+                    (String)
+                        catalogObjWithProperties
+                            .schemaPropertiesMetadata()
+                            .getOrDefault(properties, Constants.LOCATION);
+                if (StringUtils.isNotBlank(schemaLocation)) {
+                  locations.add(normalizeFilesetLocation(schemaLocation));
+                }
+              } else {
+                FilesetCatalog filesetCatalog = catalogObj.asFilesetCatalog();
+                String catalogObjLocation = catalogObj.properties().get(Constants.LOCATION);
+                Namespace namespace = NamespaceUtil.toFileset(ident);
+                NameIdentifier[] nameIdentifiers = filesetCatalog.listFilesets(namespace);
+                if (nameIdentifiers.length == 0) {
+                  LOG.warn(
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: yuqi1129
body: ditto
created_at: 2025-02-10T01:42:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: tengqm
body: Emm .... I don't like this kind of "info" logs.
It smells to me like "debug" logs, which should be killed unless there is a real need.
created_at: 2025-02-17T03:57:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -278,8 +278,9 @@ private void removeSchemaMetadataObject(AuthorizationMetadataObject authzMetadat
         authzMetadataObject instanceof PathBasedMetadataObject,
         "The metadata object must be a PathBasedMetadataObject");
     Preconditions.checkArgument(
-        authzMetadataObject.type()
-            == PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA),
+        authzMetadataObject
+            .type()
+            .equals(PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA)),
path: authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHDFSPlugin.java
user: login: yuqi1129
body: Why don't you create some static instances in PathBasedMetadataObject to avoid creating new instances every time?

```java
public class PathBasedMetadataObject {

public static final SCHEMA_PATH = new PathType(MetadataObject.Type.SCHEMA);
public static final TABLE_PATH = new PathType(MetadataObject.Type.TABLE);
public static final FILESET_PATH = new PathType(MetadataObject.Type.FILESET);
...
}
```

Then we can use `SCHEMA_PATH`, `TABLE_PATH` and `FILESET_PATH` directly. 

created_at: 2025-03-27T08:29:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -499,27 +506,32 @@ public List<AuthorizationSecurableObject> translatePrivilege(SecurableObject sec
                 case CREATE_SCHEMA:
                   switch (securableObject.type()) {
                     case METALAKE:
+                      NameIdentifier[] catalogs =
+                          GravitinoEnv.getInstance()
+                              .catalogDispatcher()
+                              .listCatalogs(Namespace.of(identifier.name()));
+                      for (NameIdentifier catalog : catalogs) {
+                        AuthorizationUtils.getMetadataObjectLocation(
+                                catalog, Entity.EntityType.CATALOG)
+                            .forEach(
+                                locationPath ->
+                                    createPathBasedMetadataObject(
+                                        securableObject,
+                                        locationPath,
+                                        rangerSecurableObjects,
+                                        rangerPrivileges));
+                      }
+                      break;
path: authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHDFSPlugin.java
user: login: yuqi1129
body: This part is almost the same as L470. Can you try to extract a common method?
created_at: 2025-03-27T08:33:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: yuqi1129
body: +1
created_at: 2025-03-27T08:35:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,12 +18,32 @@
  */
 package org.apache.gravitino.utils;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
 import org.apache.gravitino.Namespace;
 import org.apache.gravitino.exceptions.IllegalNamespaceException;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 public class TestNamespaceUtil {
+  private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
path: core/src/test/java/org/apache/gravitino/utils/TestNamespaceUtil.java
user: login: yuqi1129
body: Why do we need to use the stream?
created_at: 2025-03-27T08:37:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -278,8 +278,9 @@ private void removeSchemaMetadataObject(AuthorizationMetadataObject authzMetadat
         authzMetadataObject instanceof PathBasedMetadataObject,
         "The metadata object must be a PathBasedMetadataObject");
     Preconditions.checkArgument(
-        authzMetadataObject.type()
-            == PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA),
+        authzMetadataObject
+            .type()
+            .equals(PathBasedMetadataObject.PathType.get(MetadataObject.Type.SCHEMA)),
path: authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHDFSPlugin.java
user: login: roryqi
body: OK.
created_at: 2025-03-27T12:29:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -499,27 +506,32 @@ public List<AuthorizationSecurableObject> translatePrivilege(SecurableObject sec
                 case CREATE_SCHEMA:
                   switch (securableObject.type()) {
                     case METALAKE:
+                      NameIdentifier[] catalogs =
+                          GravitinoEnv.getInstance()
+                              .catalogDispatcher()
+                              .listCatalogs(Namespace.of(identifier.name()));
+                      for (NameIdentifier catalog : catalogs) {
+                        AuthorizationUtils.getMetadataObjectLocation(
+                                catalog, Entity.EntityType.CATALOG)
+                            .forEach(
+                                locationPath ->
+                                    createPathBasedMetadataObject(
+                                        securableObject,
+                                        locationPath,
+                                        rangerSecurableObjects,
+                                        rangerPrivileges));
+                      }
+                      break;
path: authorizations/authorization-ranger/src/main/java/org/apache/gravitino/authorization/ranger/RangerAuthorizationHDFSPlugin.java
user: login: roryqi
body: OK.
created_at: 2025-03-27T12:45:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,12 +18,32 @@
  */
 package org.apache.gravitino.utils;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
 import org.apache.gravitino.Namespace;
 import org.apache.gravitino.exceptions.IllegalNamespaceException;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 public class TestNamespaceUtil {
+  private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
path: core/src/test/java/org/apache/gravitino/utils/TestNamespaceUtil.java
user: login: roryqi
body: Removed.
created_at: 2025-03-27T12:47:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -465,30 +471,72 @@ public static List<String> getMetadataObjectLocation(
           }
           break;
         case SCHEMA:
-          {
-            Catalog catalogObj =
-                GravitinoEnv.getInstance()
-                    .catalogDispatcher()
-                    .loadCatalog(
-                        NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
-            LOG.info("Catalog provider is %s", catalogObj.provider());
-            if (catalogObj.provider().equals("hive")) {
-              Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
-              if (schema.properties().containsKey(HiveConstants.LOCATION)) {
+          Catalog catalogObj =
+              GravitinoEnv.getInstance()
+                  .catalogDispatcher()
+                  .loadCatalog(
+                      NameIdentifier.of(ident.namespace().level(0), ident.namespace().level(1)));
+          Schema schema = GravitinoEnv.getInstance().schemaDispatcher().loadSchema(ident);
+
+          switch (catalogObj.type()) {
+            case RELATIONAL:
+              LOG.info("Catalog provider is {}", catalogObj.provider());
path: core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java
user: login: roryqi
body: Removed.
created_at: 2025-03-27T12:48:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,7 +24,6 @@
 import org.junit.jupiter.api.Test;
 
 public class TestNamespaceUtil {
-
path: core/src/test/java/org/apache/gravitino/utils/TestNamespaceUtil.java
user: login: yuqi1129
body: If this is a change unrelated to this, please revert it. 
created_at: 2025-03-27T14:27:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -24,7 +24,6 @@
 import org.junit.jupiter.api.Test;
 
 public class TestNamespaceUtil {
-
path: core/src/test/java/org/apache/gravitino/utils/TestNamespaceUtil.java
user: login: roryqi
body: Done.
created_at: 2025-03-28T02:03:41Z
author_association: CONTRIBUTOR

PR comments:
user: login: Abyss-lord
created_at: 2025-01-13T09:12:16Z
body: Hi @xunliu , could you please review this PR when you have time? I’d really appreciate your feedback.
author_association: CONTRIBUTOR
user: login: roryqi
created_at: 2025-03-12T06:50:56Z
body: @Abyss-lord Will you continue this PR?
author_association: CONTRIBUTOR
user: login: roryqi
created_at: 2025-03-25T09:48:28Z
body: @Abyss-lord Would you like to continue this PR?
author_association: CONTRIBUTOR
user: login: roryqi
created_at: 2025-03-25T12:32:12Z
body: After discussing offline, I will take on this PR.
author_association: CONTRIBUTOR