You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by ka...@apache.org on 2018/12/07 15:21:39 UTC

sentry git commit: SENTRY-2460: Export sentry permission information to HDFS location. (Kalyan Kumar Kalvagadda reviewed by Sergio Pena)

Repository: sentry
Updated Branches:
  refs/heads/master ea7a33b77 -> 7a4320968


SENTRY-2460: Export sentry permission information to HDFS location. (Kalyan Kumar Kalvagadda reviewed by Sergio Pena)


Project: http://git-wip-us.apache.org/repos/asf/sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/7a432096
Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/7a432096
Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/7a432096

Branch: refs/heads/master
Commit: 7a43209685506b8b8a869bab00086d367a524ebf
Parents: ea7a33b
Author: Kalyan Kumar Kalvagadda <kk...@cloudera.com>
Authored: Fri Dec 7 09:18:39 2018 -0600
Committer: Kalyan Kumar Kalvagadda <kk...@cloudera.com>
Committed: Fri Dec 7 09:18:39 2018 -0600

----------------------------------------------------------------------
 .../hive/SentryIniPolicyFileFormatter.java      |  46 +++++--
 .../binding/hive/SentryPolicyFileFormatter.java |   2 +-
 .../binding/hive/authz/SentryConfigTool.java    |   2 +-
 .../hive/TestSentryIniPolicyFileFormatter.java  | 124 ++++++++++++++++---
 .../sentry/service/common/ServiceConstants.java |   5 +
 .../thrift/TestSentryServiceImportExport.java   |   5 +
 .../persistent/TestSentryStoreImportExport.java |   3 +
 .../tests/e2e/hive/TestPolicyImportExport.java  |  61 +++++++++
 8 files changed, 217 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/7a432096/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
index b8ec8a1..8c3895c 100644
--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
+++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
@@ -18,28 +18,31 @@
 
 package org.apache.sentry.binding.hive;
 
-import java.io.File;
+import java.io.BufferedWriter;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import com.google.common.base.Strings;
 import com.google.common.collect.Sets;
 import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.sentry.core.common.exception.SentryConfigurationException;
 import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.common.utils.PolicyFileConstants;
 import org.apache.sentry.core.common.utils.PolicyFiles;
+import org.apache.sentry.service.common.ServiceConstants;
 import org.apache.shiro.config.Ini;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Charsets;
 import com.google.common.base.Joiner;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.io.Files;
 
 /**
  * SentryIniPolicyFileFormatter is to parse file and write data to file for sentry mapping data with
@@ -58,8 +61,8 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
   /**
    * Write the sentry mapping data to ini file.
    *
-   * @param resourcePath
-   *        The path of the output file
+   * @param resourcePath The path of the output file
+   * @param conf sentry configuration
    * @param sentryMappingData
    *        The map for sentry mapping data, eg:
    *        for the following mapping data:
@@ -82,11 +85,19 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
    *        }
    */
   @Override
