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

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


The following commit(s) were added to refs/heads/master by this push:
     new 073bd9fb4 RANGER-5367: simplify resource-name parsing (#699)
073bd9fb4 is described below

commit 073bd9fb43f8a3f3f55353cf90c5ad691db24651
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Mon Oct 13 15:09:55 2025 -0700

    RANGER-5367: simplify resource-name parsing (#699)
---
 .../ranger/plugin/model/RangerServiceDef.java      |  21 --
 .../model/validation/RangerServiceDefHelper.java   |  27 +-
 .../validation/TestRangerServiceDefHelper.java     |  26 +-
 .../ranger/authz/api/RangerAuthzApiErrorCode.java  |   6 +-
 .../authz/util/RangerResourceNameParser.java       | 216 +++++++++++
 .../ranger/authz/util/RangerResourceTemplate.java  | 192 ----------
 .../ranger/authz/api/TestAuthzApiErrorCode.java    |   8 +-
 .../ranger/authz/api/TestAuthzException.java       |  10 +-
 .../authz/util/TestRangerResourceNameParser.java   | 406 +++++++++++++++++++++
 .../ranger/authz/util/TestResourceTemplate.java    | 250 -------------
 10 files changed, 647 insertions(+), 515 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
index 479d7d1ef..71a578b8f 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
@@ -1417,7 +1417,6 @@ public static class RangerResourceDef implements 
java.io.Serializable {
         private String              rbKeyValidationMessage;
         private Set<String>         accessTypeRestrictions;
         private Boolean             isValidLeaf;
-        private String              rrnTemplate; // resource-name template. 
Examples: {database}.{table}.{column}, 
{container}@{storageaccount}/{relativepath}
 
         public RangerResourceDef() {
             this(null, null, null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, null, null, null);
@@ -1445,7 +1444,6 @@ public RangerResourceDef(RangerResourceDef other) {
             setRbKeyValidationMessage(other.getRbKeyValidationMessage());
             setAccessTypeRestrictions(other.getAccessTypeRestrictions());
             setIsValidLeaf(other.getIsValidLeaf());
-            setRrnTemplate(other.getRrnTemplate());
         }
 
         public RangerResourceDef(Long itemId, String name, String type, 
Integer level, String parent, Boolean mandatory, Boolean lookupSupported, 
Boolean recursiveSupported, Boolean excludesSupported, String matcher, 
Map<String, String> matcherOptions, String validationRegEx, String 
validationMessage, String uiHint, String label, String description, String 
rbKeyLabel, String rbKeyDescription, String rbKeyValidationMessage, Set<String> 
accessTypeRestrictions, Boolean isValidLeaf) {
@@ -1754,14 +1752,6 @@ public void setIsValidLeaf(Boolean isValidLeaf) {
             this.isValidLeaf = isValidLeaf;
         }
 
-        public String getRrnTemplate() {
-            return rrnTemplate;
-        }
-
-        public void setRrnTemplate(String rrnTemplate) {
-            this.rrnTemplate = rrnTemplate;
-        }
-
         public void dedupStrings(Map<String, String> strTbl) {
             name                   = StringUtil.dedupString(name, strTbl);
             type                   = StringUtil.dedupString(type, strTbl);
@@ -1777,7 +1767,6 @@ public void dedupStrings(Map<String, String> strTbl) {
             rbKeyDescription       = StringUtil.dedupString(rbKeyDescription, 
strTbl);
             rbKeyValidationMessage = 
StringUtil.dedupString(rbKeyValidationMessage, strTbl);
             accessTypeRestrictions = 
StringUtil.dedupStringsSet(accessTypeRestrictions, strTbl);
-            rrnTemplate            = StringUtil.dedupString(rrnTemplate, 
strTbl);
         }
 
         public StringBuilder toString(StringBuilder sb) {
@@ -1803,7 +1792,6 @@ public StringBuilder toString(StringBuilder sb) {
             
sb.append("rbKeyValidationMessage={").append(rbKeyValidationMessage).append("} 
");
             
sb.append("accessTypeRestrictions={").append(accessTypeRestrictions == null ? 
"null" : accessTypeRestrictions.toString()).append("} ");
             sb.append("isValidLeaf={").append(isValidLeaf == null ? "null" : 
isValidLeaf.toString()).append("} ");
-            sb.append("rrnTemplate={").append(rrnTemplate == null ? "null" : 
rrnTemplate).append("} ");
             sb.append("}");
 
             return sb;
@@ -1866,9 +1854,6 @@ public int hashCode() {
             result = prime
                     * result
                     + ((isValidLeaf == null) ? 0 : isValidLeaf.hashCode());
-            result = prime
-                    * result
-                    + ((rrnTemplate == null) ? 0 : rrnTemplate.hashCode());
             return result;
         }
 
@@ -2024,12 +2009,6 @@ public boolean equals(Object obj) {
                 return false;
             }
 
-            if (rrnTemplate == null) {
-                return other.rrnTemplate == null;
-            } else if (!rrnTemplate.equals(other.rrnTemplate)) {
-                return false;
-            }
-
             return true;
         }
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
index ae414cf4a..30be2cb86 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
@@ -48,10 +48,7 @@
 public class RangerServiceDefHelper {
     private static final Logger LOG = 
LoggerFactory.getLogger(RangerServiceDefHelper.class);
 
-    public static final String RRN_RESOURCE_PREFIX   = "{";
-    public static final String RRN_RESOURCE_SUFFIX   = "}";
-    public static final String RRN_RESOURCE_SEP      = ".";
-    public static final String RRN_PATH_RESOURCE_SEP = "/";
+    public static final String RRN_RESOURCE_SEP = "/";
 
     static final Map<String, Delegate> cache = new ConcurrentHashMap<>();
     final        Delegate              delegate;
@@ -497,13 +494,7 @@ public Delegate(RangerServiceDef serviceDef, boolean 
checkForCycles) {
                 orderedResourceNames = buildSortedResourceNames();
 
                 for (RangerResourceDef resourceDef : 
serviceDef.getResources()) {
-                    if (StringUtils.isBlank(resourceDef.getRrnTemplate())) {
-                        
resourceDef.setRrnTemplate(getDefaultRrnTemplate(resourceDef));
-
-                        LOG.debug("No rrnTemplate was defined for resource 
{}.{}. It is now set to default: {}", serviceName, resourceDef.getName(), 
resourceDef.getRrnTemplate());
-                    }
-
-                    this.rrnTemplates.put(resourceDef.getName(), 
resourceDef.getRrnTemplate());
+                    this.rrnTemplates.put(resourceDef.getName(), 
getDefaultRrnTemplate(resourceDef));
                 }
             } else {
                 orderedResourceNames = new ArrayList<>();
@@ -901,11 +892,11 @@ public int compareTo(ResourceNameLevel other) {
         }
 
         // create default resource-name template for the resource-def, like:
-        //  database:{database}
-        //  table:{database}.{table}
-        //  column:{database}.{table}.{column}
-        //  path:{bucket}/{path}
-        //  key:{volume}.{bucket}/{key}
+        //  database:database
+        //  table:database/table
+        //  column:database/table/column
+        //  path:bucket/path
+        //  key:volume/bucket/key
         private String getDefaultRrnTemplate(RangerResourceDef resourceDef) {
             List<RangerResourceDef> path = new ArrayList<>();
 
@@ -919,10 +910,10 @@ private String getDefaultRrnTemplate(RangerResourceDef 
resourceDef) {
                 RangerResourceDef res = path.get(i);
 
                 if (i > 0) {
-                    sb.append(StringUtils.equalsIgnoreCase(res.getType(), 
"path") ? RRN_PATH_RESOURCE_SEP : RRN_RESOURCE_SEP);
+                    sb.append(RRN_RESOURCE_SEP);
                 }
 
-                
sb.append(RRN_RESOURCE_PREFIX).append(res.getName()).append(RRN_RESOURCE_SUFFIX);
+                sb.append(res.getName());
             }
 
             return sb.toString();
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
index a5e76874d..b31726006 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
@@ -382,19 +382,12 @@ public void testRrnTemplateHive() {
         RangerServiceDef       svcDef       = JsonUtils.jsonToObject(reader, 
RangerServiceDef.class);
         RangerServiceDefHelper svcDefHelper = new 
RangerServiceDefHelper(svcDef);
 
-        String rrnDatabase = svcDefHelper.getRrnTemplate("database");
-        String rrnTable    = svcDefHelper.getRrnTemplate("table");
-        String rrnColumn   = svcDefHelper.getRrnTemplate("column");
-        String rrnUdf      = svcDefHelper.getRrnTemplate("udf");
-        String rrnUrl      = svcDefHelper.getRrnTemplate("url");
-        String rrnUnknown  = svcDefHelper.getRrnTemplate("unknown-resource");
-
-        assertEquals("{database}", rrnDatabase);
-        assertEquals("{database}.{table}", rrnTable);
-        assertEquals("{database}.{table}.{column}", rrnColumn);
-        assertEquals("{database}.{udf}", rrnUdf);
-        assertEquals("{url}", rrnUrl);
-        assertNull(rrnUnknown);
+        assertEquals("database", svcDefHelper.getRrnTemplate("database"));
+        assertEquals("database/table", svcDefHelper.getRrnTemplate("table"));
+        assertEquals("database/table/column", 
svcDefHelper.getRrnTemplate("column"));
+        assertEquals("database/udf", svcDefHelper.getRrnTemplate("udf"));
+        assertEquals("url", svcDefHelper.getRrnTemplate("url"));
+        assertNull(svcDefHelper.getRrnTemplate("unknown-resource"));
     }
 
     @Test
@@ -403,11 +396,8 @@ public void testRrnTemplateS3() {
         RangerServiceDef       svcDef       = JsonUtils.jsonToObject(reader, 
RangerServiceDef.class);
         RangerServiceDefHelper svcDefHelper = new 
RangerServiceDefHelper(svcDef);
 
-        String rrnBucket = svcDefHelper.getRrnTemplate("bucket");
-        String rrnPath   = svcDefHelper.getRrnTemplate("path");
-
-        assertEquals("{bucket}", rrnBucket);
-        assertEquals("{bucket}/{path}", rrnPath);
+        assertEquals("bucket", svcDefHelper.getRrnTemplate("bucket"));
+        assertEquals("bucket/path", svcDefHelper.getRrnTemplate("path"));
     }
 
     RangerResourceDef createResourceDef(String name, String parent) {
diff --git 
a/authz-api/src/main/java/org/apache/ranger/authz/api/RangerAuthzApiErrorCode.java
 
b/authz-api/src/main/java/org/apache/ranger/authz/api/RangerAuthzApiErrorCode.java
index f289e3f55..cc7881d27 100644
--- 
a/authz-api/src/main/java/org/apache/ranger/authz/api/RangerAuthzApiErrorCode.java
+++ 
b/authz-api/src/main/java/org/apache/ranger/authz/api/RangerAuthzApiErrorCode.java
@@ -35,13 +35,11 @@ public enum RangerAuthzApiErrorCode implements 
RangerAuthzErrorCode {
     INVALID_REQUEST_PERMISSION_NOT_FOUND(400, "00-011", "{0}: permission not 
found"),
     INVALID_REQUEST_PERMISSIONS_EMPTY(400, "00-012", "permissions is empty. 
Nothing to authorize"),
     INVALID_REQUEST_SERVICE_NAME_OR_TYPE_MANDATORY(400, "00-013", "service 
name or service type is mandatory"),
-    INVALID_RESOURCE_TEMPLATE_UNEXPECTED_MARKER_AT(400, "00-014", "invalid 
resource template: {0}. Unexpected marker \"{1}\" at position {2}"),
+    INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE(400, "00-014", "invalid resource 
template - empty"),
 
     INVALID_RESOURCE_TYPE_NOT_VALID(400, "00-015", "invalid resource \"{0}\" - 
unknown type \"{1}\""),
     INVALID_RESOURCE_EMPTY_VALUE(400, "00-016", "invalid resource - empty"),
-    INVALID_RESOURCE_PREFIX_MISMATCH(400, "00-017", "invalid resource \"{0}\" 
- prefix \"{1}\" not found"),
-    INVALID_RESOURCE_SUFFIX_MISMATCH(400, "00-018", "invalid resource \"{0}\" 
- suffix \"{1}\" not found"),
-    INVALID_RESOURCE_VALUE(400, "00-019", "invalid resource \"{0}\" - does not 
match template \"{1}\"");
+    INVALID_RESOURCE_VALUE(400, "00-017", "invalid resource \"{0}\" - does not 
match template \"{1}\"");
 
     private static final String ERROR_CODE_MODULE_PREFIX = "AUTHZ";
 
diff --git 
a/authz-api/src/main/java/org/apache/ranger/authz/util/RangerResourceNameParser.java
 
b/authz-api/src/main/java/org/apache/ranger/authz/util/RangerResourceNameParser.java
new file mode 100644
index 000000000..5000a5a43
--- /dev/null
+++ 
b/authz-api/src/main/java/org/apache/ranger/authz/util/RangerResourceNameParser.java
@@ -0,0 +1,216 @@
+/*
+ * 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.ranger.authz.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.authz.api.RangerAuthzException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_EMPTY_VALUE;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_VALUE;
+
+public class RangerResourceNameParser {
+    private static final Logger LOG = 
LoggerFactory.getLogger(RangerResourceNameParser.class);
+
+    public static final char ESCAPE_CHAR    = '\\';
+    public static final char SEPARATOR_CHAR = '/';
+
+    private static final String   SEPARATOR_STRING  = 
String.valueOf(SEPARATOR_CHAR);
+    private static final String   ESCAPED_SEPARATOR = "\\\\" + 
SEPARATOR_STRING;
+    private static final Pattern  SEPARATOR_PATTERN = 
Pattern.compile(SEPARATOR_STRING);
+    private static final String[] EMPTY_ARRAY       = new String[0];
+
+    private final String   template;   // examples: database/table/column, 
bucket/volume/path
+    private final String[] resources;  // examples: [database, table, column], 
  [bucket, volume, path]
+
+    public RangerResourceNameParser(String template) throws 
RangerAuthzException {
+        if (StringUtils.isBlank(template)) {
+            throw new 
RangerAuthzException(INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE);
+        }
+
+        this.template  = template;
+        this.resources = template.split(SEPARATOR_STRING); // assumption: '/' 
is not a valid character in resource names
+    }
+
+    public String getTemplate() {
+        return template;
+    }
+
+    public String getResourceType() {
+        return resources[resources.length - 1];
+    }
+
+    public int count() {
+        return resources.length;
+    }
+
+    public String resourceAt(int index) {
+        return resources[index];
+    }
+
+    public String[] parseToArray(final String resourceName) throws 
RangerAuthzException {
+        if (StringUtils.isBlank(resourceName)) {
+            throw new RangerAuthzException(INVALID_RESOURCE_EMPTY_VALUE);
+        }
+
+        final String[]      ret         = new String[resources.length];
+        final int           nameLen     = resourceName.length();
+        final StringBuilder token       = new StringBuilder();
+        int                 idxToken    = 0;
+        boolean             isLastToken = resources.length == 1;
+        boolean             isInEscape  = false;
+
+        for (int i = 0; i < nameLen; i++) {
+            char c = resourceName.charAt(i);
+
+            if (c == ESCAPE_CHAR) {
+                if (!isInEscape) {
+                    isInEscape = true;
+
+                    continue;
+                }
+            } else if (c == SEPARATOR_CHAR) {
+                if (!isInEscape) {
+                    if (!isLastToken) { // for last token, '/' is not a 
separator
+                        ret[idxToken++] = token.toString();
+
+                        token.setLength(0);
+
+                        isLastToken = idxToken == (resources.length - 1);
+
+                        continue;
+                    }
+                }
+            }
+
+            token.append(c);
+
+            isInEscape = false;
+        }
+
+        ret[idxToken] = token.toString();
+
+        if (!isLastToken) {
+            throw new RangerAuthzException(INVALID_RESOURCE_VALUE, 
resourceName, template);
+        }
+
+        LOG.debug("parseToArray(resource='{}', template='{}'): ret={}", 
resourceName, template, ret);
+
+        return ret;
+    }
+
+    public Map<String, String> parseToMap(final String resourceName) throws 
RangerAuthzException {
+        final String[]            arr = parseToArray(resourceName);
+        final Map<String, String> ret = new HashMap<>(arr.length);
+
+        for (int i = 0; i < arr.length; i++) {
+            ret.put(resources[i], arr[i]);
+        }
+
+        LOG.debug("parseToMap(resourceName='{}', template='{}'): ret={}", 
resourceName, template, ret);
+
+        return ret;
+    }
+
+    public String toResourceName(String[] values) {
+        StringBuilder ret = new StringBuilder();
+
+        if (values == null) {
+            values = EMPTY_ARRAY;
+        }
+
+        for (int i = 0; i < resources.length; i++) {
+            String  value  = values.length > i ? values[i] : null;
+            boolean isLast = i == (resources.length - 1);
+
+            if (value == null) {
+                value = "";
+            }
+
+            if (!isLast) { // escape '/' in all but the last resource
+                value = escapeIfNeeded(value);
+            }
+
+            if (i > 0) {
+                ret.append(SEPARATOR_CHAR);
+            }
+
+            ret.append(value);
+        }
+
+        LOG.debug("toResourceName(values={}, template='{}'): ret='{}'", 
values, template, ret);
+
+        return ret.toString();
+    }
+
+    public String toResourceName(Map<String, String> values) {
+        StringBuilder ret = new StringBuilder();
+
+        if (values == null) {
+            values = Collections.emptyMap();
+        }
+
+        for (int i = 0; i < resources.length; i++) {
+            String  value  = values.get(resources[i]);
+            boolean isLast = i == (resources.length - 1);
+
+            if (value == null) {
+                value = "";
+            }
+
+            if (!isLast) { // escape '/' in all but the last resource
+                value = escapeIfNeeded(value);
+            }
+
+            if (i > 0) {
+                ret.append(SEPARATOR_CHAR);
+            }
+
+            ret.append(value);
+        }
+
+        LOG.debug("toResourceName(values={}, template='{}'): ret='{}'", 
values, template, ret);
+
+        return ret.toString();
+    }
+
+    @Override
+    public String toString() {
+        return "RangerResourceTemplate{" +
+                "template=" + template +
+                ", resources='" + String.join(SEPARATOR_STRING, resources) + 
"'" +
+                "}";
+    }
+
+    private String escapeIfNeeded(String value) {
+        if (value.contains(SEPARATOR_STRING)) {
+            return 
SEPARATOR_PATTERN.matcher(value).replaceAll(ESCAPED_SEPARATOR);
+        } else {
+            return value;
+        }
+    }
+}
diff --git 
a/authz-api/src/main/java/org/apache/ranger/authz/util/RangerResourceTemplate.java
 
b/authz-api/src/main/java/org/apache/ranger/authz/util/RangerResourceTemplate.java
deleted file mode 100644
index a32e9c6c5..000000000
--- 
a/authz-api/src/main/java/org/apache/ranger/authz/util/RangerResourceTemplate.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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.ranger.authz.util;
-
-import org.apache.ranger.authz.api.RangerAuthzException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_EMPTY_VALUE;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_PREFIX_MISMATCH;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_SUFFIX_MISMATCH;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TEMPLATE_UNEXPECTED_MARKER_AT;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_VALUE;
-
-public class RangerResourceTemplate {
-    private static final Logger LOG = 
LoggerFactory.getLogger(RangerResourceTemplate.class);
-
-    private static final char RESOURCE_START_CHAR = '{';
-    private static final char RESOURCE_END_CHAR   = '}';
-    private static final char ESCAPE_CHAR         = '\\';
-
-    private final String   template;   // examples: 
{database}.{table}.{column}, ofs://{bucket}/{volume}/{path}
-    private final String[] resources;  // examples: [database, table, column], 
  [bucket, volume, path]
-    private final String   prefix;     // examples: "",                        
  "ofs://"
-    private final String[] separators; // examples: [".", "."],                
  ["/", "/"]
-    private final String   suffix;
-
-    public RangerResourceTemplate(String template) throws RangerAuthzException 
{
-        List<String>  resources    = new ArrayList<>();
-        List<String>  separators   = new ArrayList<>();
-        String        prefix       = null;
-        boolean       isInEscape   = false;
-        boolean       isInResource = false;
-        StringBuilder currentToken = new StringBuilder();
-
-        for (int i = 0; i < template.length(); i++) {
-            char c = template.charAt(i);
-
-            if (isInEscape) {
-                currentToken.append(c);
-
-                isInEscape = false;
-            } else if (c == ESCAPE_CHAR) {
-                isInEscape = true;
-            } else if (c == RESOURCE_START_CHAR) {
-                if (isInResource) {
-                    throw new 
RangerAuthzException(INVALID_RESOURCE_TEMPLATE_UNEXPECTED_MARKER_AT, template, 
RESOURCE_START_CHAR, i);
-                }
-
-                if (prefix == null) {
-                    prefix = currentToken.toString();
-                } else {
-                    separators.add(currentToken.toString());
-                }
-
-                isInResource = true;
-
-                currentToken.setLength(0);
-            } else if (c == RESOURCE_END_CHAR) {
-                if (!isInResource) {
-                    throw new 
RangerAuthzException(INVALID_RESOURCE_TEMPLATE_UNEXPECTED_MARKER_AT, template, 
RESOURCE_END_CHAR, i);
-                }
-
-                resources.add(currentToken.toString());
-
-                isInResource = false;
-
-                currentToken.setLength(0);
-            } else {
-                currentToken.append(c);
-            }
-        }
-
-        this.template   = template;
-        this.resources  = resources.toArray(new String[0]);
-        this.separators = separators.toArray(new String[0]);
-        this.prefix     = prefix;
-        this.suffix     = currentToken.toString();
-    }
-
-    public String getTemplate() {
-        return template;
-    }
-
-    public Map<String, String> parse(String resource) throws 
RangerAuthzException {
-        Map<String, String> ret = null;
-
-        if (resource == null || resource.isEmpty()) {
-            throw new RangerAuthzException(INVALID_RESOURCE_EMPTY_VALUE);
-        } else if (!resource.startsWith(prefix)) {
-            throw new RangerAuthzException(INVALID_RESOURCE_PREFIX_MISMATCH, 
resource, prefix);
-        } else if (!resource.endsWith(suffix)) {
-            throw new RangerAuthzException(INVALID_RESOURCE_SUFFIX_MISMATCH, 
resource, suffix);
-        } else {
-            ret = new HashMap<>();
-
-            int tokenStartPos = prefix.length();
-
-            for (int i = 0; i < this.separators.length; i++) {
-                String sep    = this.separators[i];
-                int    idxSep = resource.indexOf(sep, tokenStartPos);
-
-                LOG.debug("Separator '{}' found at {}: tokenStartPos={}", sep, 
idxSep, tokenStartPos);
-
-                if (idxSep == -1) {
-                    ret = null;
-
-                    break;
-                } else {
-                    String value = resource.substring(tokenStartPos, idxSep);
-
-                    ret.put(this.resources[i], value);
-                }
-
-                tokenStartPos = idxSep + sep.length();
-            }
-
-            if (ret != null && tokenStartPos != -1) {
-                String name  = this.resources[this.resources.length - 1];
-                String value = resource.substring(tokenStartPos, 
resource.length() - suffix.length());
-
-                ret.put(name, value);
-            }
-        }
-
-        if (ret == null || ret.size() != resources.length) {
-            throw new RangerAuthzException(INVALID_RESOURCE_VALUE, resource, 
template);
-        }
-
-        LOG.debug("parse(resource='{}', template='{}'): ret={}", resource, 
template, ret);
-
-        return ret;
-    }
-
-    public String formatResource(Map<String, String> resourceMap) {
-        StringBuilder ret = new StringBuilder(prefix);
-
-        for (int i = 0; i < resources.length; i++) {
-            String name  = resources[i];
-            String value = resourceMap.get(name);
-
-            if (value == null) {
-                value = "";
-            }
-
-            ret.append(value);
-
-            if (i < separators.length) {
-                ret.append(separators[i]);
-            }
-        }
-
-        ret.append(suffix);
-
-        LOG.debug("createResource(resourceMap={}, template='{}'): ret='{}'", 
resourceMap, template, ret);
-
-        return ret.toString();
-    }
-
-    @Override
-    public String toString() {
-        return "RangerResourceTemplate{" +
-                "template=" + template +
-                ", resources='" + String.join(",", resources) + "'" +
-                ", prefix='" + prefix + "'" +
-                ", separators='" + String.join(",", separators) + "'" +
-                ", suffix='" + suffix + "'" +
-                "}";
-    }
-}
diff --git 
a/authz-api/src/test/java/org/apache/ranger/authz/api/TestAuthzApiErrorCode.java
 
b/authz-api/src/test/java/org/apache/ranger/authz/api/TestAuthzApiErrorCode.java
index 441f1c36f..77c92e783 100644
--- 
a/authz-api/src/test/java/org/apache/ranger/authz/api/TestAuthzApiErrorCode.java
+++ 
b/authz-api/src/test/java/org/apache/ranger/authz/api/TestAuthzApiErrorCode.java
@@ -36,7 +36,7 @@
 import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_REQUEST_SERVICE_NOT_FOUND;
 import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_REQUEST_SERVICE_TYPE_NOT_FOUND;
 import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_REQUEST_USER_INFO_MISSING;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TEMPLATE_UNEXPECTED_MARKER_AT;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE;
 import static 
org.apache.ranger.authz.model.RangerResourceInfo.ResourceMatchScope.SELF;
 import static 
org.apache.ranger.authz.model.RangerResourceInfo.ResourceMatchScope.SELF_OR_ANY_CHILD;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -59,12 +59,10 @@ public void testAuthzApiErrorCodeMessages() {
         assertEquals("AUTHZ-400-00-011: mypermission: permission not found", 
INVALID_REQUEST_PERMISSION_NOT_FOUND.getFormattedMessage("mypermission"));
         assertEquals("AUTHZ-400-00-012: permissions is empty. Nothing to 
authorize", INVALID_REQUEST_PERMISSIONS_EMPTY.getFormattedMessage());
         assertEquals("AUTHZ-400-00-013: service name or service type is 
mandatory", 
INVALID_REQUEST_SERVICE_NAME_OR_TYPE_MANDATORY.getFormattedMessage());
-        assertEquals("AUTHZ-400-00-014: invalid resource template: 
{database}.{table}}. Unexpected marker \"}\" at position 18", 
INVALID_RESOURCE_TEMPLATE_UNEXPECTED_MARKER_AT.getFormattedMessage("{database}.{table}}",
 "}", 18));
+        assertEquals("AUTHZ-400-00-014: invalid resource template - empty", 
INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE.getFormattedMessage());
 
         assertEquals("AUTHZ-400-00-015: invalid resource \"mytype:myresource\" 
- unknown type \"mytype\"", 
RangerAuthzApiErrorCode.INVALID_RESOURCE_TYPE_NOT_VALID.getFormattedMessage("mytype:myresource",
 "mytype"));
         assertEquals("AUTHZ-400-00-016: invalid resource - empty", 
RangerAuthzApiErrorCode.INVALID_RESOURCE_EMPTY_VALUE.getFormattedMessage());
-        assertEquals("AUTHZ-400-00-017: invalid resource \"mytype:myresource\" 
- prefix \"myprefix\" not found", 
RangerAuthzApiErrorCode.INVALID_RESOURCE_PREFIX_MISMATCH.getFormattedMessage("mytype:myresource",
 "myprefix"));
-        assertEquals("AUTHZ-400-00-018: invalid resource \"mytype:myresource\" 
- suffix \"mysuffix\" not found", 
RangerAuthzApiErrorCode.INVALID_RESOURCE_SUFFIX_MISMATCH.getFormattedMessage("mytype:myresource",
 "mysuffix"));
-        assertEquals("AUTHZ-400-00-019: invalid resource \"mytype:myresource\" 
- does not match template \"{res1}.{res2}\"", 
RangerAuthzApiErrorCode.INVALID_RESOURCE_VALUE.getFormattedMessage("mytype:myresource",
 "{res1}.{res2}"));
+        assertEquals("AUTHZ-400-00-017: invalid resource \"mytype:myresource\" 
- does not match template \"{res1}/{res2}\"", 
RangerAuthzApiErrorCode.INVALID_RESOURCE_VALUE.getFormattedMessage("mytype:myresource",
 "{res1}/{res2}"));
     }
 }
diff --git 
a/authz-api/src/test/java/org/apache/ranger/authz/api/TestAuthzException.java 
b/authz-api/src/test/java/org/apache/ranger/authz/api/TestAuthzException.java
index 59529371a..5aabe3631 100644
--- 
a/authz-api/src/test/java/org/apache/ranger/authz/api/TestAuthzException.java
+++ 
b/authz-api/src/test/java/org/apache/ranger/authz/api/TestAuthzException.java
@@ -37,9 +37,7 @@
 import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_REQUEST_SERVICE_TYPE_NOT_FOUND;
 import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_REQUEST_USER_INFO_MISSING;
 import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_EMPTY_VALUE;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_PREFIX_MISMATCH;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_SUFFIX_MISMATCH;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TEMPLATE_UNEXPECTED_MARKER_AT;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE;
 import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TYPE_NOT_VALID;
 import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_VALUE;
 import static 
org.apache.ranger.authz.model.RangerResourceInfo.ResourceMatchScope.SELF;
@@ -64,12 +62,10 @@ public void testAuthzApiExceptionMessage() {
         assertEquals("AUTHZ-400-00-011: mypermission: permission not found", 
new RangerAuthzException(INVALID_REQUEST_PERMISSION_NOT_FOUND, 
"mypermission").getMessage());
         assertEquals("AUTHZ-400-00-012: permissions is empty. Nothing to 
authorize", new 
RangerAuthzException(INVALID_REQUEST_PERMISSIONS_EMPTY).getMessage());
         assertEquals("AUTHZ-400-00-013: service name or service type is 
mandatory", new 
RangerAuthzException(INVALID_REQUEST_SERVICE_NAME_OR_TYPE_MANDATORY).getMessage());
-        assertEquals("AUTHZ-400-00-014: invalid resource template: 
{database}.{table}}. Unexpected marker \"}\" at position 18", new 
RangerAuthzException(INVALID_RESOURCE_TEMPLATE_UNEXPECTED_MARKER_AT, 
"{database}.{table}}", "}", 18).getMessage());
+        assertEquals("AUTHZ-400-00-014: invalid resource template - empty", 
new RangerAuthzException(INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE).getMessage());
 
         assertEquals("AUTHZ-400-00-015: invalid resource \"mytype:myresource\" 
- unknown type \"mytype\"", new 
RangerAuthzException(INVALID_RESOURCE_TYPE_NOT_VALID, "mytype:myresource", 
"mytype").getMessage());
         assertEquals("AUTHZ-400-00-016: invalid resource - empty", new 
RangerAuthzException(INVALID_RESOURCE_EMPTY_VALUE).getMessage());
-        assertEquals("AUTHZ-400-00-017: invalid resource \"mytype:myresource\" 
- prefix \"myprefix\" not found", new 
RangerAuthzException(INVALID_RESOURCE_PREFIX_MISMATCH, "mytype:myresource", 
"myprefix").getMessage());
-        assertEquals("AUTHZ-400-00-018: invalid resource \"mytype:myresource\" 
- suffix \"mysuffix\" not found", new 
RangerAuthzException(INVALID_RESOURCE_SUFFIX_MISMATCH, "mytype:myresource", 
"mysuffix").getMessage());
-        assertEquals("AUTHZ-400-00-019: invalid resource \"mytype:myresource\" 
- does not match template \"{res1}.{res2}\"", new 
RangerAuthzException(INVALID_RESOURCE_VALUE, "mytype:myresource", 
"{res1}.{res2}").getMessage());
+        assertEquals("AUTHZ-400-00-017: invalid resource \"mytype:myresource\" 
- does not match template \"{res1}/{res2}\"", new 
RangerAuthzException(INVALID_RESOURCE_VALUE, "mytype:myresource", 
"{res1}/{res2}").getMessage());
     }
 }
diff --git 
a/authz-api/src/test/java/org/apache/ranger/authz/util/TestRangerResourceNameParser.java
 
b/authz-api/src/test/java/org/apache/ranger/authz/util/TestRangerResourceNameParser.java
new file mode 100644
index 000000000..8c137203b
--- /dev/null
+++ 
b/authz-api/src/test/java/org/apache/ranger/authz/util/TestRangerResourceNameParser.java
@@ -0,0 +1,406 @@
+/*
+ * 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.ranger.authz.util;
+
+import org.apache.ranger.authz.api.RangerAuthzErrorCode;
+import org.apache.ranger.authz.api.RangerAuthzException;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_EMPTY_VALUE;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TYPE_NOT_VALID;
+import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_VALUE;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
+
+public class TestRangerResourceNameParser {
+    @Test
+    public void testValidTemplates() throws Exception {
+        Object[][] testData = {
+                {"database", "database", 1, "database"},
+                {"database/table", "table", 2, "database", "table"},
+                {"database/table/column", "column", 3, "database", "table", 
"column"},
+                {"bucket", "bucket", 1, "bucket"},
+                {"bucket/path", "path", 2, "bucket", "path"},
+                {"storageaccount", "storageaccount", 1, "storageaccount"},
+                {"storageaccount/container", "container", 2, "storageaccount", 
"container"},
+                {"storageaccount/container/relativepath", "relativepath", 3, 
"storageaccount", "container", "relativepath"},
+                {"catalog", "catalog", 1, "catalog"},
+                {"catalog/schema", "schema", 2, "catalog", "schema"},
+                {"catalog/schema/table", "table", 3, "catalog", "schema", 
"table"},
+                {"catalog/schema/table/column", "column", 4, "catalog", 
"schema", "table", "column"},
+                {"catalog/schema/procedure", "procedure", 3, "catalog", 
"schema", "procedure"},
+                {"catalog/schema/schemafunction", "schemafunction", 3, 
"catalog", "schema", "schemafunction"},
+                {"catalog/sessionproperty", "sessionproperty", 2, "catalog", 
"sessionproperty"},
+        };
+
+        for (Object[] test : testData) {
+            String                   template         = (String) test[0];
+            String                   resourceType     = (String) test[1];
+            int                      resourceCount    = (Integer) test[2];
+            RangerResourceNameParser resourceTemplate = new 
RangerResourceNameParser(template);
+
+            assertEquals(resourceType, resourceTemplate.getResourceType(), 
template);
+            assertEquals(resourceCount, resourceTemplate.count(), template);
+            assertEquals(template, resourceTemplate.getTemplate(), template);
+
+            for (int i = 0; i < resourceCount; i++) {
+                assertEquals(test[i + 3], resourceTemplate.resourceAt(i), 
template + " at " + i);
+            }
+        }
+    }
+
+    @Test
+    public void testInvalidTemplates() throws Exception {
+        String[] templates = {
+                null,
+                "",
+                "  ",
+        };
+
+        for (String template : templates) {
+            RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> new 
RangerResourceNameParser(template), template);
+
+            assertEquals(INVALID_RESOURCE_TEMPLATE_EMPTY_VALUE.getCode(), 
excp.getErrorCode().getCode(), template);
+        }
+    }
+
+    @Test
+    public void testParseHiveResources() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getHiveTemplates();
+
+        TestData[] tests = {
+                new TestData("database:db1", "database", "db1"),
+                new TestData("database:db1/", "database", "db1/"),
+                new TestData("table:db1/tbl1", "database", "db1", "table", 
"tbl1"),
+                new TestData("table:db\\/1/tbl1", "database", "db/1", "table", 
"tbl1"), // escape '/' in database name "db/1"
+                new TestData("column:db1/tbl1/col1", "database", "db1", 
"table", "tbl1", "column", "col1"),
+                new TestData("column:db1//col1", "database", "db1", "table", 
"", "column", "col1"), // empty table name
+                new TestData("column:db1//", "database", "db1", "table", "", 
"column", ""), // empty table and column names
+                new TestData("column://", "database", "", "table", "", 
"column", ""), // empty database, table and column names
+                new TestData("udf:db1/myUDF", "database", "db1", "udf", 
"myUDF"),
+                new TestData("url:s3a://mybucket/db1/tbl1", "url", 
"s3a://mybucket/db1/tbl1"),
+                new TestData("hiveservice:server1", "hiveservice", "server1"),
+                new TestData("global:*", "global", "*"),
+                // invalid values
+                new TestData("db1/tbl1/col1", 
INVALID_RESOURCE_TYPE_NOT_VALID),                     // no resource-type
+                new TestData(":db1/tbl1/col1", 
INVALID_RESOURCE_TYPE_NOT_VALID),                    // empty resource-type
+                new TestData("invalidResourceType:db1/tbl1/col1", 
INVALID_RESOURCE_TYPE_NOT_VALID), // unknown resource-type
+                new TestData("database:", INVALID_RESOURCE_EMPTY_VALUE),
+                new TestData("table:db1_tbl1", INVALID_RESOURCE_VALUE),
+                new TestData("column:db1_tbl1/col1", INVALID_RESOURCE_VALUE),
+                new TestData("udf:db1_myUDF", INVALID_RESOURCE_VALUE),
+        };
+
+        for (TestData test : tests) {
+            if (test.errorCode != null) {
+                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> parseToMap(test.resource, 
templates), test.resource);
+
+                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
+            } else {
+                assertEquals(test.expected, parseToMap(test.resource, 
templates), test.resource);
+            }
+        }
+    }
+
+    @Test
+    public void testParseS3Resources() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getS3Templates();
+
+        TestData[] tests = {
+                new TestData("bucket:mybucket", "bucket", "mybucket"),
+                new TestData("path:mybucket/myfolder/myfile.txt", "bucket", 
"mybucket", "path", "myfolder/myfile.txt"),    // no escape needed for '/' in 
the last resource
+                new TestData("path:mybucket/myfolder\\/myfile.txt", "bucket", 
"mybucket", "path", "myfolder/myfile.txt"),  // escape in the last resource 
should be ignored
+                new TestData("path:mybucket/\\/myfolder/myfile.txt", "bucket", 
"mybucket", "path", "/myfolder/myfile.txt"), // escape in the last resource 
should be ignored
+                new TestData("path:mybucket/", "bucket", "mybucket", "path", 
""),
+                // invalid values
+                new TestData("mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID),                     // no resource-type
+                new TestData(":mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID),                    // empty resource-type
+                new 
TestData("invalidResourceType:mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID), // unknown resource-type
+                new TestData("bucket:", INVALID_RESOURCE_EMPTY_VALUE),
+                new TestData("path:mybucket_myfolder_myfile.txt", 
INVALID_RESOURCE_VALUE),
+        };
+
+        for (TestData test : tests) {
+            if (test.errorCode != null) {
+                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> parseToMap(test.resource, 
templates), test.resource);
+
+                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
+            } else {
+                assertEquals(test.expected, parseToMap(test.resource, 
templates), test.resource);
+            }
+        }
+    }
+
+    @Test
+    public void testParseAdlsGen2Resources() throws Exception {
+        Map<String, RangerResourceNameParser> templates = 
getAdlsGen2Templates();
+
+        TestData[] tests = {
+                new TestData("container:myaccount/mycontainer", 
"storageaccount", "myaccount", "container", "mycontainer"),
+                new 
TestData("relativepath:myaccount/mycontainer/p1/p2/f1.txt", "storageaccount", 
"myaccount", "container", "mycontainer", "relativepath", "p1/p2/f1.txt"),
+        };
+
+        for (TestData test : tests) {
+            if (test.errorCode != null) {
+                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> parseToMap(test.resource, 
templates), test.resource);
+
+                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
+            } else {
+                assertEquals(test.expected, parseToMap(test.resource, 
templates), test.resource);
+            }
+        }
+    }
+
+    @Test
+    public void testParseTrinoResources() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getTrinoTemplates();
+
+        TestData[] tests = {
+                new TestData("catalog:mycatalog", "catalog", "mycatalog"),
+                new TestData("schema:mycatalog/myschema", "catalog", 
"mycatalog", "schema", "myschema"),
+                new TestData("table:mycatalog/myschema/mytable", "catalog", 
"mycatalog", "schema", "myschema", "table", "mytable"),
+                new TestData("column:mycatalog/myschema/mytable/mycolumn", 
"catalog", "mycatalog", "schema", "myschema", "table", "mytable", "column", 
"mycolumn"),
+                new TestData("trinouser:myuser", "trinouser", "myuser"),
+                new TestData("systemproperty:myproperty", "systemproperty", 
"myproperty"),
+                new TestData("sessionproperty:mycatalog/mysessionproperty", 
"catalog", "mycatalog", "sessionproperty", "mysessionproperty"),
+                new TestData("function:myfunction", "function", "myfunction"),
+                new TestData("procedure:mycatalog/myschema/myprocedure", 
"catalog", "mycatalog", "schema", "myschema", "procedure", "myprocedure"),
+                new 
TestData("schemafunction:mycatalog/myschema/myschemafunction", "catalog", 
"mycatalog", "schema", "myschema", "schemafunction", "myschemafunction"),
+                new 
TestData("queryid:12345-67890-abcdefg-hijklmnopqrs-tuvwxyz", "queryid", 
"12345-67890-abcdefg-hijklmnopqrs-tuvwxyz"),
+                new TestData("sysinfo:systeminfo", "sysinfo", "systeminfo"),
+                new TestData("role:myrole", "role", "myrole"),
+                // invalid values
+                new TestData("mycatalog/myschema/mytable/mycolumn", 
INVALID_RESOURCE_TYPE_NOT_VALID),                     // no resource-type
+                new TestData(":mycatalog/myschema/mytable/mycolumn", 
INVALID_RESOURCE_TYPE_NOT_VALID),                    // empty resource-type
+                new 
TestData("invalidResourceType:mycatalog/myschema/mytable/mycolumn", 
INVALID_RESOURCE_TYPE_NOT_VALID), // unknown resource-type
+                new TestData("catalog:", INVALID_RESOURCE_EMPTY_VALUE),
+                new TestData("schema:mycatalog_myschema", 
INVALID_RESOURCE_VALUE),
+                new TestData("table:mycatalog_myschema_mytable", 
INVALID_RESOURCE_VALUE),
+                new TestData("column:mycatalog_myschema_mytable_mycolumn", 
INVALID_RESOURCE_VALUE),
+                new TestData("trinouser:", INVALID_RESOURCE_EMPTY_VALUE),
+                new TestData("sessionproperty:mycatalog_mysessionproperty", 
INVALID_RESOURCE_VALUE),
+                new TestData("procedure:mycatalog_myschema_myprocedure", 
INVALID_RESOURCE_VALUE),
+        };
+
+        for (TestData test : tests) {
+            if (test.errorCode != null) {
+                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> parseToMap(test.resource, 
templates), test.resource);
+
+                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
+            } else {
+                assertEquals(test.expected, parseToMap(test.resource, 
templates), test.resource);
+            }
+        }
+    }
+
+    @Test
+    public void testResourceNameFromMapHive() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getHiveTemplates();
+
+        assertEquals("db1", 
templates.get("database").toResourceName(toMap("database", "db1")));
+        assertEquals("db1/tbl1", 
templates.get("table").toResourceName(toMap("database", "db1", "table", 
"tbl1")));
+        assertEquals("db1/tbl1/col1", 
templates.get("column").toResourceName(toMap("database", "db1", "table", 
"tbl1", "column", "col1")));
+        assertEquals("db1/myUDF", 
templates.get("udf").toResourceName(toMap("database", "db1", "udf", "myUDF")));
+        assertEquals("s3a://mybucket/db1/tbl1", 
templates.get("url").toResourceName(toMap("url", "s3a://mybucket/db1/tbl1")));
+        assertEquals("server1", 
templates.get("hiveservice").toResourceName(toMap("hiveservice", "server1")));
+        assertEquals("*", 
templates.get("global").toResourceName(toMap("global", "*")));
+        assertEquals("db1/tbl\\/1/col1", 
templates.get("column").toResourceName(toMap("database", "db1", "table", 
"tbl/1", "column", "col1")));
+        assertEquals("db1/tbl\\/1/col/1", 
templates.get("column").toResourceName(toMap("database", "db1", "table", 
"tbl/1", "column", "col/1")));
+
+        // validate missing entries in map
+        assertEquals("", templates.get("database").toResourceName((Map<String, 
String>) null));
+        assertEquals("", 
templates.get("database").toResourceName(Collections.emptyMap()));
+        assertEquals("/", templates.get("table").toResourceName((Map<String, 
String>) null));
+        assertEquals("/", 
templates.get("table").toResourceName(Collections.emptyMap()));
+        assertEquals("/tbl1", 
templates.get("table").toResourceName(toMap("table", "tbl1"))); // missing 
database name
+        assertEquals("db1/", 
templates.get("table").toResourceName(toMap("database", "db1"))); // missing 
table name
+        assertEquals("//", templates.get("column").toResourceName((Map<String, 
String>) null)); // null map
+        assertEquals("//", 
templates.get("column").toResourceName(Collections.emptyMap())); // empty map
+        assertEquals("/tbl1/col1", 
templates.get("column").toResourceName(toMap("table", "tbl1", "column", 
"col1"))); // missing database name
+        assertEquals("db1//col1", 
templates.get("column").toResourceName(toMap("database", "db1", "column", 
"col1"))); // missing table name
+        assertEquals("db1/tbl1/", 
templates.get("column").toResourceName(toMap("database", "db1", "table", 
"tbl1"))); // missing column name
+        assertEquals("//", 
templates.get("column").toResourceName(toMap("database", null, "table", 
null))); // all names  null or missing
+
+        // validate unknown entries in map
+        assertEquals("db1", 
templates.get("database").toResourceName(toMap("database", "db1", "unknown", 
"ignore")));
+    }
+
+    @Test
+    public void testResourceNameFromMapS3() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getS3Templates();
+
+        assertEquals("mybucket", 
templates.get("bucket").toResourceName(toMap("bucket", "mybucket")));
+        assertEquals("mybucket/myfolder/myfile.txt", 
templates.get("path").toResourceName(toMap("bucket", "mybucket", "path", 
"myfolder/myfile.txt")));
+        assertEquals("mybucket//myfolder/myfile.txt", 
templates.get("path").toResourceName(toMap("bucket", "mybucket", "path", 
"/myfolder/myfile.txt")));
+    }
+
+    @Test
+    public void testResourceNameFromArrayHive() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getHiveTemplates();
+
+        assertEquals("db1", 
templates.get("database").toResourceName(toArray("db1")));
+        assertEquals("db1/tbl1", 
templates.get("table").toResourceName(toArray("db1", "tbl1")));
+        assertEquals("db1/tbl1/col1", 
templates.get("column").toResourceName(toArray("db1", "tbl1", "col1")));
+        assertEquals("db1/myUDF", 
templates.get("udf").toResourceName(toArray("db1", "myUDF")));
+        assertEquals("s3a://mybucket/db1/tbl1", 
templates.get("url").toResourceName(toArray("s3a://mybucket/db1/tbl1")));
+        assertEquals("server1", 
templates.get("hiveservice").toResourceName(toArray("server1")));
+        assertEquals("*", 
templates.get("global").toResourceName(toArray("*")));
+        assertEquals("db1/tbl\\/1/col1", 
templates.get("column").toResourceName(toArray("db1", "tbl/1", "col1")));
+        assertEquals("db1/tbl\\/1/col/1", 
templates.get("column").toResourceName(toArray("db1", "tbl/1", "col/1")));
+
+        // validate null or missing entries in array
+        assertEquals("", templates.get("database").toResourceName((Map<String, 
String>) null));
+        assertEquals("", 
templates.get("database").toResourceName(Collections.emptyMap()));
+        assertEquals("/", templates.get("table").toResourceName((Map<String, 
String>) null));
+        assertEquals("/", 
templates.get("table").toResourceName(Collections.emptyMap()));
+        assertEquals("/tbl1", 
templates.get("table").toResourceName(toArray(null, "tbl1"))); // null database 
name
+        assertEquals("db1/", 
templates.get("table").toResourceName(toArray("db1"))); // missing table name
+        assertEquals("//", templates.get("column").toResourceName((String[]) 
null)); // null array
+        assertEquals("//", templates.get("column").toResourceName(new 
String[0])); // empty array
+        assertEquals("/tbl1/col1", 
templates.get("column").toResourceName(toArray(null, "tbl1", "col1"))); // null 
database name
+        assertEquals("db1//col1", 
templates.get("column").toResourceName(toArray("db1", null, "col1"))); // null 
table name
+        assertEquals("db1/tbl1/", 
templates.get("column").toResourceName(toArray("db1", "tbl1", null))); // null 
column name
+        assertEquals("db1/tbl1/", 
templates.get("column").toResourceName(toArray("db1", "tbl1"))); // missing 
column name
+
+        // validate unknown entries in map
+        assertEquals("db1", 
templates.get("database").toResourceName(toArray("db1", "ignore")));
+    }
+
+    @Test
+    public void testResourceNameFromArrayS3() throws Exception {
+        Map<String, RangerResourceNameParser> templates = getS3Templates();
+
+        assertEquals("mybucket", 
templates.get("bucket").toResourceName(toArray("mybucket")));
+        assertEquals("mybucket/myfolder/myfile.txt", 
templates.get("path").toResourceName(toArray("mybucket", 
"myfolder/myfile.txt")));
+        assertEquals("mybucket//myfolder/myfile.txt", 
templates.get("path").toResourceName(toArray("mybucket", 
"/myfolder/myfile.txt")));
+    }
+
+    private static Map<String, RangerResourceNameParser> getHiveTemplates() 
throws Exception {
+        Map<String, RangerResourceNameParser> ret = new HashMap<>();
+
+        ret.put("database", new RangerResourceNameParser("database"));
+        ret.put("table", new RangerResourceNameParser("database/table"));
+        ret.put("column", new 
RangerResourceNameParser("database/table/column"));
+        ret.put("udf", new RangerResourceNameParser("database/udf"));
+        ret.put("url", new RangerResourceNameParser("url"));
+        ret.put("hiveservice", new RangerResourceNameParser("hiveservice"));
+        ret.put("global", new RangerResourceNameParser("global"));
+
+        return ret;
+    }
+
+    private static Map<String, RangerResourceNameParser> getS3Templates() 
throws Exception {
+        Map<String, RangerResourceNameParser> ret = new HashMap<>();
+
+        ret.put("bucket", new RangerResourceNameParser("bucket"));
+        ret.put("path", new RangerResourceNameParser("bucket/path"));
+
+        return ret;
+    }
+
+    private static Map<String, RangerResourceNameParser> 
getAdlsGen2Templates() throws Exception {
+        Map<String, RangerResourceNameParser> ret = new HashMap<>();
+
+        ret.put("container", new 
RangerResourceNameParser("storageaccount/container"));
+        ret.put("relativepath", new 
RangerResourceNameParser("storageaccount/container/relativepath"));
+
+        return ret;
+    }
+
+    private static Map<String, RangerResourceNameParser> getTrinoTemplates() 
throws Exception {
+        Map<String, RangerResourceNameParser> ret = new HashMap<>();
+
+        ret.put("catalog", new RangerResourceNameParser("catalog"));
+        ret.put("schema", new RangerResourceNameParser("catalog/schema"));
+        ret.put("table", new RangerResourceNameParser("catalog/schema/table"));
+        ret.put("column", new 
RangerResourceNameParser("catalog/schema/table/column"));
+        ret.put("trinouser", new RangerResourceNameParser("trinouser"));
+        ret.put("systemproperty", new 
RangerResourceNameParser("systemproperty"));
+        ret.put("sessionproperty", new 
RangerResourceNameParser("catalog/sessionproperty"));
+        ret.put("function", new RangerResourceNameParser("function"));
+        ret.put("procedure", new 
RangerResourceNameParser("catalog/schema/procedure"));
+        ret.put("schemafunction", new 
RangerResourceNameParser("catalog/schema/schemafunction"));
+        ret.put("queryid", new RangerResourceNameParser("queryid"));
+        ret.put("sysinfo", new RangerResourceNameParser("sysinfo"));
+        ret.put("role", new RangerResourceNameParser("role"));
+
+        return ret;
+    }
+
+    private Map<String, String> parseToMap(String resource, Map<String, 
RangerResourceNameParser> templates) throws RangerAuthzException {
+        String[]                 resourceParts = resource.split(":", 2);
+        String                   resourceType  = resourceParts.length > 0 ? 
resourceParts[0] : null;
+        String                   resourceValue = resourceParts.length > 1 ? 
resourceParts[1] : null;
+        RangerResourceNameParser template      = templates.get(resourceType);
+
+        if (template == null) {
+            throw new RangerAuthzException(INVALID_RESOURCE_TYPE_NOT_VALID, 
resourceType);
+        }
+
+        return template.parseToMap(resourceValue);
+    }
+
+    private static class TestData {
+        public final String               resource;
+        public final Map<String, String>  expected;
+        public final RangerAuthzErrorCode errorCode;
+
+        public TestData(String resource, String...values) {
+            this.resource = resource;
+
+            if (values.length > 1) {
+                this.expected  = new HashMap<>();
+                this.errorCode = null;
+
+                for (int i = 1; i < values.length; i += 2) {
+                    expected.put(values[i - 1], values[i]);
+                }
+            } else {
+                this.expected  = null;
+                this.errorCode = null;
+            }
+        }
+
+        public TestData(String resource, RangerAuthzErrorCode errorCode) {
+            this.resource  = resource;
+            this.expected  = null;
+            this.errorCode = errorCode;
+        }
+    }
+
+    private static Map<String, String> toMap(String... values) {
+        Map<String, String> ret = new HashMap<>();
+
+        for (int i = 1; i < values.length; i += 2) {
+            ret.put(values[i - 1], values[i]);
+        }
+
+        return ret;
+    }
+
+    private static String[] toArray(String... values) {
+        return values;
+    }
+}
diff --git 
a/authz-api/src/test/java/org/apache/ranger/authz/util/TestResourceTemplate.java
 
b/authz-api/src/test/java/org/apache/ranger/authz/util/TestResourceTemplate.java
deleted file mode 100644
index 704fd77e9..000000000
--- 
a/authz-api/src/test/java/org/apache/ranger/authz/util/TestResourceTemplate.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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.ranger.authz.util;
-
-import org.apache.ranger.authz.api.RangerAuthzErrorCode;
-import org.apache.ranger.authz.api.RangerAuthzException;
-import org.junit.jupiter.api.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_EMPTY_VALUE;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_TYPE_NOT_VALID;
-import static 
org.apache.ranger.authz.api.RangerAuthzApiErrorCode.INVALID_RESOURCE_VALUE;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
-
-public class TestResourceTemplate {
-    @Test
-    public void testHiveResources() throws Exception {
-        Map<String, RangerResourceTemplate> templates = getHiveTemplates();
-
-        TestData[] tests = {
-                new TestData("database:db1", "database", "db1"),
-                new TestData("table:db1.tbl1", "database", "db1", "table", 
"tbl1"),
-                new TestData("column:db1.tbl1.col1", "database", "db1", 
"table", "tbl1", "column", "col1"),
-                new TestData("udf:db1.myUDF", "database", "db1", "udf", 
"myUDF"),
-                new TestData("url:s3a://mybucket/db1/tbl1", "url", 
"s3a://mybucket/db1/tbl1"),
-                new TestData("hiveservice:server1", "hiveservice", "server1"),
-                new TestData("global:*", "global", "*"),
-                // invalid values
-                new TestData("db1.tbl1.col1", 
INVALID_RESOURCE_TYPE_NOT_VALID),                     // no resource-type
-                new TestData(":db1.tbl1.col1", 
INVALID_RESOURCE_TYPE_NOT_VALID),                    // empty resource-type
-                new TestData("invalidResourceType:db1.tbl1.col1", 
INVALID_RESOURCE_TYPE_NOT_VALID), // unknown resource-type
-                new TestData("database:", INVALID_RESOURCE_EMPTY_VALUE),
-                new TestData("table:db1_tbl1", INVALID_RESOURCE_VALUE),
-                new TestData("column:db1_tbl1.col1", INVALID_RESOURCE_VALUE),
-                new TestData("udf:db1_myUDF", INVALID_RESOURCE_VALUE),
-        };
-
-        for (TestData test : tests) {
-            if (test.errorCode != null) {
-                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> 
getResourceAsMap(test.resource, templates), test.resource);
-
-                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
-            } else {
-                assertEquals(test.expected, getResourceAsMap(test.resource, 
templates), test.resource);
-            }
-        }
-    }
-
-    @Test
-    public void testS3Resources() throws Exception {
-        Map<String, RangerResourceTemplate> templates = getS3Templates();
-
-        TestData[] tests = {
-                new TestData("bucket:mybucket", "bucket", "mybucket"),
-                new TestData("path:mybucket/myfolder/myfile.txt", "bucket", 
"mybucket", "path", "myfolder/myfile.txt"),
-                new TestData("path:mybucket/", "bucket", "mybucket", "path", 
""),
-                // invalid values
-                new TestData("mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID),                     // no resource-type
-                new TestData(":mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID),                    // empty resource-type
-                new 
TestData("invalidResourceType:mybucket/myfolder/myfile.txt", 
INVALID_RESOURCE_TYPE_NOT_VALID), // unknown resource-type
-                new TestData("bucket:", INVALID_RESOURCE_EMPTY_VALUE),
-                new TestData("path:mybucket_myfolder_myfile.txt", 
INVALID_RESOURCE_VALUE),
-        };
-
-        for (TestData test : tests) {
-            if (test.errorCode != null) {
-                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> 
getResourceAsMap(test.resource, templates), test.resource);
-
-                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
-            } else {
-                assertEquals(test.expected, getResourceAsMap(test.resource, 
templates), test.resource);
-            }
-        }
-    }
-
-    @Test
-    public void testAdlsGen2Resources() throws Exception {
-        Map<String, RangerResourceTemplate> templates = getAdlsGen2Templates();
-
-        TestData[] tests = {
-                new TestData("container:mycontainer@myaccount", 
"storageaccount", "myaccount", "container", "mycontainer"),
-                new 
TestData("relativepath:mycontainer@myaccount/p1/p2/f1.txt", "storageaccount", 
"myaccount", "container", "mycontainer", "relativepath", "p1/p2/f1.txt"),
-        };
-
-        for (TestData test : tests) {
-            if (test.errorCode != null) {
-                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> 
getResourceAsMap(test.resource, templates), test.resource);
-
-                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
-            } else {
-                assertEquals(test.expected, getResourceAsMap(test.resource, 
templates), test.resource);
-            }
-        }
-    }
-
-    @Test
-    public void testTrinoResources() throws Exception {
-        Map<String, RangerResourceTemplate> templates = getTrinoTemplates();
-
-        TestData[] tests = {
-                new TestData("catalog:mycatalog", "catalog", "mycatalog"),
-                new TestData("schema:mycatalog.myschema", "catalog", 
"mycatalog", "schema", "myschema"),
-                new TestData("table:mycatalog.myschema.mytable", "catalog", 
"mycatalog", "schema", "myschema", "table", "mytable"),
-                new TestData("column:mycatalog.myschema.mytable.mycolumn", 
"catalog", "mycatalog", "schema", "myschema", "table", "mytable", "column", 
"mycolumn"),
-                new TestData("trinouser:myuser", "trinouser", "myuser"),
-                new TestData("systemproperty:myproperty", "systemproperty", 
"myproperty"),
-                new TestData("sessionproperty:mycatalog.mysessionproperty", 
"catalog", "mycatalog", "sessionproperty", "mysessionproperty"),
-                new TestData("function:myfunction", "function", "myfunction"),
-                new TestData("procedure:mycatalog.myschema.myprocedure", 
"catalog", "mycatalog", "schema", "myschema", "procedure", "myprocedure"),
-                new 
TestData("schemafunction:mycatalog.myschema.myschemafunction", "catalog", 
"mycatalog", "schema", "myschema", "schemafunction", "myschemafunction"),
-                new 
TestData("queryid:12345-67890-abcdefg-hijklmnopqrs-tuvwxyz", "queryid", 
"12345-67890-abcdefg-hijklmnopqrs-tuvwxyz"),
-                new TestData("sysinfo:systeminfo", "sysinfo", "systeminfo"),
-                new TestData("role:myrole", "role", "myrole"),
-                // invalid values
-                new TestData("mycatalog.myschema.mytable.mycolumn", 
INVALID_RESOURCE_TYPE_NOT_VALID),                     // no resource-type
-                new TestData(":mycatalog.myschema.mytable.mycolumn", 
INVALID_RESOURCE_TYPE_NOT_VALID),                    // empty resource-type
-                new 
TestData("invalidResourceType:mycatalog.myschema.mytable.mycolumn", 
INVALID_RESOURCE_TYPE_NOT_VALID), // unknown resource-type
-                new TestData("catalog:", INVALID_RESOURCE_EMPTY_VALUE),
-                new TestData("schema:mycatalog_myschema", 
INVALID_RESOURCE_VALUE),
-                new TestData("table:mycatalog_myschema_mytable", 
INVALID_RESOURCE_VALUE),
-                new TestData("column:mycatalog_myschema_mytable_mycolumn", 
INVALID_RESOURCE_VALUE),
-                new TestData("trinouser:", INVALID_RESOURCE_EMPTY_VALUE),
-                new TestData("sessionproperty:mycatalog_mysessionproperty", 
INVALID_RESOURCE_VALUE),
-                new TestData("procedure:mycatalog_myschema_myprocedure", 
INVALID_RESOURCE_VALUE),
-        };
-
-        for (TestData test : tests) {
-            if (test.errorCode != null) {
-                RangerAuthzException excp = 
assertThrowsExactly(RangerAuthzException.class, () -> 
getResourceAsMap(test.resource, templates), test.resource);
-
-                assertEquals(test.errorCode.getCode(), 
excp.getErrorCode().getCode(), test.resource);
-            } else {
-                assertEquals(test.expected, getResourceAsMap(test.resource, 
templates), test.resource);
-            }
-        }
-    }
-
-    private static Map<String, RangerResourceTemplate> getHiveTemplates() 
throws Exception {
-        Map<String, RangerResourceTemplate> ret = new HashMap<>();
-
-        ret.put("database", new RangerResourceTemplate("{database}"));
-        ret.put("table", new RangerResourceTemplate("{database}.{table}"));
-        ret.put("column", new 
RangerResourceTemplate("{database}.{table}.{column}"));
-        ret.put("udf", new RangerResourceTemplate("{database}.{udf}"));
-        ret.put("url", new RangerResourceTemplate("{url}"));
-        ret.put("hiveservice", new RangerResourceTemplate("{hiveservice}"));
-        ret.put("global", new RangerResourceTemplate("{global}"));
-
-        return ret;
-    }
-
-    private static Map<String, RangerResourceTemplate> getS3Templates() throws 
Exception {
-        Map<String, RangerResourceTemplate> ret = new HashMap<>();
-
-        ret.put("bucket", new RangerResourceTemplate("{bucket}"));
-        ret.put("path", new RangerResourceTemplate("{bucket}/{path}"));
-
-        return ret;
-    }
-
-    private static Map<String, RangerResourceTemplate> getAdlsGen2Templates() 
throws Exception {
-        Map<String, RangerResourceTemplate> ret = new HashMap<>();
-
-        ret.put("container", new 
RangerResourceTemplate("{container}@{storageaccount}"));
-        ret.put("relativepath", new 
RangerResourceTemplate("{container}@{storageaccount}/{relativepath}"));
-
-        return ret;
-    }
-
-    private static Map<String, RangerResourceTemplate> getTrinoTemplates() 
throws Exception {
-        Map<String, RangerResourceTemplate> ret = new HashMap<>();
-
-        ret.put("catalog", new RangerResourceTemplate("{catalog}"));
-        ret.put("schema", new RangerResourceTemplate("{catalog}.{schema}"));
-        ret.put("table", new 
RangerResourceTemplate("{catalog}.{schema}.{table}"));
-        ret.put("column", new 
RangerResourceTemplate("{catalog}.{schema}.{table}.{column}"));
-        ret.put("trinouser", new RangerResourceTemplate("{trinouser}"));
-        ret.put("systemproperty", new 
RangerResourceTemplate("{systemproperty}"));
-        ret.put("sessionproperty", new 
RangerResourceTemplate("{catalog}.{sessionproperty}"));
-        ret.put("function", new RangerResourceTemplate("{function}"));
-        ret.put("procedure", new 
RangerResourceTemplate("{catalog}.{schema}.{procedure}"));
-        ret.put("schemafunction", new 
RangerResourceTemplate("{catalog}.{schema}.{schemafunction}"));
-        ret.put("queryid", new RangerResourceTemplate("{queryid}"));
-        ret.put("sysinfo", new RangerResourceTemplate("{sysinfo}"));
-        ret.put("role", new RangerResourceTemplate("{role}"));
-
-        return ret;
-    }
-
-    private Map<String, String> getResourceAsMap(String resource, Map<String, 
RangerResourceTemplate> templates) throws RangerAuthzException {
-        String[]               resourceParts = resource.split(":", 2);
-        String                 resourceType  = resourceParts.length > 0 ? 
resourceParts[0] : null;
-        String                 resourceValue = resourceParts.length > 1 ? 
resourceParts[1] : null;
-        RangerResourceTemplate template      = templates.get(resourceType);
-
-        if (template == null) {
-            throw new RangerAuthzException(INVALID_RESOURCE_TYPE_NOT_VALID, 
resourceType);
-        }
-
-        return template.parse(resourceValue);
-    }
-
-    private static class TestData {
-        public final String               resource;
-        public final Map<String, String>  expected;
-        public final RangerAuthzErrorCode errorCode;
-
-        public TestData(String resource, String...values) {
-            this.resource = resource;
-
-            if (values.length > 1) {
-                this.expected  = new HashMap<>();
-                this.errorCode = null;
-
-                for (int i = 1; i < values.length; i += 2) {
-                    expected.put(values[i - 1], values[i]);
-                }
-            } else {
-                this.expected  = null;
-                this.errorCode = null;
-            }
-        }
-
-        public TestData(String resource, RangerAuthzErrorCode errorCode) {
-            this.resource  = resource;
-            this.expected  = null;
-            this.errorCode = errorCode;
-        }
-    }
-}

Reply via email to