SENTRY-2502: Sentry NN plug-in stops fetching updates from sentry server.(Kalyan Kumar Kalvagadda reviewed by Na Li)

Change-Id: I4bc91802c53a45f3874a3f873b744e9cfef4f60f
diff --git a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/HMSPaths.java b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/HMSPaths.java
index 1dfa1d9..c49e244 100644
--- a/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/HMSPaths.java
+++ b/sentry-hdfs/sentry-hdfs-common/src/main/java/org/apache/sentry/hdfs/HMSPaths.java
@@ -204,7 +204,7 @@
     }
 
     Entry removeChild(String pathElement) {
-      LOG.debug("[removeChild]Removing {} from children {}", pathElement, childrenValues());
+      LOG.debug("[removeChild]Removing {} from children", pathElement);
       return children.remove(pathElement);
     }
 
@@ -479,6 +479,9 @@
 
     public void deleteAuthzObject(String authzObj) {
       LOG.debug("[deleteAuthzObject] Removing authObj:{} from path {}", authzObj, this.toString());
+      if(!getAuthzObjs().contains(authzObj)) {
+        return;
+      }
       if (getParent() != null) {
         if (!hasChildren()) {
 
@@ -498,11 +501,13 @@
           // change it to be a dir entry. And remove the authzObj on
           // the path entry.
           if (getType() == EntryType.AUTHZ_OBJECT) {
-            LOG.debug("Entry with path: {} is changed to DIR", this.getFullPath());
-            setType(EntryType.DIR);
             if (authzObjs != null) {
               removeAuthzObj(authzObj);
             }
+            if(getAuthzObjsSize() == 0) {
+              LOG.debug("Entry with path: {} is changed to DIR", this.getFullPath());
+              setType(EntryType.DIR);
+            }
           }
         }
       }
@@ -800,13 +805,12 @@
     Set<Entry> entries = authzObjToEntries.get(authzObj);
     if (entries != null) {
       LOG.debug("[deletePathsFromAuthzObject] Paths for {} before delete are {}", authzObj, entries.toString());
-      Set<Entry> toDelEntries = new HashSet<Entry>(authzObjPathElements.size());
       for (List<String> pathElements : authzObjPathElements) {
         Entry entry = root.find(
             pathElements.toArray(new String[pathElements.size()]), false);
         if (entry != null) {
+          entries.remove(entry);
           entry.deleteAuthzObject(authzObj);
-          toDelEntries.add(entry);
         } else {
           LOG.warn(String.format("%s deletePathsFromAuthzObject(%s, %s):" +
             " Path %s was not deleted from AuthzObject, path not registered." +
@@ -814,8 +818,11 @@
             this, authzObj, assemblePaths(authzObjPathElements), pathElements));
         }
       }
-      entries.removeAll(toDelEntries);
       LOG.debug("[deletePathsFromAuthzObject] Paths for {} after are {}", authzObj, entries.toString());
+      if(entries.size() == 0) {
+        authzObjToEntries.remove(authzObj);
+        LOG.debug("[deletePathsFromAuthzObject] Removing the mapping for {} as the entries are stale", authzObj);
+      }
     } else {
       LOG.warn(String.format("%s deletePathsFromAuthzObject(%s, %s):" +
         " Path was not deleted from AuthzObject, could not find key in authzObjToPath",
diff --git a/sentry-hdfs/sentry-hdfs-namenode-plugin/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationInfo.java b/sentry-hdfs/sentry-hdfs-namenode-plugin/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationInfo.java
index 9fe22ef..a87dbe1 100644
--- a/sentry-hdfs/sentry-hdfs-namenode-plugin/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationInfo.java
+++ b/sentry-hdfs/sentry-hdfs-namenode-plugin/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationInfo.java
@@ -232,7 +232,7 @@
       LOG.warn("Failed to update, will retry in [{}]ms, error: ", 
           new Object[]{ retryWaitMillisec, ex.getMessage(), ex});
     } catch (Throwable t) {
-      LOG.error("Received a throwable while refreshing the cache" + t);
+      LOG.error("Received a throwable while refreshing the cache", t);
       System.out.println("Received a throwable  while refreshing the cache " + t);
       throw t;
     }
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hdfs/TestHDFSIntegrationEnd2End.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hdfs/TestHDFSIntegrationEnd2End.java
index 574bc4b..38c7a6d 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hdfs/TestHDFSIntegrationEnd2End.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hdfs/TestHDFSIntegrationEnd2End.java
@@ -607,5 +607,59 @@
     conn.close();
   }
 
+  /*
+  Added to verify the SENTRY-2502
+  */
+  @Test
+  public void testTableRename() throws Throwable {
+    String dbName = "testdb";
+    dbNames = new String[]{dbName};
+    roles = new String[]{"admin_role"};
+    admin = StaticUserGroup.ADMIN1;
 
+    Connection conn;
+    Statement stmt;
+
+    conn = hiveServer2.createConnection("hive", "hive");
+    stmt = conn.createStatement();
+    stmt.execute("create role admin_role");
+    stmt.execute("grant all on server server1 to role admin_role");
+    stmt.execute("grant all on database " + dbName + " to role admin_role");
+    stmt.execute("grant role admin_role to group " + StaticUserGroup.USERGROUP1);
+    stmt.execute("grant role admin_role to group " + StaticUserGroup.ADMINGROUP);
+
+
+    conn = hiveServer2.createConnection(StaticUserGroup.USER1_1, StaticUserGroup.USERGROUP1);
+    stmt = conn.createStatement();
+    stmt.execute("create database " + dbName);
+    stmt.execute("use "+ dbName);
+    stmt.execute("create table testable (s string) partitioned by (month int)");
+
+    stmt.execute("alter table testable add partition (month=1)");
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/testable", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/testable/month=1", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+
+    stmt.execute("alter table testable rename to testable1");
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/testable1", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/testable1/month=1", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+
+
+    stmt.execute("alter table testable1 drop partition (month=1)");
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/testable1", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+
+    stmt.execute("alter table testable1 add partition (month=1)");
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/testable1/month=1", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+
+    stmt.execute("alter table testable1 rename to testable2");
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/testable2", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/testable2/month=1", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+
+    stmt.execute("create table  table3(s string) partitioned by (month int)");
+    stmt.execute("alter table table3 add partition (month=1)");
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/table3", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+    verifyGroupPermOnAllSubDirs("/user/hive/warehouse/" + dbName + ".db/table3/month=1", FsAction.ALL, StaticUserGroup.USERGROUP1, true);
+
+    stmt.close();
+    conn.close();
+  }
 }