-  public void write(String resourcePath, Map<String, Map<String, Set<String>>> sentryMappingData)
+  public void write(String resourcePath, Configuration conf, Map<String, Map<String, Set<String>>> sentryMappingData)
       throws Exception {
-    File destFile = new File(resourcePath);
-    if (destFile.exists() && !destFile.delete()) {
-      throw new IllegalStateException("Unable to delete " + destFile);
+    Path path = new Path(resourcePath);
+    if (Strings.isNullOrEmpty(path.toUri().getScheme())) {
+      // Path provided did not have any URI scheme. Update the scheme based on configuration.
+      String defaultFs = conf.get(ServiceConstants.ClientConfig.SENTRY_EXPORT_IMPORT_DEFAULT_FS,
+              ServiceConstants.ClientConfig.SENTRY_EXPORT_IMPORT_DEFAULT_FS_DEFAULT);
+       path = new Path(defaultFs + resourcePath);
+    }
+
+    FileSystem fileSystem = path.getFileSystem(conf);
+    if (fileSystem.exists(path)) {
+      fileSystem.delete(path,true);
     }
     String contents = Joiner
         .on(NL)
@@ -98,8 +109,19 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
         generateSection(PolicyFileConstants.ROLES,
                 sentryMappingData.get(PolicyFileConstants.ROLES)),
             "");
-    LOGGER.info("Writing policy file to " + destFile + ":\n" + contents);
-    Files.write(contents, destFile, Charsets.UTF_8);
+    LOGGER.info("Writing policy information to file located at" + path);
+    OutputStream os = fileSystem.create(path);
+    BufferedWriter br = new BufferedWriter( new OutputStreamWriter( os, "UTF-8" ) );
+    try {
+      br.write(contents);
+    }
+    catch (Exception exception) {
+      LOGGER.error("Failed to export policy information to file, located at " + path);
+    }
+    finally {
+      br.close();
+      fileSystem.close();
+    }
   }
 
   /**
@@ -156,7 +178,7 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
 
   // generate the ini section according to the mapping data.
   private String generateSection(String name, Map<String, Set<String>> mappingData) {
-    if (mappingData.isEmpty()) {
+    if (mappingData == null || mappingData.isEmpty()) {
       return "";
     }
     List<String> lines = Lists.newArrayList();

http://git-wip-us.apache.org/repos/asf/sentry/blob/7a432096/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryPolicyFileFormatter.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryPolicyFileFormatter.java
index 4f465b3..441e0cc 100644
--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryPolicyFileFormatter.java
+++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryPolicyFileFormatter.java
@@ -29,7 +29,7 @@ import org.apache.hadoop.conf.Configuration;
 public interface SentryPolicyFileFormatter {
 
   // write the sentry mapping data to file
-  void write(String resourcePath, Map<String, Map<String, Set<String>>> sentryMappingData)
+  void write(String resourcePath, Configuration conf, Map<String, Map<String, Set<String>>> sentryMappingData)
       throws Exception;
 
   // parse the sentry mapping data from file

http://git-wip-us.apache.org/repos/asf/sentry/blob/7a432096/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/SentryConfigTool.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/SentryConfigTool.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/SentryConfigTool.java
index 5f1e3e9..3a0c0f0 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/SentryConfigTool.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/authz/SentryConfigTool.java
@@ -309,7 +309,7 @@ public class SentryConfigTool {
       SentryPolicyFileFormatter sentryPolicyFileFormatter = SentryPolicyFileFormatFactory
               .createFileFormatter(authzConf);
       // write the sentry mapping data to exportPolicyFilePath with the data in map structure
-      sentryPolicyFileFormatter.write(exportPolicyFilePath, policyFileMappingData);
+      sentryPolicyFileFormatter.write(exportPolicyFilePath, authzConf, policyFileMappingData);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/7a432096/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
index 7baeee1..76f5b09 100644
--- a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
@@ -21,13 +21,20 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
 import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
 import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.common.utils.PolicyFileConstants;
-import org.junit.Test;
+
+import org.junit.*;
 
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -36,7 +43,13 @@ import com.google.common.io.Resources;
 
 public class TestSentryIniPolicyFileFormatter {
 
-  private static final String RESOURCE_PATH = "testImportExportPolicy.ini";
+  private static final String RESOURCE_FILE = "testImportExportPolicy.ini";
+  private static File baseDir;
+  private static MiniDFSCluster dfsCluster;
+  private static FileSystem fileSystem;
+  private static Path root;
+  private static Path etc;
+
   // define the privileges
   public static String PRIVILIEGE1 = "server=server1";
   public static String PRIVILIEGE2 = "server=server1->action=select->grantoption=false";
@@ -47,13 +60,39 @@ public class TestSentryIniPolicyFileFormatter {
   public static String PRIVILIEGE7 = "server=server1->db=db1->table=tbl4->column=col1->action=all->grantoption=true";
   public static String PRIVILIEGE8 = "server=server1->uri=hdfs://testserver:9999/path2->action=insert";
 
-  private Map<String, Map<String, Set<String>>> policyFileMappingData1;
-  private Map<String, Map<String, Set<String>>> policyFileMappingData2;
-  private Map<String, Map<String, Set<String>>> policyFileMappingData3;
-  private Map<String, Map<String, Set<String>>> policyFileMappingData4;
-  private Map<String, Map<String, Set<String>>> policyFileMappingData5;
+  private static Map<String, Map<String, Set<String>>> policyFileMappingData1;
+  private static Map<String, Map<String, Set<String>>> policyFileMappingData2;
+  private static Map<String, Map<String, Set<String>>> policyFileMappingData3;
+  private static Map<String, Map<String, Set<String>>> policyFileMappingData4;
+  private static Map<String, Map<String, Set<String>>> policyFileMappingData5;
+
+  @BeforeClass
+  public static void setup() throws IOException {
+    baseDir = Files.createTempDir();
+    Assert.assertNotNull(baseDir);
+    File dfsDir = new File(baseDir, "dfs");
+    assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
+    Configuration conf = new Configuration();
+    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
+    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).build();
+    fileSystem = dfsCluster.getFileSystem();
+    root = new Path(fileSystem.getUri().toString());
+    etc = new Path(root, "/etc");
+    fileSystem.mkdirs(etc);
+    prepareTestData();
+  }
+
+  @AfterClass
+  public static void teardownLocalClazz() throws Exception{
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+    if(dfsCluster != null) {
+      dfsCluster.shutdown();
+    }
+  }
 
-  private void prepareTestData() {
+  private static void prepareTestData() {
     // test data for:
     // [users]
     // user1=role1,role2,role3
@@ -170,42 +209,93 @@ public class TestSentryIniPolicyFileFormatter {
     policyFileMappingData5.put(PolicyFileConstants.ROLES, rolePrivilegesMap);
   }
 
+
+  @Before
+  public void  setupBeforeTest() throws IOException {
+    fileSystem.delete(etc, true);
+    fileSystem.mkdirs(etc);
+  }
+
+  /**
+   * Test to verify import and export into local file system.
+   * @throws Exception
+   */
   @Test
