Repository: incubator-ranger
Updated Branches:
  refs/heads/master fb6e94f13 -> f0a8931a8


RANGER-513 Policy validation: resource hierarchies check does not work with 
single-node hierarchies e.g. for HDFS

Signed-off-by: Madhan Neethiraj <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/f0a8931a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/f0a8931a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/f0a8931a

Branch: refs/heads/master
Commit: f0a8931a8c1847470e486ffdf59c70814270ce9d
Parents: fb6e94f
Author: Alok Lal <[email protected]>
Authored: Thu May 28 15:34:15 2015 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Thu May 28 20:47:54 2015 -0700

----------------------------------------------------------------------
 .../validation/RangerServiceDefHelper.java      | 30 +++++++++++---
 .../validation/TestRangerServiceDefHelper.java  | 42 +++++++++++++++++++-
 2 files changed, 66 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f0a8931a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
----------------------------------------------------------------------
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 91ff16a..d3bcc1a 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
@@ -36,6 +36,8 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 
+import com.google.common.collect.Lists;
+
 public class RangerServiceDefHelper {
 
        private static final Log LOG = 
LogFactory.getLog(RangerServiceDefHelper.class);
@@ -238,10 +240,20 @@ public class RangerServiceDefHelper {
                        Set<String> sources = graph.getSources();
                        Set<String> sinks = graph.getSinks();
                        for (String source : sources) {
-                               for (String sink : sinks) {
-                                       List<String> path = 
graph.getAPath(source, sink, new HashSet<String>());
-                                       if (!path.isEmpty()) {
-                                               hierarchies.add(path);
+                               /*
+                                * A disconnected node, i.e. one that does not 
have any arc coming into or out of it is a hierarchy in itself!
+                                * A source by definition does not have any 
arcs coming into it.  So if it also doesn't have any neighbors then we know
+                                * it is a disconnected node.
+                                */
+                               if (!graph.hasNeighbors(source)) {
+                                       List<String> path = 
Lists.newArrayList(source);
+                                       hierarchies.add(path);
+                               } else {
+                                       for (String sink : sinks) {
+                                               List<String> path = 
graph.getAPath(source, sink, new HashSet<String>());
+                                               if (!path.isEmpty()) {
+                                                       hierarchies.add(path);
+                                               }
                                        }
                                }
                        }
@@ -328,6 +340,14 @@ public class RangerServiceDefHelper {
                }
 
                /**
+                * Returns true if the node "from" has any neighbor.
+                * @param from
+                * @return
+                */
+               boolean hasNeighbors(String from) {
+                       return _nodes.containsKey(from) && 
_nodes.get(from).size() > 0;
+               }
+               /**
                 * Return the set of nodes with in degree of 0, i.e. those that 
are not in any other nodes' list of neighbors
                 * 
                 * @return
@@ -339,7 +359,7 @@ public class RangerServiceDefHelper {
                                sources.removeAll(nbrs); // A source in a DAG 
can't be a neighbor of any other node
                        }
                        if (LOG.isDebugEnabled()) {
-                               LOG.debug("Returning sinks: " + sources);
+                               LOG.debug("Returning sources: " + sources);
                        }
                        return sources;
                }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f0a8931a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
----------------------------------------------------------------------
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 2703384..883b808 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
@@ -149,10 +149,50 @@ public class TestRangerServiceDefHelper {
                        assertTrue(expectedHierarchies.contains(resourceNames));
                        expectedHierarchies.remove(resourceNames);
                }
-               assertTrue(expectedHierarchies.isEmpty()); // make sure we saw 
got back hierarchies
+               assertTrue("Missing hierarchies: " + 
expectedHierarchies.toString(), expectedHierarchies.isEmpty()); // make sure we 
got back all hierarchies
        }
 
        @Test
+       public final void test_isResourceGraphValid_forest_singleNodeTrees() {
+               /*
+                * Create a service-def which is a forest with a few single 
node trees
+                * 
+                *   Database
+                *   
+                *   Server
+                *      
+                *   Namespace -> package
+                *       |
+                *       v
+                *     function
+                *     
+                * Check that helper corrects reports back all of the 
hierarchies: levels in it and their order.   
+                */
+               RangerResourceDef database = createResourceDef("database", "");
+               RangerResourceDef server = createResourceDef("server", "");
+               RangerResourceDef namespace = createResourceDef("namespace", 
"");
+               RangerResourceDef function = createResourceDef("function", 
"namespace");
+               RangerResourceDef Package = createResourceDef("package", 
"namespace"); 
+               List<RangerResourceDef> resourceDefs = 
Lists.newArrayList(database, server, namespace, function, Package);
+               when(_serviceDef.getResources()).thenReturn(resourceDefs);
+               _helper = new RangerServiceDefHelper(_serviceDef);
+               assertTrue(_helper.isResourceGraphValid());
+               Set<List<RangerResourceDef>> hierarchies = 
_helper.getResourceHierarchies();
+
+               Set<List<String>> expectedHierarchies = new 
HashSet<List<String>>(); 
+               expectedHierarchies.add(Lists.newArrayList("database"));
+               expectedHierarchies.add(Lists.newArrayList("server"));
+               expectedHierarchies.add(Lists.newArrayList("namespace", 
"package"));
+               expectedHierarchies.add(Lists.newArrayList("namespace", 
"function"));
+               
+               for (List<RangerResourceDef> aHierarchy : hierarchies) {
+                       List<String> resourceNames = 
_helper.getAllResourceNames(aHierarchy);
+                       assertTrue(expectedHierarchies.contains(resourceNames));
+                       expectedHierarchies.remove(resourceNames);
+               }
+               assertTrue("Missing hierarchies: " + 
expectedHierarchies.toString(), expectedHierarchies.isEmpty()); // make sure we 
got back all hierarchies
+       }
+       @Test
        public final void test_cacheBehavior() {
                // wipe the cache clean
                RangerServiceDefHelper._Cache.clear();

Reply via email to