http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/92cde111/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
index 81adec2..fbb611e 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
@@ -65,6 +65,7 @@ import 
org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
 import org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
 import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
 import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
+import org.apache.sentry.provider.db.service.thrift.TSentryMappingData;
 import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
 import org.apache.sentry.provider.db.service.thrift.TSentryPrivilegeMap;
 import org.apache.sentry.provider.db.service.thrift.TSentryRole;
@@ -76,9 +77,11 @@ import org.slf4j.LoggerFactory;
 
 import com.codahale.metrics.Gauge;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
+import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -310,16 +313,10 @@ public class SentryStore {
     PersistenceManager pm = null;
     try {
       pm = openTransaction();
-      MSentryRole mSentryRole = getMSentryRole(pm, roleName);
-      if (mSentryRole == null) {
-        MSentryRole mRole = new MSentryRole(roleName, 
System.currentTimeMillis());
-        pm.makePersistent(mRole);
-        CommitContext commit = commitUpdateTransaction(pm);
-        rollbackTransaction = false;
-        return commit;
-      } else {
-        throw new SentryAlreadyExistsException("Role: " + roleName);
-      }
+      createSentryRoleCore(pm, roleName);
+      CommitContext commit = commitUpdateTransaction(pm);
+      rollbackTransaction = false;
+      return commit;
     } finally {
       if (rollbackTransaction) {
         rollbackTransaction(pm);
@@ -327,6 +324,17 @@ public class SentryStore {
     }
   }
 
+  private void createSentryRoleCore(PersistenceManager pm, String roleName)
+      throws SentryAlreadyExistsException {
+    MSentryRole mSentryRole = getMSentryRole(pm, roleName);
+    if (mSentryRole == null) {
+      MSentryRole mRole = new MSentryRole(roleName, 
System.currentTimeMillis());
+      pm.makePersistent(mRole);
+    } else {
+      throw new SentryAlreadyExistsException("Role: " + roleName);
+    }
+  }
+
   private <T> Long getCount(Class<T> tClass) {
     PersistenceManager pm = null;
     Long size = new Long(-1);
@@ -444,7 +452,8 @@ public class SentryStore {
           || (!isNULL(privilege.getDbName()))) {
         // If Grant is for ALL and Either INSERT/SELECT already exists..
         // need to remove it and GRANT ALL..
-        if (privilege.getAction().equalsIgnoreCase("*")) {
+        if (AccessConstants.ALL.equalsIgnoreCase(privilege.getAction())
+            || 
AccessConstants.ACTION_ALL.equalsIgnoreCase(privilege.getAction())) {
           TSentryPrivilege tNotAll = new TSentryPrivilege(privilege);
           tNotAll.setAction(AccessConstants.SELECT);
           MSentryPrivilege mSelect = getMSentryPrivilege(tNotAll, pm);
@@ -465,8 +474,13 @@ public class SentryStore {
           // do nothing..
           TSentryPrivilege tAll = new TSentryPrivilege(privilege);
           tAll.setAction(AccessConstants.ALL);
-          MSentryPrivilege mAll = getMSentryPrivilege(tAll, pm);
-          if ((mAll != null) && (mRole.getPrivileges().contains(mAll))) {
+          MSentryPrivilege mAll1 = getMSentryPrivilege(tAll, pm);
+          tAll.setAction(AccessConstants.ACTION_ALL);
+          MSentryPrivilege mAll2 = getMSentryPrivilege(tAll, pm);
+          if ((mAll1 != null) && (mRole.getPrivileges().contains(mAll1))) {
+            return null;
+          }
+          if ((mAll2 != null) && (mRole.getPrivileges().contains(mAll2))) {
             return null;
           }
         }
@@ -763,25 +777,9 @@ public class SentryStore {
       throws SentryNoSuchObjectException {
     boolean rollbackTransaction = true;
     PersistenceManager pm = null;
-    roleName = roleName.trim().toLowerCase();
     try {
       pm = openTransaction();
-      Query query = pm.newQuery(MSentryRole.class);
-      query.setFilter("this.roleName == t");
-      query.declareParameters("java.lang.String t");
-      query.setUnique(true);
-      MSentryRole sentryRole = (MSentryRole) query.execute(roleName);
-      if (sentryRole == null) {
-        throw new SentryNoSuchObjectException("Role " + roleName);
-      } else {
-        pm.retrieve(sentryRole);
-        int numPrivs = sentryRole.getPrivileges().size();
-        sentryRole.removePrivileges();
-        //with SENTRY-398 generic model
-        sentryRole.removeGMPrivileges();
-        privCleaner.incPrivRemoval(numPrivs);
-        pm.deletePersistent(sentryRole);
-      }
+      dropSentryRoleCore(pm, roleName);
       CommitContext commit = commitUpdateTransaction(pm);
       rollbackTransaction = false;
       return commit;
@@ -792,42 +790,38 @@ public class SentryStore {
     }
   }
 
+  private void dropSentryRoleCore(PersistenceManager pm, String roleName)
+      throws SentryNoSuchObjectException {
+    String lRoleName = roleName.trim().toLowerCase();
+    Query query = pm.newQuery(MSentryRole.class);
+    query.setFilter("this.roleName == t");
+    query.declareParameters("java.lang.String t");
+    query.setUnique(true);
+    MSentryRole sentryRole = (MSentryRole) query.execute(lRoleName);
+    if (sentryRole == null) {
+      throw new SentryNoSuchObjectException("Role " + lRoleName);
+    } else {
+      pm.retrieve(sentryRole);
+      int numPrivs = sentryRole.getPrivileges().size();
+      sentryRole.removePrivileges();
+      // with SENTRY-398 generic model
+      sentryRole.removeGMPrivileges();
+      privCleaner.incPrivRemoval(numPrivs);
+      pm.deletePersistent(sentryRole);
+    }
+  }
+
   public CommitContext alterSentryRoleAddGroups( String grantorPrincipal, 
String roleName,
       Set<TSentryGroup> groupNames)
           throws SentryNoSuchObjectException {
     boolean rollbackTransaction = true;
     PersistenceManager pm = null;
-    roleName = roleName.trim().toLowerCase();
     try {
       pm = openTransaction();
-      Query query = pm.newQuery(MSentryRole.class);
-      query.setFilter("this.roleName == t");
-      query.declareParameters("java.lang.String t");
-      query.setUnique(true);
-      MSentryRole role = (MSentryRole) query.execute(roleName);
-      if (role == null) {
-        throw new SentryNoSuchObjectException("Role: " + roleName);
-      } else {
-        query = pm.newQuery(MSentryGroup.class);
-        query.setFilter("this.groupName == t");
-        query.declareParameters("java.lang.String t");
-        query.setUnique(true);
-        List<MSentryGroup> groups = Lists.newArrayList();
-        for (TSentryGroup tGroup : groupNames) {
-          String groupName = tGroup.getGroupName().trim();
-          MSentryGroup group = (MSentryGroup) query.execute(groupName);
-          if (group == null) {
-            group = new MSentryGroup(groupName, System.currentTimeMillis(),
-                 Sets.newHashSet(role));
-          }
-          group.appendRole(role);
-          groups.add(group);
-        }
-        pm.makePersistentAll(groups);
-        CommitContext commit = commitUpdateTransaction(pm);
-        rollbackTransaction = false;
-        return commit;
-      }
+      alterSentryRoleAddGroupsCore(pm, roleName, groupNames);
+      CommitContext commit = commitUpdateTransaction(pm);
+      rollbackTransaction = false;
+      return commit;
     } finally {
       if (rollbackTransaction) {
         rollbackTransaction(pm);
@@ -835,6 +829,35 @@ public class SentryStore {
     }
   }
 
+  private void alterSentryRoleAddGroupsCore(PersistenceManager pm, String 
roleName,
+      Set<TSentryGroup> groupNames) throws SentryNoSuchObjectException {
+    String lRoleName = roleName.trim().toLowerCase();
+    Query query = pm.newQuery(MSentryRole.class);
+    query.setFilter("this.roleName == t");
+    query.declareParameters("java.lang.String t");
+    query.setUnique(true);
+    MSentryRole role = (MSentryRole) query.execute(lRoleName);
+    if (role == null) {
+      throw new SentryNoSuchObjectException("Role: " + lRoleName);
+    } else {
+      query = pm.newQuery(MSentryGroup.class);
+      query.setFilter("this.groupName == t");
+      query.declareParameters("java.lang.String t");
+      query.setUnique(true);
+      List<MSentryGroup> groups = Lists.newArrayList();
+      for (TSentryGroup tGroup : groupNames) {
+        String groupName = tGroup.getGroupName().trim();
+        MSentryGroup group = (MSentryGroup) query.execute(groupName);
+        if (group == null) {
+          group = new MSentryGroup(groupName, System.currentTimeMillis(), 
Sets.newHashSet(role));
+        }
+        group.appendRole(role);
+        groups.add(group);
+      }
+      pm.makePersistentAll(groups);
+    }
+  }
+
   public CommitContext alterSentryRoleDeleteGroups(String roleName,
       Set<TSentryGroup> groupNames)
           throws SentryNoSuchObjectException {
@@ -1341,7 +1364,7 @@ public class SentryStore {
     return group;
   }
 
-  private TSentryPrivilege convertToTSentryPrivilege(MSentryPrivilege 
mSentryPrivilege) {
+  protected TSentryPrivilege convertToTSentryPrivilege(MSentryPrivilege 
mSentryPrivilege) {
     TSentryPrivilege privilege = new TSentryPrivilege();
     convertToTSentryPrivilege(mSentryPrivilege, privilege);
     return privilege;
@@ -1979,4 +2002,319 @@ public class SentryStore {
       }
     }
   }
+
+  // get all mapping data for [group,role]
+  public Map<String, Set<String>> getGroupNameRoleNamesMap() {
+    boolean rollbackTransaction = true;
+    PersistenceManager pm = null;
+    try {
+      pm = openTransaction();
+      Query query = pm.newQuery(MSentryGroup.class);
+      List<MSentryGroup> mSentryGroups = (List<MSentryGroup>) query.execute();
+      Map<String, Set<String>> sentryGroupNameRoleNamesMap = Maps.newHashMap();
+      if (mSentryGroups != null) {
+        // change the List<MSentryGroup> -> Map<groupName, Set<roleName>>
+        for (MSentryGroup mSentryGroup : mSentryGroups) {
+          String groupName = mSentryGroup.getGroupName();
+          Set<String> roleNames = Sets.newHashSet();
+          for (MSentryRole mSentryRole : mSentryGroup.getRoles()) {
+            roleNames.add(mSentryRole.getRoleName());
+          }
+          if (roleNames.size() > 0) {
+            sentryGroupNameRoleNamesMap.put(groupName, roleNames);
+          }
+        }
+      }
+      commitTransaction(pm);
+      rollbackTransaction = false;
+      return sentryGroupNameRoleNamesMap;
+    } finally {
+      if (rollbackTransaction) {
+        rollbackTransaction(pm);
+      }
+    }
+  }
+
+  // get all mapping data for [role,privilege]
+  public Map<String, Set<TSentryPrivilege>> getRoleNameTPrivilegesMap() throws 
Exception {
+    boolean rollbackTransaction = true;
+    PersistenceManager pm = null;
+    try {
+      pm = openTransaction();
+      Query query = pm.newQuery(MSentryRole.class);
+      List<MSentryRole> mSentryRoles = (List<MSentryRole>) query.execute();
+      Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap = 
Maps.newHashMap();
+      if (mSentryRoles != null) {
+        // change the List<MSentryRole> -> Map<roleName, Set<TSentryPrivilege>>
+        for (MSentryRole mSentryRole : mSentryRoles) {
+          Set<TSentryPrivilege> privilegeSet = 
convertToTSentryPrivileges(mSentryRole
+              .getPrivileges());
+          if (privilegeSet != null && !privilegeSet.isEmpty()) {
+            sentryRolePrivilegesMap.put(mSentryRole.getRoleName(), 
privilegeSet);
+          }
+        }
+      }
+      commitTransaction(pm);
+      rollbackTransaction = false;
+    return sentryRolePrivilegesMap;
+    } finally {
+      if (rollbackTransaction) {
+        rollbackTransaction(pm);
+      }
+    }
+  }
+
+  // get the all exist role names
+  private Set<String> getAllRoleNames(PersistenceManager pm) {
+    Query query = pm.newQuery(MSentryRole.class);
+    List<MSentryRole> mSentryRoles = (List<MSentryRole>) query.execute();
+    Set<String> existRoleNames = Sets.newHashSet();
+    if (mSentryRoles != null) {
+      for (MSentryRole mSentryRole : mSentryRoles) {
+        existRoleNames.add(mSentryRole.getRoleName());
+      }
+    }
+    return existRoleNames;
+  }
+
+  // get the all exist groups
+  private Map<String, MSentryGroup> getGroupNameTGroupMap(PersistenceManager 
pm) {
+    Query query = pm.newQuery(MSentryGroup.class);
+    List<MSentryGroup> mSentryGroups = (List<MSentryGroup>) query.execute();
+    Map<String, MSentryGroup> existGroupsMap = Maps.newHashMap();
+    if (mSentryGroups != null) {
+      // change the List<MSentryGroup> -> Map<roleName, Set<MSentryGroup>>
+      for (MSentryGroup mSentryGroup : mSentryGroups) {
+        existGroupsMap.put(mSentryGroup.getGroupName(), mSentryGroup);
+      }
+    }
+    return existGroupsMap;
+  }
+
+  // get the all exist privileges
+  private List<MSentryPrivilege> getPrivilegesList(PersistenceManager pm) {
+    Query query = pm.newQuery(MSentryPrivilege.class);
+    List<MSentryPrivilege> resultList = (List<MSentryPrivilege>) 
query.execute();
+    if (resultList == null) {
+      resultList = Lists.newArrayList();
+    }
+    return resultList;
+  }
+
+  @VisibleForTesting
+  protected Map<String, MSentryRole> getRolesMap() {
+    boolean rollbackTransaction = true;
+    PersistenceManager pm = null;
+    try {
+      pm = openTransaction();
+
+      Query query = pm.newQuery(MSentryRole.class);
+      List<MSentryRole> mSentryRoles = (List<MSentryRole>) query.execute();
+      Map<String, MSentryRole> existRolesMap = Maps.newHashMap();
+      if (mSentryRoles != null) {
+        // change the List<MSentryRole> -> Map<roleName, Set<MSentryRole>>
+        for (MSentryRole mSentryRole : mSentryRoles) {
+          existRolesMap.put(mSentryRole.getRoleName(), mSentryRole);
+        }
+      }
+
+      commitTransaction(pm);
+      rollbackTransaction = false;
+      return existRolesMap;
+    } finally {
+      if (rollbackTransaction) {
+        rollbackTransaction(pm);
+      }
+    }
+  }
+
+  @VisibleForTesting
+  protected Map<String, MSentryGroup> getGroupNameTGroupMap() {
+    boolean rollbackTransaction = true;
+    PersistenceManager pm = null;
+    try {
+      pm = openTransaction();
+      Map<String, MSentryGroup> resultMap = getGroupNameTGroupMap(pm);
+      commitTransaction(pm);
+      rollbackTransaction = false;
+      return resultMap;
+    } finally {
+      if (rollbackTransaction) {
+        rollbackTransaction(pm);
+      }
+    }
+  }
+
+  @VisibleForTesting
+  protected List<MSentryPrivilege> getPrivilegesList() {
+    boolean rollbackTransaction = true;
+    PersistenceManager pm = null;
+    try {
+      pm = openTransaction();
+      List<MSentryPrivilege> resultList = getPrivilegesList(pm);
+      commitTransaction(pm);
+      rollbackTransaction = false;
+      return resultList;
+    } finally {
+      if (rollbackTransaction) {
+        rollbackTransaction(pm);
+      }
+    }
+  }
+
+  /**
+   * Import the sentry mapping data.
+   * 
+   * @param tSentryMappingData
+   *        Include 2 maps to save the mapping data, the following is the 
example of the data
+   *        structure:
+   *        for the following mapping data:
+   *        group1=role1,role2
+   *        group2=role2,role3
+   *        role1=server=server1->db=db1
+   *        
role2=server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2
+   *        role3=server=server1->url=hdfs://localhost/path
+   * 
+   *        The GroupRolesMap in TSentryMappingData will be saved as:
+   *        {
+   *        TSentryGroup(group1)={role1, role2},
+   *        TSentryGroup(group2)={role2, role3}
+   *        }
+   *        The RolePrivilegesMap in TSentryMappingData will be saved as:
+   *        {
+   *        role1={TSentryPrivilege(server=server1->db=db1)},
+   *        role2={TSentryPrivilege(server=server1->db=db1->table=tbl1),
+   *        TSentryPrivilege(server=server1->db=db1->table=tbl2)},
+   *        role3={TSentryPrivilege(server=server1->url=hdfs://localhost/path)}
+   *        }
+   * @param isOverwriteForRole
+   *        The option for merging or overwriting the existing data during 
import, true for
+   *        overwriting, false for merging
+   */
+  public void importSentryMetaData(TSentryMappingData tSentryMappingData, 
boolean isOverwriteForRole)
+      throws Exception {
+    boolean rollbackTransaction = true;
+    PersistenceManager pm = null;
+    // change all role name in lowercase
+    TSentryMappingData mappingData = lowercaseRoleName(tSentryMappingData);
+    try {
+      pm = openTransaction();
+      Set<String> existRoleNames = getAllRoleNames(pm);
+      //
+      Map<String, Set<TSentryGroup>> importedRoleGroupsMap = 
covertToRoleNameTGroupsMap(mappingData
+          .getGroupRolesMap());
+      Set<String> importedRoleNames = importedRoleGroupsMap.keySet();
+      // if import with overwrite role, drop the duplicated roles in current 
DB first.
+      if (isOverwriteForRole) {
+        dropDuplicatedRoleForImport(pm, existRoleNames, importedRoleNames);
+        // refresh the existRoleNames for the drop role
+        existRoleNames = getAllRoleNames(pm);
+      }
+
+      // import the mapping data for [role,privilege], the existRoleNames will 
be updated
+      importSentryRolePrivilegeMapping(pm, existRoleNames, 
mappingData.getRolePrivilegesMap());
+
+      importSentryGroupRoleMapping(pm, existRoleNames, importedRoleGroupsMap);
+
+      commitTransaction(pm);
+      rollbackTransaction = false;
+    } finally {
+      if (rollbackTransaction) {
+        rollbackTransaction(pm);
+      }
+    }
+  }
+
+  // covert the Map[group->roles] to Map[role->groups]
+  private Map<String, Set<TSentryGroup>> covertToRoleNameTGroupsMap(
+      Map<String, Set<String>> groupRolesMap) {
+    Map<String, Set<TSentryGroup>> roleGroupsMap = Maps.newHashMap();
+    if (groupRolesMap != null) {
+      for (String groupName : groupRolesMap.keySet()) {
+        Set<String> roleNames = groupRolesMap.get(groupName);
+        if (roleNames != null) {
+          for (String roleName : roleNames) {
+            Set<TSentryGroup> tSentryGroups = roleGroupsMap.get(roleName);
+            if (tSentryGroups == null) {
+              tSentryGroups = Sets.newHashSet();
+            }
+            tSentryGroups.add(new TSentryGroup(groupName));
+            roleGroupsMap.put(roleName, tSentryGroups);
+          }
+        }
+      }
+    }
+    return roleGroupsMap;
+  }
+
+  private void importSentryGroupRoleMapping(PersistenceManager pm, Set<String> 
existRoleNames,
+      Map<String, Set<TSentryGroup>> importedRoleGroupsMap) throws Exception {
+    if (importedRoleGroupsMap == null || importedRoleGroupsMap.keySet() == 
null) {
+      return;
+    }
+    for (String roleName : importedRoleGroupsMap.keySet()) {
+      if (!existRoleNames.contains(roleName)) {
+        createSentryRoleCore(pm, roleName);
+      }
+      alterSentryRoleAddGroupsCore(pm, roleName, 
importedRoleGroupsMap.get(roleName));
+    }
+  }
+
+  // drop all duplicated with the imported role
+  private void dropDuplicatedRoleForImport(PersistenceManager pm, Set<String> 
existRoleNames,
+      Set<String> importedRoleNames) throws Exception {
+    Set<String> duplicatedRoleNames = Sets.intersection(existRoleNames, 
importedRoleNames);
+    for (String droppedRoleName : duplicatedRoleNames) {
+      dropSentryRoleCore(pm, droppedRoleName);
+    }
+  }
+
+  // change all role name in lowercase
+  private TSentryMappingData lowercaseRoleName(TSentryMappingData 
tSentryMappingData) {
+    Map<String, Set<String>> sentryGroupRolesMap = 
tSentryMappingData.getGroupRolesMap();
+    Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap = 
tSentryMappingData
+        .getRolePrivilegesMap();
+
+    Map<String, Set<String>> newSentryGroupRolesMap = Maps.newHashMap();
+    Map<String, Set<TSentryPrivilege>> newSentryRolePrivilegesMap = 
Maps.newHashMap();
+    // for mapping data [group,role]
+    for (String groupName : sentryGroupRolesMap.keySet()) {
+      Collection<String> lowcaseRoles = 
Collections2.transform(sentryGroupRolesMap.get(groupName),
+          new Function<String, String>() {
+            @Override
+            public String apply(String input) {
+              return input.toString().toLowerCase();
+            }
+          });
+      newSentryGroupRolesMap.put(groupName, Sets.newHashSet(lowcaseRoles));
+    }
+
+    // for mapping data [role,privilege]
+    for (String roleName : sentryRolePrivilegesMap.keySet()) {
+      newSentryRolePrivilegesMap.put(roleName.toLowerCase(), 
sentryRolePrivilegesMap.get(roleName));
+    }
+
+    tSentryMappingData.setGroupRolesMap(newSentryGroupRolesMap);
+    tSentryMappingData.setRolePrivilegesMap(newSentryRolePrivilegesMap);
+    return tSentryMappingData;
+  }
+
+  // import the mapping data for [role,privilege]
+  private void importSentryRolePrivilegeMapping(PersistenceManager pm, 
Set<String> existRoleNames,
+      Map<String, Set<TSentryPrivilege>> sentryRolePrivilegesMap) throws 
Exception {
+    if (sentryRolePrivilegesMap != null) {
+      for (String roleName : sentryRolePrivilegesMap.keySet()) {
+        // if the rolenName doesn't exist, create it.
+        if (!existRoleNames.contains(roleName)) {
+          createSentryRoleCore(pm, roleName);
+          existRoleNames.add(roleName);
+        }
+        // get the privileges for the role
+        Set<TSentryPrivilege> tSentryPrivileges = 
sentryRolePrivilegesMap.get(roleName);
+        for (TSentryPrivilege tSentryPrivilege : tSentryPrivileges) {
+          alterSentryRoleGrantPrivilegeCore(pm, roleName, tSentryPrivilege);
+        }
+      }
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/92cde111/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
index 05cbfb6..9c2d384 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClient.java
@@ -178,4 +178,12 @@ public interface SentryPolicyServiceClient {
   public String getConfigValue(String propertyName, String defaultValue) 
throws SentryUserException;
 
   public void close();
+
+  // Import the sentry mapping data with map structure
+  public void importPolicy(Map<String, Map<String, Set<String>>> 
policyFileMappingData,
+      String requestorUserName, boolean isOverwriteRole) throws 
SentryUserException;
+
+  // export the sentry mapping data with map structure
+  public Map<String, Map<String, Set<String>>> exportPolicy(String 
requestorUserName)
+      throws SentryUserException;
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/92cde111/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
index 533a28c..09b3d99 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyServiceClientDefaultImpl.java
@@ -27,6 +27,7 @@ import java.util.Set;
 
 import javax.security.auth.callback.CallbackHandler;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.net.NetUtils;
 import org.apache.hadoop.security.SaslRpcServer;
@@ -38,6 +39,8 @@ import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.model.db.AccessConstants;
 import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.provider.common.PolicyFileConstants;
+import org.apache.sentry.service.thrift.SentryServiceUtil;
 import org.apache.sentry.service.thrift.ServiceConstants.ClientConfig;
 import org.apache.sentry.service.thrift.ServiceConstants.PrivilegeScope;
 import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
@@ -58,6 +61,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
 public class SentryPolicyServiceClientDefaultImpl implements 
SentryPolicyServiceClient {
@@ -816,4 +820,111 @@ public class SentryPolicyServiceClientDefaultImpl 
implements SentryPolicyService
       transport.close();
     }
   }
+
+  /**
+   * Import the sentry mapping data, convert the mapping data from map 
structure to
+   * TSentryMappingData, and call the import API.
+   * 
+   * @param policyFileMappingData
+   *        Include 2 maps to save the mapping data, the following is the 
example of the data
+   *        structure:
+   *        for the following mapping data:
+   *        group1=role1,role2
+   *        group2=role2,role3
+   *        role1=server=server1->db=db1
+   *        
role2=server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2
+   *        role3=server=server1->url=hdfs://localhost/path
+   * 
+   *        The policyFileMappingData will be inputed as:
+   *        {
+   *          groups={[group1={role1, role2}], group2=[role2, role3]},
+   *          roles={role1=[server=server1->db=db1],
+   *                 
role2=[server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2],
+   *                 role3=[server=server1->url=hdfs://localhost/path]
+   *                }
+   *        }
+   * @param requestorUserName
+   *        The name of the request user
+   */
+  public void importPolicy(Map<String, Map<String, Set<String>>> 
policyFileMappingData,
+      String requestorUserName, boolean isOverwriteRole)
+      throws SentryUserException {
+    try {
+      TSentryMappingData tSentryMappingData = new TSentryMappingData();
+      // convert the mapping data for [group,role] from map structure to
+      // TSentryMappingData.GroupRolesMap
+      
tSentryMappingData.setGroupRolesMap(policyFileMappingData.get(PolicyFileConstants.GROUPS));
+      // convert the mapping data for [role,privilege] from map structure to
+      // TSentryMappingData.RolePrivilegesMap
+      tSentryMappingData
+          
.setRolePrivilegesMap(convertRolePrivilegesMapForSentryDB(policyFileMappingData
+              .get(PolicyFileConstants.ROLES)));
+      TSentryImportMappingDataRequest request = new 
TSentryImportMappingDataRequest(
+          ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName, 
isOverwriteRole,
+          tSentryMappingData);
+      TSentryImportMappingDataResponse response = 
client.import_sentry_mapping_data(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  // convert the mapping data for [role,privilege] from map structure to
+  // TSentryMappingData.RolePrivilegesMap
+  private Map<String, Set<TSentryPrivilege>> 
convertRolePrivilegesMapForSentryDB(
+      Map<String, Set<String>> rolePrivilegesMap) {
+    Map<String, Set<TSentryPrivilege>> rolePrivilegesMapResult = 
Maps.newHashMap();
+    if (rolePrivilegesMap != null) {
+      for (String tempRoleName : rolePrivilegesMap.keySet()) {
+        Set<TSentryPrivilege> tempTSentryPrivileges = Sets.newHashSet();
+        Set<String> tempPrivileges = rolePrivilegesMap.get(tempRoleName);
+        for (String tempPrivilege : tempPrivileges) {
+          
tempTSentryPrivileges.add(SentryServiceUtil.convertToTSentryPrivilege(tempPrivilege));
+        }
+        rolePrivilegesMapResult.put(tempRoleName, tempTSentryPrivileges);
+      }
+    }
+    return rolePrivilegesMapResult;
+  }
+
+  // export the sentry mapping data with map structure
+  public Map<String, Map<String, Set<String>>> exportPolicy(String 
requestorUserName)
+      throws SentryUserException {
+    TSentryExportMappingDataRequest request = new 
TSentryExportMappingDataRequest(
+        ThriftConstants.TSENTRY_SERVICE_VERSION_CURRENT, requestorUserName);
+    try {
+      TSentryExportMappingDataResponse response = 
client.export_sentry_mapping_data(request);
+      Status.throwIfNotOk(response.getStatus());
+      TSentryMappingData tSentryMappingData = response.getMappingData();
+      Map<String, Map<String, Set<String>>> resultMap = Maps.newHashMap();
+      resultMap.put(PolicyFileConstants.GROUPS, 
tSentryMappingData.getGroupRolesMap());
+      resultMap.put(PolicyFileConstants.ROLES,
+          
convertRolePrivilegesMapForPolicyFile(tSentryMappingData.getRolePrivilegesMap()));
+      return resultMap;
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  // convert the mapping data for [roleName,privilege] from 
TSentryMappingData.RolePrivilegesMap to
+  // map structure
+  private Map<String, Set<String>> convertRolePrivilegesMapForPolicyFile(
+      Map<String, Set<TSentryPrivilege>> rolePrivilegesMap) {
+    Map<String, Set<String>> rolePrivilegesMapForFile = Maps.newHashMap();
+    if (rolePrivilegesMap != null) {
+      for (String tempRoleName : rolePrivilegesMap.keySet()) {
+        Set<TSentryPrivilege> tempSentryPrivileges = 
rolePrivilegesMap.get(tempRoleName);
+        Set<String> tempStrPrivileges = Sets.newHashSet();
+        for (TSentryPrivilege tSentryPrivilege : tempSentryPrivileges) {
+          // convert TSentryPrivilege to privilege in string
+          String privilegeStr = 
SentryServiceUtil.convertTSentryPrivilegeToStr(tSentryPrivilege);
+          if (!StringUtils.isEmpty(privilegeStr)) {
+            tempStrPrivileges.add(privilegeStr);
+          }
+        }
+        rolePrivilegesMapForFile.put(tempRoleName, tempStrPrivileges);
+      }
+    }
+    return rolePrivilegesMapForFile;
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/92cde111/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
index 406daa0..ea9fae9 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/thrift/SentryPolicyStoreProcessor.java
@@ -857,4 +857,57 @@ public class SentryPolicyStoreProcessor implements 
SentryPolicyService.Iface {
     }
   }
 
+  // get the sentry mapping data and return the data with map structure
+  @Override
+  public TSentryExportMappingDataResponse export_sentry_mapping_data(
+      TSentryExportMappingDataRequest request) throws TException {
+    TSentryExportMappingDataResponse response = new 
TSentryExportMappingDataResponse();
+    try {
+      String requestor = request.getRequestorUserName();
+      Set<String> memberGroups = getRequestorGroups(requestor);
+      if (!inAdminGroups(memberGroups)) {
+        // disallow non-admin to import the metadata of sentry
+        throw new SentryAccessDeniedException("Access denied to " + requestor
+            + " for export the metadata of sentry.");
+      }
+      TSentryMappingData tSentryMappingData = new TSentryMappingData();
+      
tSentryMappingData.setGroupRolesMap(sentryStore.getGroupNameRoleNamesMap());
+      
tSentryMappingData.setRolePrivilegesMap(sentryStore.getRoleNameTPrivilegesMap());
+      response.setMappingData(tSentryMappingData);
+      response.setStatus(Status.OK());
+    } catch (Exception e) {
+      String msg = "Unknown error for request: " + request + ", message: " + 
e.getMessage();
+      LOGGER.error(msg, e);
+      response.setMappingData(new TSentryMappingData());
+      response.setStatus(Status.RuntimeError(msg, e));
+    }
+    return response;
+  }
+
+  // import the sentry mapping data
+  @Override
+  public TSentryImportMappingDataResponse import_sentry_mapping_data(
+      TSentryImportMappingDataRequest request) throws TException {
+    TSentryImportMappingDataResponse response = new 
TSentryImportMappingDataResponse();
+    try {
+      String requestor = request.getRequestorUserName();
+      Set<String> memberGroups = getRequestorGroups(requestor);
+      if (!inAdminGroups(memberGroups)) {
+        // disallow non-admin to import the metadata of sentry
+        throw new SentryAccessDeniedException("Access denied to " + requestor
+            + " for import the metadata of sentry.");
+      }
+      sentryStore.importSentryMetaData(request.getMappingData(), 
request.isOverwriteRole());
+      response.setStatus(Status.OK());
+    } catch (SentryInvalidInputException e) {
+      String msg = "Invalid input privilege object";
+      LOGGER.error(msg, e);
+      response.setStatus(Status.InvalidInput(msg, e));
+    } catch (Exception e) {
+      String msg = "Unknown error for request: " + request + ", message: " + 
e.getMessage();
+      LOGGER.error(msg, e);
+      response.setStatus(Status.RuntimeError(msg, e));
+    }
+    return response;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/92cde111/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java
 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java
new file mode 100644
index 0000000..46798a0
--- /dev/null
+++ 
b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java
@@ -0,0 +1,127 @@
+/**
+ * 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.sentry.service.thrift;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.sentry.provider.common.KeyValue;
+import org.apache.sentry.provider.common.PolicyFileConstants;
+import org.apache.sentry.provider.common.ProviderConstants;
+import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
+import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
+import org.apache.sentry.service.thrift.ServiceConstants.PrivilegeScope;
+
+import com.google.common.collect.Lists;
+
+public class SentryServiceUtil {
+
+  // parse the privilege in String and get the TSentryPrivilege as result
+  public static TSentryPrivilege convertToTSentryPrivilege(String 
privilegeStr) {
+    TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
+    for (String authorizable : 
ProviderConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
+      KeyValue tempKV = new KeyValue(authorizable);
+      String key = tempKV.getKey();
+      String value = tempKV.getValue();
+
+      if (PolicyFileConstants.PRIVILEGE_SERVER_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setServerName(value);
+      } else if 
(PolicyFileConstants.PRIVILEGE_DATABASE_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setDbName(value);
+      } else if 
(PolicyFileConstants.PRIVILEGE_TABLE_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setTableName(value);
+      } else if 
(PolicyFileConstants.PRIVILEGE_COLUMN_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setColumnName(value);
+      } else if (PolicyFileConstants.PRIVILEGE_URI_NAME.equalsIgnoreCase(key)) 
{
+        tSentryPrivilege.setURI(value);
+      } else if 
(PolicyFileConstants.PRIVILEGE_ACTION_NAME.equalsIgnoreCase(key)) {
+        tSentryPrivilege.setAction(value);
+      } else if 
(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME.equalsIgnoreCase(key)) {
+        TSentryGrantOption grantOption = "true".equalsIgnoreCase(value) ? 
TSentryGrantOption.TRUE
+            : TSentryGrantOption.FALSE;
+        tSentryPrivilege.setGrantOption(grantOption);
+      }
+    }
+    tSentryPrivilege.setPrivilegeScope(getPrivilegeScope(tSentryPrivilege));
+    return tSentryPrivilege;
+  }
+
+  // for the different hierarchy for hive:
+  // 1: server->url
+  // 2: server->database->table->column
+  // if both of them are found in the privilege string, the privilege scope 
will be set as
+  // PrivilegeScope.URI
+  public static String getPrivilegeScope(TSentryPrivilege tSentryPrivilege) {
+    PrivilegeScope privilegeScope = PrivilegeScope.SERVER;
+    if (!StringUtils.isEmpty(tSentryPrivilege.getURI())) {
+      privilegeScope = PrivilegeScope.URI;
+    } else if (!StringUtils.isEmpty(tSentryPrivilege.getColumnName())) {
+      privilegeScope = PrivilegeScope.COLUMN;
+    } else if (!StringUtils.isEmpty(tSentryPrivilege.getTableName())) {
+      privilegeScope = PrivilegeScope.TABLE;
+    } else if (!StringUtils.isEmpty(tSentryPrivilege.getDbName())) {
+      privilegeScope = PrivilegeScope.DATABASE;
+    }
+    return privilegeScope.toString();
+  }
+
+  // convert TSentryPrivilege to privilege in string
+  public static String convertTSentryPrivilegeToStr(TSentryPrivilege 
tSentryPrivilege) {
+    List<String> privileges = Lists.newArrayList();
+    if (tSentryPrivilege != null) {
+      String serverName = tSentryPrivilege.getServerName();
+      String dbName = tSentryPrivilege.getDbName();
+      String tableName = tSentryPrivilege.getTableName();
+      String columnName = tSentryPrivilege.getColumnName();
+      String uri = tSentryPrivilege.getURI();
+      String action = tSentryPrivilege.getAction();
+      String grantOption = (tSentryPrivilege.getGrantOption() == 
TSentryGrantOption.TRUE ? "true"
+          : "false");
+      if (!StringUtils.isEmpty(serverName)) {
+        
privileges.add(ProviderConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_SERVER_NAME,
+            serverName));
+        if (!StringUtils.isEmpty(uri)) {
+          
privileges.add(ProviderConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_URI_NAME,
+              uri));
+        } else if (!StringUtils.isEmpty(dbName)) {
+          privileges.add(ProviderConstants.KV_JOINER.join(
+              PolicyFileConstants.PRIVILEGE_DATABASE_NAME, dbName));
+          if (!StringUtils.isEmpty(tableName)) {
+            privileges.add(ProviderConstants.KV_JOINER.join(
+                PolicyFileConstants.PRIVILEGE_TABLE_NAME, tableName));
+            if (!StringUtils.isEmpty(columnName)) {
+              privileges.add(ProviderConstants.KV_JOINER.join(
+                  PolicyFileConstants.PRIVILEGE_COLUMN_NAME, columnName));
+            }
+          }
+        }
+        if (!StringUtils.isEmpty(action)) {
+          privileges.add(ProviderConstants.KV_JOINER.join(
+              PolicyFileConstants.PRIVILEGE_ACTION_NAME, action));
+        }
+      }
+      // only append the grant option to privilege string if it's true
+      if ("true".equals(grantOption)) {
+        privileges.add(ProviderConstants.KV_JOINER.join(
+            PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME, grantOption));
+      }
+    }
+    return ProviderConstants.AUTHORIZABLE_JOINER.join(privileges);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/92cde111/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
----------------------------------------------------------------------
diff --git 
a/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
 
b/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
index 5803cc4..40889e8 100644
--- 
a/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
+++ 
b/sentry-provider/sentry-provider-db/src/main/resources/sentry_policy_service.thrift
@@ -232,6 +232,33 @@ struct TSentryConfigValueResponse {
 2: optional string value
 }
 
+# struct for the mapping data like group to role, role to privilege
+struct TSentryMappingData {
+1: optional map<string, set<string>> groupRolesMap,               # for the 
groupName -> role mapping
+2: optional map<string, set<TSentryPrivilege>>  rolePrivilegesMap  # for the 
roleName -> privilege mapping
+}
+
+struct TSentryExportMappingDataRequest {
+1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
+2: required string requestorUserName # user on whose behalf the request is 
issued
+}
+
+struct TSentryExportMappingDataResponse {
+1: required sentry_common_service.TSentryResponseStatus status,
+2: required TSentryMappingData mappingData
+}
+
+struct TSentryImportMappingDataRequest {
+1: required i32 protocol_version = sentry_common_service.TSENTRY_SERVICE_V1,
+2: required string requestorUserName, # user on whose behalf the request is 
issued
+3: required bool overwriteRole = false, # if overwrite the exist role with the 
imported privileges, default is false 
+4: required TSentryMappingData mappingData
+}
+
+struct TSentryImportMappingDataResponse {
+1: required sentry_common_service.TSentryResponseStatus status
+}
+
 service SentryPolicyService
 {
   TCreateSentryRoleResponse create_sentry_role(1:TCreateSentryRoleRequest 
request)
@@ -250,11 +277,17 @@ service SentryPolicyService
   # For use with ProviderBackend.getPrivileges only
   TListSentryPrivilegesForProviderResponse 
list_sentry_privileges_for_provider(1:TListSentryPrivilegesForProviderRequest 
request)
 
- TDropPrivilegesResponse drop_sentry_privilege(1:TDropPrivilegesRequest 
request);
+  TDropPrivilegesResponse drop_sentry_privilege(1:TDropPrivilegesRequest 
request);
+
+  TRenamePrivilegesResponse rename_sentry_privilege(1:TRenamePrivilegesRequest 
request);
+
+  TListSentryPrivilegesByAuthResponse 
list_sentry_privileges_by_authorizable(1:TListSentryPrivilegesByAuthRequest 
request);
 
- TRenamePrivilegesResponse rename_sentry_privilege(1:TRenamePrivilegesRequest 
request);
+  TSentryConfigValueResponse 
get_sentry_config_value(1:TSentryConfigValueRequest request);
 
- TListSentryPrivilegesByAuthResponse 
list_sentry_privileges_by_authorizable(1:TListSentryPrivilegesByAuthRequest 
request);
+  # export the mapping data in sentry
+  TSentryExportMappingDataResponse 
export_sentry_mapping_data(1:TSentryExportMappingDataRequest request);
 
- TSentryConfigValueResponse 
get_sentry_config_value(1:TSentryConfigValueRequest request)
+  # import the mapping data in sentry
+  TSentryImportMappingDataResponse 
import_sentry_mapping_data(1:TSentryImportMappingDataRequest request);
 }


Reply via email to