-  public void testImportExport() throws Exception {
-    prepareTestData();
+  public void testImportExportFromLocalFilesystem() throws Exception {
+
     File baseDir = Files.createTempDir();
-    String resourcePath = (new File(baseDir, RESOURCE_PATH)).getAbsolutePath();
+    String resourcePath = (new File(baseDir, RESOURCE_FILE)).getAbsolutePath();
     HiveAuthzConf authzConf = new HiveAuthzConf(Resources.getResource("sentry-site.xml"));
     SentryIniPolicyFileFormatter iniFormatter = new SentryIniPolicyFileFormatter();
 
     // test data1
-    iniFormatter.write(resourcePath, policyFileMappingData1);
+    iniFormatter.write(resourcePath, authzConf, policyFileMappingData1);
     Map<String, Map<String, Set<String>>> parsedMappingData = iniFormatter.parse(resourcePath,
         authzConf);
     validateSentryMappingData(parsedMappingData, policyFileMappingData1);
 
     // test data2
-    iniFormatter.write(resourcePath, policyFileMappingData2);
+    iniFormatter.write(resourcePath, authzConf, policyFileMappingData2);
     parsedMappingData = iniFormatter.parse(resourcePath, authzConf);
     validateSentryMappingData(parsedMappingData, policyFileMappingData2);
 
     // test data3
-    iniFormatter.write(resourcePath, policyFileMappingData3);
+    iniFormatter.write(resourcePath, authzConf, policyFileMappingData3);
     parsedMappingData = iniFormatter.parse(resourcePath, authzConf);
     validateSentryMappingData(parsedMappingData, policyFileMappingData3);
 
     // test data4
-    iniFormatter.write(resourcePath, policyFileMappingData4);
+    iniFormatter.write(resourcePath, authzConf, policyFileMappingData4);
     parsedMappingData = iniFormatter.parse(resourcePath, authzConf);
     validateSentryMappingData(parsedMappingData, policyFileMappingData4);
 
     // test data5
-    iniFormatter.write(resourcePath, policyFileMappingData5);
+    iniFormatter.write(resourcePath, authzConf, policyFileMappingData5);
     parsedMappingData = iniFormatter.parse(resourcePath, authzConf);
     assertTrue(parsedMappingData.get(PolicyFileConstants.USER_ROLES).isEmpty());
     assertTrue(parsedMappingData.get(PolicyFileConstants.GROUPS).isEmpty());
     assertTrue(parsedMappingData.get(PolicyFileConstants.ROLES).isEmpty());
-    (new File(baseDir, RESOURCE_PATH)).delete();
+    (new File(baseDir, RESOURCE_FILE)).delete();
+  }
+
+  /**
+   * Test to verify import and export into a hdfs file
+   * @throws Exception
+   */
+  @Test
+  public void testImportExportFromHDFS() throws Exception {
+    Path resourcePath = new Path(etc, RESOURCE_FILE);
+    String resourcePathStr = resourcePath.toUri().toString();
+    HiveAuthzConf authzConf = new HiveAuthzConf(Resources.getResource("sentry-site.xml"));
+    SentryIniPolicyFileFormatter iniFormatter = new SentryIniPolicyFileFormatter();
+
+    // test data1
+    iniFormatter.write(resourcePathStr, authzConf, policyFileMappingData1);
+    Map<String, Map<String, Set<String>>> parsedMappingData = iniFormatter.parse(resourcePath.toUri().toString(),
+            authzConf);
+    validateSentryMappingData(parsedMappingData, policyFileMappingData1);
+
+    // test data2
+    iniFormatter.write(resourcePathStr, authzConf, policyFileMappingData2);
+    parsedMappingData = iniFormatter.parse(resourcePath.toUri().toString(), authzConf);
+    validateSentryMappingData(parsedMappingData, policyFileMappingData2);
+
+    // test data3
+    iniFormatter.write(resourcePathStr, authzConf, policyFileMappingData3);
+    parsedMappingData = iniFormatter.parse(resourcePath.toUri().toString(), authzConf);
+    validateSentryMappingData(parsedMappingData, policyFileMappingData3);
+
+    // test data4
+    iniFormatter.write(resourcePathStr, authzConf, policyFileMappingData4);
+    parsedMappingData = iniFormatter.parse(resourcePath.toUri().toString(), authzConf);
+    validateSentryMappingData(parsedMappingData, policyFileMappingData4);
+
+    // test data5
+    iniFormatter.write(resourcePathStr, authzConf, policyFileMappingData5);
+    parsedMappingData = iniFormatter.parse(resourcePath.toUri().toString(), authzConf);
+    assertTrue(parsedMappingData.get(PolicyFileConstants.USER_ROLES).isEmpty());
+    assertTrue(parsedMappingData.get(PolicyFileConstants.GROUPS).isEmpty());
+    assertTrue(parsedMappingData.get(PolicyFileConstants.ROLES).isEmpty());
   }
 
   // verify the mapping data

http://git-wip-us.apache.org/repos/asf/sentry/blob/7a432096/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
index 092060c..26a58f6 100644
--- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
@@ -266,6 +266,11 @@ public class ServiceConstants {
     public static final int SENTRY_DB_VALUE_GENERATION_ALLOCATION_SIZE_DEFAULT = 100;
   }
 
+  public static class ClientConfig {
+    public static final String SENTRY_EXPORT_IMPORT_DEFAULT_FS = "sentry.export.import.default.fs";
+    public static final String SENTRY_EXPORT_IMPORT_DEFAULT_FS_DEFAULT = "file:///";
+  }
+
   public static final String SENTRY_ZK_JAAS_NAME = "Sentry";
   public static final String CURRENT_INCARNATION_ID_KEY = "current.incarnation.key";
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/7a432096/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java
index cf1fdab..69be166 100644
--- a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java
+++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/api/service/thrift/TestSentryServiceImportExport.java
@@ -35,6 +35,11 @@ import org.junit.Test;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
+/**
+ * Test makes sure that sentry client is gathering all the permission information from sentry server
+ * while export and makes sure that sentry client is retrieving the permission information from sentry server
+ * as requested.
+ */
 public class TestSentryServiceImportExport extends SentryServiceIntegrationBase {
 
   // define the privileges

http://git-wip-us.apache.org/repos/asf/sentry/blob/7a432096/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java
----------------------------------------------------------------------
diff --git a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java
index df9299c..44548dc 100644
--- a/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java
+++ b/sentry-service/sentry-service-server/src/test/java/org/apache/sentry/provider/db/service/persistent/TestSentryStoreImportExport.java
@@ -51,6 +51,9 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.io.Files;
 
+/**
+ * This test verifies that the sentry store APIs for export/import are working as expected.
+ */
 public class TestSentryStoreImportExport {
 
   private static File dataDir;

http://git-wip-us.apache.org/repos/asf/sentry/blob/7a432096/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java
index b048989..d653aca 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java
@@ -26,11 +26,14 @@ import java.lang.reflect.UndeclaredThrowableException;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.io.FileUtils;
+import org.apache.hadoop.fs.Path;
 import org.apache.sentry.binding.hive.SentryPolicyFileFormatFactory;
 import org.apache.sentry.binding.hive.SentryPolicyFileFormatter;
 import org.apache.sentry.binding.hive.authz.SentryConfigTool;
 import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.common.utils.PolicyFileConstants;
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -39,6 +42,9 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.io.Resources;
 
+/**
+ * Performs e2e tests on export/import of sentry permissions.
+ */
 public class TestPolicyImportExport extends AbstractTestWithStaticConfiguration {
 
   // resources/testPolicyImport.ini is used for the import test and all the following
@@ -52,8 +58,13 @@ public class TestPolicyImportExport extends AbstractTestWithStaticConfiguration
   public static String PRIVILIEGE6 = "server=server1->db=db1->table=tbl3->column=col1->action=*->grantoption=true";
   public static String PRIVILIEGE7 = "server=server1->db=db1->table=tbl4->column=col1->action=all->grantoption=true";
   public static String PRIVILIEGE8 = "server=server1->uri=hdfs://testserver:9999/path2->action=insert";
+  private static final String IMPORT_FILE = "testImportPolicy.ini";
+  private static final String EXPORT_FILE = "testExportPolicy.ini";
+
 
   private SentryConfigTool configTool;
+  private static Path root;
+  private static Path etc;
 
   @BeforeClass
   public static void setupTestStaticConfiguration() throws Exception{
@@ -62,6 +73,17 @@ public class TestPolicyImportExport extends AbstractTestWithStaticConfiguration
     String requestorUserName = System.getProperty("user.name", "");
     StaticUserGroup.getStaticMapping().put(requestorUserName, ADMINGROUP);
     AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+    root = new Path(fileSystem.getUri().toString());
+    etc = new Path(root, "/etc");
+    fileSystem.mkdirs(etc);
+  }
+
+  @AfterClass
+  public static void teardown() throws Exception{
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+    tearDownTestStaticConfiguration();
   }
 
   @Before
@@ -134,6 +156,7 @@ public class TestPolicyImportExport extends AbstractTestWithStaticConfiguration
     return policyFileMappingData;
   }
 
+
   @Test
   public void testImportExportPolicy() throws Exception {
     String importFileName = "testPolicyImport.ini";
@@ -161,6 +184,7 @@ public class TestPolicyImportExport extends AbstractTestWithStaticConfiguration
     // test export with objectPath db=db1
     configTool.setObjectPath("db=db1");
     configTool.exportPolicy();
+
     policyFileMappingData = getExceptedDb1ExportData();
     exportMappingData = sentryPolicyFileFormatter.parse(
         exportFile.getAbsolutePath(), configTool.getAuthzConf());
@@ -168,6 +192,43 @@ public class TestPolicyImportExport extends AbstractTestWithStaticConfiguration
   }
 
   @Test
+  public void testImportExportFromHDFS() throws Exception {
+
+    Path importPath = new Path(etc, IMPORT_FILE);
+    Path exportPath = new Path(etc, EXPORT_FILE);
+
+    Map<String, Map<String, Set<String>>> policyFileMappingData =
+            getExceptedAllExportData();
+
+    //Populate sentry permissions using sentryPolicyFileFormatter
+    SentryPolicyFileFormatter sentryPolicyFileFormatter = SentryPolicyFileFormatFactory
+            .createFileFormatter(configTool.getAuthzConf());
+    sentryPolicyFileFormatter.write(importPath.toUri().toString(), configTool.getAuthzConf(), policyFileMappingData);
+
+    // Import the permission information from sentry server to a HDFS file
+    configTool.setImportPolicyFilePath(importPath.toUri().toString());
+    configTool.importPolicy();
+
+    // Export the permission information to a HDFS file
+    configTool.setExportPolicyFilePath(exportPath.toUri().toString());
+    configTool.exportPolicy();
+
+    // Verify the exported data matches with the data that was imported.
+    Map<String, Map<String, Set<String>>> exportMappingData = sentryPolicyFileFormatter.parse(
+            exportPath.toUri().toString(), configTool.getAuthzConf());
+    validateSentryMappingData(exportMappingData, policyFileMappingData);
+
+    // test export with objectPath db=db1
+    configTool.setObjectPath("db=db1");
+    configTool.exportPolicy();
+
+    policyFileMappingData = getExceptedDb1ExportData();
+    exportMappingData = sentryPolicyFileFormatter.parse(
+            exportPath.toUri().toString(), configTool.getAuthzConf());
+    validateSentryMappingData(exportMappingData, policyFileMappingData);
+  }
+
+  @Test
   public void testImportExportPolicyForError() throws Exception {
     prepareForImport("testPolicyImportError.ini");
     try {