You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by sd...@apache.org on 2015/08/28 10:01:36 UTC

[4/5] incubator-sentry git commit: SENTRY-590: Client factory for generic authorization model (Dapeng Sun, Reviewed by: Guoquan Shen)

SENTRY-590: Client factory for generic authorization model (Dapeng Sun, Reviewed by: Guoquan Shen)


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

Branch: refs/heads/hive_plugin_v2
Commit: fd293e117a31f7d1d1b6994b6a3a026e5d2abfe4
Parents: e11062d
Author: Sun Dapeng <sd...@apache.org>
Authored: Thu Aug 20 13:47:38 2015 +0800
Committer: Sun Dapeng <sd...@apache.org>
Committed: Thu Aug 20 13:47:38 2015 +0800

----------------------------------------------------------------------
 .../binding/solr/authz/SolrAuthzBinding.java    |   3 +-
 .../sentry/sqoop/binding/SqoopAuthBinding.java  |   3 +-
 .../generic/SentryGenericProviderBackend.java   |   3 +-
 .../thrift/SentryGenericServiceClient.java      | 405 +-------------
 .../SentryGenericServiceClientDefaultImpl.java  | 538 +++++++++++++++++++
 .../SentryGenericServiceClientFactory.java      |  34 ++
 .../TestSentryGenericServiceIntegration.java    |   5 +-
 .../AbstractSolrSentryTestWithDbProvider.java   |   3 +-
 .../e2e/sqoop/AbstractSqoopSentryTestBase.java  |   3 +-
 9 files changed, 608 insertions(+), 389 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java b/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java
index 2accbbf..6980c7c 100644
--- a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java
+++ b/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java
@@ -47,6 +47,7 @@ import org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvide
 import org.apache.sentry.provider.common.ProviderBackend;
 import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
 import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
@@ -261,7 +262,7 @@ public class SolrAuthzBinding {
   }
 
   public SentryGenericServiceClient getClient() throws Exception {
-    return new SentryGenericServiceClient(authzConf);
+    return SentryGenericServiceClientFactory.create(authzConf);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
index ee0fbfa..42638f8 100644
--- a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
@@ -35,6 +35,7 @@ import org.apache.sentry.provider.common.AuthorizationProvider;
 import org.apache.sentry.provider.common.ProviderBackend;
 import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
 import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
@@ -154,7 +155,7 @@ public class SqoopAuthBinding {
    *  was committed to master, the getClient method was needed to refactor using the connection pool
    */
   private SentryGenericServiceClient getClient() throws Exception {
-    return new SentryGenericServiceClient(authConf);
+    return SentryGenericServiceClientFactory.create(authConf);
   }
 
   public void createRole(final Subject subject, final String role) throws SqoopException {

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
index 50edeb3..d7cb814 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/SentryGenericProviderBackend.java
@@ -29,6 +29,7 @@ import org.apache.sentry.core.common.SentryConfigurationException;
 import org.apache.sentry.provider.common.ProviderBackend;
 import org.apache.sentry.provider.common.ProviderBackendContext;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryRole;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -66,7 +67,7 @@ public class SentryGenericProviderBackend implements ProviderBackend {
    *  was committed to master, the getClient method was needed to refactor using the connection pool
    */
   private SentryGenericServiceClient getClient() throws Exception {
-    return new SentryGenericServiceClient(conf);
+    return SentryGenericServiceClientFactory.create(conf);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java
index 9f4a292..4b31b0b 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClient.java
@@ -17,148 +17,14 @@
  */
 package org.apache.sentry.provider.db.generic.service.thrift;
 
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.security.PrivilegedExceptionAction;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
-import javax.security.auth.callback.CallbackHandler;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.net.NetUtils;
-import org.apache.hadoop.security.SaslRpcServer;
-import org.apache.hadoop.security.SaslRpcServer.AuthMethod;
-import org.apache.hadoop.security.SecurityUtil;
-import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.sentry.SentryUserException;
 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.service.thrift.ServiceConstants.ClientConfig;
-import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
-import org.apache.sentry.service.thrift.Status;
-import org.apache.sentry.service.thrift.sentry_common_serviceConstants;
-import org.apache.thrift.TException;
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.protocol.TMultiplexedProtocol;
-import org.apache.thrift.transport.TSaslClientTransport;
-import org.apache.thrift.transport.TSocket;
-import org.apache.thrift.transport.TTransport;
-import org.apache.thrift.transport.TTransportException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-
-public class SentryGenericServiceClient {
-  private final Configuration conf;
-  private final InetSocketAddress serverAddress;
-  private final boolean kerberos;
-  private final String[] serverPrincipalParts;
-  private SentryGenericPolicyService.Client client;
-  private TTransport transport;
-  private int connectionTimeout;
-  private static final Logger LOGGER = LoggerFactory
-                                       .getLogger(SentryGenericServiceClient.class);
-  private static final String THRIFT_EXCEPTION_MESSAGE = "Thrift exception occured ";
-
-  /**
-   * This transport wraps the Sasl transports to set up the right UGI context for open().
-   */
-  public static class UgiSaslClientTransport extends TSaslClientTransport {
-    protected UserGroupInformation ugi = null;
-
-    public UgiSaslClientTransport(String mechanism, String authorizationId,
-        String protocol, String serverName, Map<String, String> props,
-        CallbackHandler cbh, TTransport transport, boolean wrapUgi)
-        throws IOException {
-      super(mechanism, authorizationId, protocol, serverName, props, cbh,
-          transport);
-      if (wrapUgi) {
-        ugi = UserGroupInformation.getLoginUser();
-      }
-    }
-
-    // open the SASL transport with using the current UserGroupInformation
-    // This is needed to get the current login context stored
-    @Override
-    public void open() throws TTransportException {
-      if (ugi == null) {
-        baseOpen();
-      } else {
-        try {
-          if (ugi.isFromKeytab()) {
-            ugi.checkTGTAndReloginFromKeytab();
-          }
-          ugi.doAs(new PrivilegedExceptionAction<Void>() {
-            public Void run() throws TTransportException {
-              baseOpen();
-              return null;
-            }
-          });
-        } catch (IOException e) {
-          throw new TTransportException("Failed to open SASL transport", e);
-        } catch (InterruptedException e) {
-          throw new TTransportException(
-              "Interrupted while opening underlying transport", e);
-        }
-      }
-    }
-
-    private void baseOpen() throws TTransportException {
-      super.open();
-    }
-  }
-
-  public SentryGenericServiceClient(Configuration conf) throws IOException {
-    this.conf = conf;
-    Preconditions.checkNotNull(this.conf, "Configuration object cannot be null");
-    this.serverAddress = NetUtils.createSocketAddr(Preconditions.checkNotNull(
-                           conf.get(ClientConfig.SERVER_RPC_ADDRESS), "Config key "
-                           + ClientConfig.SERVER_RPC_ADDRESS + " is required"), conf.getInt(
-                           ClientConfig.SERVER_RPC_PORT, ClientConfig.SERVER_RPC_PORT_DEFAULT));
-    this.connectionTimeout = conf.getInt(ClientConfig.SERVER_RPC_CONN_TIMEOUT,
-                                         ClientConfig.SERVER_RPC_CONN_TIMEOUT_DEFAULT);
-    kerberos = ServerConfig.SECURITY_MODE_KERBEROS.equalsIgnoreCase(
-        conf.get(ServerConfig.SECURITY_MODE, ServerConfig.SECURITY_MODE_KERBEROS).trim());
-    transport = new TSocket(serverAddress.getHostName(),
-        serverAddress.getPort(), connectionTimeout);
-    if (kerberos) {
-      String serverPrincipal = Preconditions.checkNotNull(conf.get(ServerConfig.PRINCIPAL), ServerConfig.PRINCIPAL + " is required");
-
-      // Resolve server host in the same way as we are doing on server side
-      serverPrincipal = SecurityUtil.getServerPrincipal(serverPrincipal, serverAddress.getAddress());
-      LOGGER.debug("Using server kerberos principal: " + serverPrincipal);
-
-      serverPrincipalParts = SaslRpcServer.splitKerberosName(serverPrincipal);
-      Preconditions.checkArgument(serverPrincipalParts.length == 3,
-           "Kerberos principal should have 3 parts: " + serverPrincipal);
-      boolean wrapUgi = "true".equalsIgnoreCase(conf
-          .get(ServerConfig.SECURITY_USE_UGI_TRANSPORT, "true"));
-      transport = new UgiSaslClientTransport(AuthMethod.KERBEROS.getMechanismName(),
-          null, serverPrincipalParts[0], serverPrincipalParts[1],
-          ClientConfig.SASL_PROPERTIES, null, transport, wrapUgi);
-    } else {
-      serverPrincipalParts = null;
-    }
-    try {
-      transport.open();
-    } catch (TTransportException e) {
-      throw new IOException("Transport exception while opening transport: " + e.getMessage(), e);
-    }
-    LOGGER.debug("Successfully opened transport: " + transport + " to " + serverAddress);
-    TMultiplexedProtocol protocol = new TMultiplexedProtocol(
-      new TBinaryProtocol(transport),
-      SentryGenericPolicyProcessor.SENTRY_GENERIC_SERVICE_NAME);
-    client = new SentryGenericPolicyService.Client(protocol);
-    LOGGER.debug("Successfully created client");
-  }
-
 
+public interface SentryGenericServiceClient {
 
   /**
    * Create a sentry role
@@ -167,38 +33,11 @@ public class SentryGenericServiceClient {
    * @param component: The request is issued to which component
    * @throws SentryUserException
    */
-  public synchronized void createRole(String requestorUserName, String roleName, String component)
-  throws SentryUserException {
-    TCreateSentryRoleRequest request = new TCreateSentryRoleRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setRequestorUserName(requestorUserName);
-    request.setRoleName(roleName);
-    request.setComponent(component);
-    try {
-      TCreateSentryRoleResponse response = client.create_sentry_role(request);
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+  public void createRole(String requestorUserName, String roleName,
+      String component) throws SentryUserException;
 
-  public void createRoleIfNotExist(String requestorUserName, String roleName, String component) throws SentryUserException {
-    TCreateSentryRoleRequest request = new TCreateSentryRoleRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setRequestorUserName(requestorUserName);
-    request.setRoleName(roleName);
-    request.setComponent(component);
-    try {
-      TCreateSentryRoleResponse response = client.create_sentry_role(request);
-      Status status = Status.fromCode(response.getStatus().getValue());
-      if (status == Status.ALREADY_EXISTS) {
-        return;
-      }
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+  public void createRoleIfNotExist(String requestorUserName,
+      String roleName, String component) throws SentryUserException;
 
   /**
    * Drop a sentry role
@@ -207,37 +46,11 @@ public class SentryGenericServiceClient {
    * @param component: The request is issued to which component
    * @throws SentryUserException
    */
-  public void dropRole(String requestorUserName,
-      String roleName, String component)
-  throws SentryUserException {
-    dropRole(requestorUserName, roleName, component, false);
-  }
-
-  public void dropRoleIfExists(String requestorUserName,
-      String roleName, String component)
-  throws SentryUserException {
-    dropRole(requestorUserName, roleName, component, true);
-  }
+  public void dropRole(String requestorUserName, String roleName,
+      String component) throws SentryUserException;
 
-  private void dropRole(String requestorUserName,
-      String roleName, String component , boolean ifExists)
-  throws SentryUserException {
-    TDropSentryRoleRequest request = new TDropSentryRoleRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setRequestorUserName(requestorUserName);
-    request.setRoleName(roleName);
-    request.setComponent(component);
-    try {
-      TDropSentryRoleResponse response = client.drop_sentry_role(request);
-      Status status = Status.fromCode(response.getStatus().getValue());
-      if (ifExists && status == Status.NO_SUCH_OBJECT) {
-        return;
-      }
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+  public void dropRoleIfExists(String requestorUserName, String roleName,
+      String component) throws SentryUserException;
 
   /**
    * add a sentry role to groups.
@@ -248,21 +61,7 @@ public class SentryGenericServiceClient {
    * @throws SentryUserException
    */
   public void addRoleToGroups(String requestorUserName, String roleName,
-      String component, Set<String> groups) throws SentryUserException {
-    TAlterSentryRoleAddGroupsRequest request = new TAlterSentryRoleAddGroupsRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setRequestorUserName(requestorUserName);
-    request.setRoleName(roleName);
-    request.setGroups(groups);
-    request.setComponent(component);
-
-    try {
-      TAlterSentryRoleAddGroupsResponse response = client.alter_sentry_role_add_groups(request);
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+      String component, Set<String> groups) throws SentryUserException;
 
   /**
    * delete a sentry role from groups.
@@ -273,21 +72,7 @@ public class SentryGenericServiceClient {
    * @throws SentryUserException
    */
   public void deleteRoleToGroups(String requestorUserName, String roleName,
-      String component, Set<String> groups) throws SentryUserException {
-    TAlterSentryRoleDeleteGroupsRequest request = new TAlterSentryRoleDeleteGroupsRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setRequestorUserName(requestorUserName);
-    request.setRoleName(roleName);
-    request.setGroups(groups);
-    request.setComponent(component);
-
-    try {
-      TAlterSentryRoleDeleteGroupsResponse response = client.alter_sentry_role_delete_groups(request);
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+      String component, Set<String> groups) throws SentryUserException;
 
   /**
    * grant privilege
@@ -298,21 +83,7 @@ public class SentryGenericServiceClient {
    * @throws SentryUserException
    */
   public void grantPrivilege(String requestorUserName, String roleName,
-      String component, TSentryPrivilege privilege) throws SentryUserException {
-    TAlterSentryRoleGrantPrivilegeRequest request = new TAlterSentryRoleGrantPrivilegeRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setComponent(component);
-    request.setRoleName(roleName);
-    request.setRequestorUserName(requestorUserName);
-    request.setPrivilege(privilege);
-
-    try {
-      TAlterSentryRoleGrantPrivilegeResponse response = client.alter_sentry_role_grant_privilege(request);
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+      String component, TSentryPrivilege privilege) throws SentryUserException;
 
   /**
    * revoke privilege
@@ -323,21 +94,7 @@ public class SentryGenericServiceClient {
    * @throws SentryUserException
    */
   public void revokePrivilege(String requestorUserName, String roleName,
-      String component, TSentryPrivilege privilege) throws SentryUserException {
-    TAlterSentryRoleRevokePrivilegeRequest request = new TAlterSentryRoleRevokePrivilegeRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setComponent(component);
-    request.setRequestorUserName(requestorUserName);
-    request.setRoleName(roleName);
-    request.setPrivilege(privilege);
-
-    try {
-      TAlterSentryRoleRevokePrivilegeResponse response = client.alter_sentry_role_revoke_privilege(request);
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+      String component, TSentryPrivilege privilege) throws SentryUserException;
 
   /**
    * drop privilege
@@ -348,20 +105,7 @@ public class SentryGenericServiceClient {
    * @throws SentryUserException
    */
   public void dropPrivilege(String requestorUserName,String component,
-      TSentryPrivilege privilege) throws SentryUserException {
-    TDropPrivilegesRequest request = new TDropPrivilegesRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setComponent(component);
-    request.setRequestorUserName(requestorUserName);
-    request.setPrivilege(privilege);
-
-    try {
-      TDropPrivilegesResponse response = client.drop_sentry_privilege(request);
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+      TSentryPrivilege privilege) throws SentryUserException;
 
   /**
    * rename privilege
@@ -374,36 +118,7 @@ public class SentryGenericServiceClient {
    */
   public void renamePrivilege(String requestorUserName, String component,
       String serviceName, List<? extends Authorizable> oldAuthorizables,
-      List<? extends Authorizable> newAuthorizables) throws SentryUserException {
-    if ((oldAuthorizables == null) || (oldAuthorizables.size() == 0)
-        || (newAuthorizables == null) || (newAuthorizables.size() == 0)) {
-      throw new SentryUserException("oldAuthorizables and newAuthorizables can't be null or empty");
-    }
-
-    TRenamePrivilegesRequest request = new TRenamePrivilegesRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setComponent(component);
-    request.setRequestorUserName(requestorUserName);
-    request.setServiceName(serviceName);
-
-    List<TAuthorizable> oldTAuthorizables = Lists.newArrayList();
-    List<TAuthorizable> newTAuthorizables = Lists.newArrayList();
-    for (Authorizable authorizable : oldAuthorizables) {
-      oldTAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
-      request.setOldAuthorizables(oldTAuthorizables);
-    }
-    for (Authorizable authorizable : newAuthorizables) {
-      newTAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
-      request.setNewAuthorizables(newTAuthorizables);
-    }
-
-    try {
-      TRenamePrivilegesResponse response = client.rename_sentry_privilege(request);
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+      List<? extends Authorizable> newAuthorizables) throws SentryUserException;
 
   /**
    * Gets sentry role objects for a given groupName using the Sentry service
@@ -413,35 +128,17 @@ public class SentryGenericServiceClient {
    * @return Set of thrift sentry role objects
    * @throws SentryUserException
    */
-  public synchronized Set<TSentryRole> listRolesByGroupName(
+  public Set<TSentryRole> listRolesByGroupName(
       String requestorUserName,
       String groupName,
       String component)
-  throws SentryUserException {
-    TListSentryRolesRequest request = new TListSentryRolesRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setRequestorUserName(requestorUserName);
-    request.setGroupName(groupName);
-    request.setComponent(component);
-    TListSentryRolesResponse response;
-    try {
-      response = client.list_sentry_roles_by_group(request);
-      Status.throwIfNotOk(response.getStatus());
-      return response.getRoles();
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+  throws SentryUserException;
 
   public Set<TSentryRole> listUserRoles(String requestorUserName, String component)
-      throws SentryUserException {
-    return listRolesByGroupName(requestorUserName, AccessConstants.ALL, component);
-  }
+      throws SentryUserException;
 
   public Set<TSentryRole> listAllRoles(String requestorUserName, String component)
-      throws SentryUserException {
-    return listRolesByGroupName(requestorUserName, null, component);
-  }
+      throws SentryUserException;
 
   /**
    * Gets sentry privileges for a given roleName and Authorizable Hirerchys using the Sentry service
@@ -456,36 +153,11 @@ public class SentryGenericServiceClient {
   public Set<TSentryPrivilege> listPrivilegesByRoleName(
       String requestorUserName, String roleName, String component,
       String serviceName, List<? extends Authorizable> authorizables)
-      throws SentryUserException {
-    TListSentryPrivilegesRequest request = new TListSentryPrivilegesRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setComponent(component);
-    request.setServiceName(serviceName);
-    request.setRequestorUserName(requestorUserName);
-    request.setRoleName(roleName);
-    if ((authorizables != null) && (authorizables.size() > 0)) {
-      List<TAuthorizable> tAuthorizables = Lists.newArrayList();
-      for (Authorizable authorizable : authorizables) {
-        tAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
-      }
-      request.setAuthorizables(tAuthorizables);
-    }
-
-    TListSentryPrivilegesResponse response;
-    try {
-      response = client.list_sentry_privileges_by_role(request);
-      Status.throwIfNotOk(response.getStatus());
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-    return response.getPrivileges();
-  }
+      throws SentryUserException;
 
   public Set<TSentryPrivilege> listPrivilegesByRoleName(
       String requestorUserName, String roleName, String component,
-      String serviceName) throws SentryUserException {
-    return listPrivilegesByRoleName(requestorUserName, roleName, component, serviceName, null);
-  }
+      String serviceName) throws SentryUserException;
 
   /**
    * get sentry permissions from provider as followings:
@@ -499,38 +171,7 @@ public class SentryGenericServiceClient {
    */
   public Set<String> listPrivilegesForProvider(String component,
       String serviceName, ActiveRoleSet roleSet, Set<String> groups,
-      List<? extends Authorizable> authorizables) throws SentryUserException {
-    TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(roleSet.isAll(), roleSet.getRoles());
-    TListSentryPrivilegesForProviderRequest request = new TListSentryPrivilegesForProviderRequest();
-    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
-    request.setComponent(component);
-    request.setServiceName(serviceName);
-    request.setRoleSet(thriftRoleSet);
-    if (groups == null) {
-      request.setGroups(new HashSet<String>());
-    } else {
-      request.setGroups(groups);
-    }
-    List<TAuthorizable> tAuthoriables = Lists.newArrayList();
-    if ((authorizables != null) && (authorizables.size() > 0)) {
-      for (Authorizable authorizable : authorizables) {
-        tAuthoriables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
-      }
-      request.setAuthorizables(tAuthoriables);
-    }
-
-    try {
-      TListSentryPrivilegesForProviderResponse response = client.list_sentry_privileges_for_provider(request);
-      Status.throwIfNotOk(response.getStatus());
-      return response.getPrivileges();
-    } catch (TException e) {
-      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
-    }
-  }
+      List<? extends Authorizable> authorizables) throws SentryUserException;
 
-  public void close() {
-    if (transport != null) {
-      transport.close();
-    }
-  }
+  public void close();
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java
new file mode 100644
index 0000000..67a3574
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientDefaultImpl.java
@@ -0,0 +1,538 @@
+/**
+ * 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.provider.db.generic.service.thrift;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.net.NetUtils;
+import org.apache.hadoop.security.SaslRpcServer;
+import org.apache.hadoop.security.SaslRpcServer.AuthMethod;
+import org.apache.hadoop.security.SecurityUtil;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.sentry.SentryUserException;
+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.service.thrift.ServiceConstants.ClientConfig;
+import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
+import org.apache.sentry.service.thrift.Status;
+import org.apache.sentry.service.thrift.sentry_common_serviceConstants;
+import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TMultiplexedProtocol;
+import org.apache.thrift.transport.TSaslClientTransport;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+public class SentryGenericServiceClientDefaultImpl implements SentryGenericServiceClient {
+  private final Configuration conf;
+  private final InetSocketAddress serverAddress;
+  private final boolean kerberos;
+  private final String[] serverPrincipalParts;
+  private SentryGenericPolicyService.Client client;
+  private TTransport transport;
+  private int connectionTimeout;
+  private static final Logger LOGGER = LoggerFactory
+                                       .getLogger(SentryGenericServiceClientDefaultImpl.class);
+  private static final String THRIFT_EXCEPTION_MESSAGE = "Thrift exception occured ";
+
+  /**
+   * This transport wraps the Sasl transports to set up the right UGI context for open().
+   */
+  public static class UgiSaslClientTransport extends TSaslClientTransport {
+    protected UserGroupInformation ugi = null;
+
+    public UgiSaslClientTransport(String mechanism, String authorizationId,
+        String protocol, String serverName, Map<String, String> props,
+        CallbackHandler cbh, TTransport transport, boolean wrapUgi)
+        throws IOException {
+      super(mechanism, authorizationId, protocol, serverName, props, cbh,
+          transport);
+      if (wrapUgi) {
+        ugi = UserGroupInformation.getLoginUser();
+      }
+    }
+
+    // open the SASL transport with using the current UserGroupInformation
+    // This is needed to get the current login context stored
+    @Override
+    public void open() throws TTransportException {
+      if (ugi == null) {
+        baseOpen();
+      } else {
+        try {
+          if (ugi.isFromKeytab()) {
+            ugi.checkTGTAndReloginFromKeytab();
+          }
+          ugi.doAs(new PrivilegedExceptionAction<Void>() {
+            public Void run() throws TTransportException {
+              baseOpen();
+              return null;
+            }
+          });
+        } catch (IOException e) {
+          throw new TTransportException("Failed to open SASL transport", e);
+        } catch (InterruptedException e) {
+          throw new TTransportException(
+              "Interrupted while opening underlying transport", e);
+        }
+      }
+    }
+
+    private void baseOpen() throws TTransportException {
+      super.open();
+    }
+  }
+
+  public SentryGenericServiceClientDefaultImpl(Configuration conf) throws IOException {
+    this.conf = conf;
+    Preconditions.checkNotNull(this.conf, "Configuration object cannot be null");
+    this.serverAddress = NetUtils.createSocketAddr(Preconditions.checkNotNull(
+                           conf.get(ClientConfig.SERVER_RPC_ADDRESS), "Config key "
+                           + ClientConfig.SERVER_RPC_ADDRESS + " is required"), conf.getInt(
+                           ClientConfig.SERVER_RPC_PORT, ClientConfig.SERVER_RPC_PORT_DEFAULT));
+    this.connectionTimeout = conf.getInt(ClientConfig.SERVER_RPC_CONN_TIMEOUT,
+                                         ClientConfig.SERVER_RPC_CONN_TIMEOUT_DEFAULT);
+    kerberos = ServerConfig.SECURITY_MODE_KERBEROS.equalsIgnoreCase(
+        conf.get(ServerConfig.SECURITY_MODE, ServerConfig.SECURITY_MODE_KERBEROS).trim());
+    transport = new TSocket(serverAddress.getHostName(),
+        serverAddress.getPort(), connectionTimeout);
+    if (kerberos) {
+      String serverPrincipal = Preconditions.checkNotNull(conf.get(ServerConfig.PRINCIPAL), ServerConfig.PRINCIPAL + " is required");
+
+      // Resolve server host in the same way as we are doing on server side
+      serverPrincipal = SecurityUtil.getServerPrincipal(serverPrincipal, serverAddress.getAddress());
+      LOGGER.debug("Using server kerberos principal: " + serverPrincipal);
+
+      serverPrincipalParts = SaslRpcServer.splitKerberosName(serverPrincipal);
+      Preconditions.checkArgument(serverPrincipalParts.length == 3,
+           "Kerberos principal should have 3 parts: " + serverPrincipal);
+      boolean wrapUgi = "true".equalsIgnoreCase(conf
+          .get(ServerConfig.SECURITY_USE_UGI_TRANSPORT, "true"));
+      transport = new UgiSaslClientTransport(AuthMethod.KERBEROS.getMechanismName(),
+          null, serverPrincipalParts[0], serverPrincipalParts[1],
+          ClientConfig.SASL_PROPERTIES, null, transport, wrapUgi);
+    } else {
+      serverPrincipalParts = null;
+    }
+    try {
+      transport.open();
+    } catch (TTransportException e) {
+      throw new IOException("Transport exception while opening transport: " + e.getMessage(), e);
+    }
+    LOGGER.debug("Successfully opened transport: " + transport + " to " + serverAddress);
+    TMultiplexedProtocol protocol = new TMultiplexedProtocol(
+      new TBinaryProtocol(transport),
+      SentryGenericPolicyProcessor.SENTRY_GENERIC_SERVICE_NAME);
+    client = new SentryGenericPolicyService.Client(protocol);
+    LOGGER.debug("Successfully created client");
+  }
+
+
+
+  /**
+   * Create a sentry role
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param roleName: Name of the role
+   * @param component: The request is issued to which component
+   * @throws SentryUserException
+   */
+  public synchronized void createRole(String requestorUserName, String roleName, String component)
+  throws SentryUserException {
+    TCreateSentryRoleRequest request = new TCreateSentryRoleRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setRequestorUserName(requestorUserName);
+    request.setRoleName(roleName);
+    request.setComponent(component);
+    try {
+      TCreateSentryRoleResponse response = client.create_sentry_role(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  public void createRoleIfNotExist(String requestorUserName, String roleName, String component) throws SentryUserException {
+    TCreateSentryRoleRequest request = new TCreateSentryRoleRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setRequestorUserName(requestorUserName);
+    request.setRoleName(roleName);
+    request.setComponent(component);
+    try {
+      TCreateSentryRoleResponse response = client.create_sentry_role(request);
+      Status status = Status.fromCode(response.getStatus().getValue());
+      if (status == Status.ALREADY_EXISTS) {
+        return;
+      }
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  /**
+   * Drop a sentry role
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param roleName: Name of the role
+   * @param component: The request is issued to which component
+   * @throws SentryUserException
+   */
+  public void dropRole(String requestorUserName,
+      String roleName, String component)
+  throws SentryUserException {
+    dropRole(requestorUserName, roleName, component, false);
+  }
+
+  public void dropRoleIfExists(String requestorUserName,
+      String roleName, String component)
+  throws SentryUserException {
+    dropRole(requestorUserName, roleName, component, true);
+  }
+
+  private void dropRole(String requestorUserName,
+      String roleName, String component , boolean ifExists)
+  throws SentryUserException {
+    TDropSentryRoleRequest request = new TDropSentryRoleRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setRequestorUserName(requestorUserName);
+    request.setRoleName(roleName);
+    request.setComponent(component);
+    try {
+      TDropSentryRoleResponse response = client.drop_sentry_role(request);
+      Status status = Status.fromCode(response.getStatus().getValue());
+      if (ifExists && status == Status.NO_SUCH_OBJECT) {
+        return;
+      }
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  /**
+   * add a sentry role to groups.
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param roleName: Name of the role
+   * @param component: The request is issued to which component
+   * @param groups: The name of groups
+   * @throws SentryUserException
+   */
+  public void addRoleToGroups(String requestorUserName, String roleName,
+      String component, Set<String> groups) throws SentryUserException {
+    TAlterSentryRoleAddGroupsRequest request = new TAlterSentryRoleAddGroupsRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setRequestorUserName(requestorUserName);
+    request.setRoleName(roleName);
+    request.setGroups(groups);
+    request.setComponent(component);
+
+    try {
+      TAlterSentryRoleAddGroupsResponse response = client.alter_sentry_role_add_groups(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  /**
+   * delete a sentry role from groups.
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param roleName: Name of the role
+   * @param component: The request is issued to which component
+   * @param groups: The name of groups
+   * @throws SentryUserException
+   */
+  public void deleteRoleToGroups(String requestorUserName, String roleName,
+      String component, Set<String> groups) throws SentryUserException {
+    TAlterSentryRoleDeleteGroupsRequest request = new TAlterSentryRoleDeleteGroupsRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setRequestorUserName(requestorUserName);
+    request.setRoleName(roleName);
+    request.setGroups(groups);
+    request.setComponent(component);
+
+    try {
+      TAlterSentryRoleDeleteGroupsResponse response = client.alter_sentry_role_delete_groups(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  /**
+   * grant privilege
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param roleName: Name of the role
+   * @param component: The request is issued to which component
+   * @param privilege
+   * @throws SentryUserException
+   */
+  public void grantPrivilege(String requestorUserName, String roleName,
+      String component, TSentryPrivilege privilege) throws SentryUserException {
+    TAlterSentryRoleGrantPrivilegeRequest request = new TAlterSentryRoleGrantPrivilegeRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setComponent(component);
+    request.setRoleName(roleName);
+    request.setRequestorUserName(requestorUserName);
+    request.setPrivilege(privilege);
+
+    try {
+      TAlterSentryRoleGrantPrivilegeResponse response = client.alter_sentry_role_grant_privilege(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  /**
+   * revoke privilege
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param roleName: Name of the role
+   * @param component: The request is issued to which component
+   * @param privilege
+   * @throws SentryUserException
+   */
+  public void revokePrivilege(String requestorUserName, String roleName,
+      String component, TSentryPrivilege privilege) throws SentryUserException {
+    TAlterSentryRoleRevokePrivilegeRequest request = new TAlterSentryRoleRevokePrivilegeRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setComponent(component);
+    request.setRequestorUserName(requestorUserName);
+    request.setRoleName(roleName);
+    request.setPrivilege(privilege);
+
+    try {
+      TAlterSentryRoleRevokePrivilegeResponse response = client.alter_sentry_role_revoke_privilege(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  /**
+   * drop privilege
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param roleName: Name of the role
+   * @param component: The request is issued to which component
+   * @param privilege
+   * @throws SentryUserException
+   */
+  public void dropPrivilege(String requestorUserName,String component,
+      TSentryPrivilege privilege) throws SentryUserException {
+    TDropPrivilegesRequest request = new TDropPrivilegesRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setComponent(component);
+    request.setRequestorUserName(requestorUserName);
+    request.setPrivilege(privilege);
+
+    try {
+      TDropPrivilegesResponse response = client.drop_sentry_privilege(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  /**
+   * rename privilege
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param component: The request is issued to which component
+   * @param serviceName: The Authorizable belongs to which service
+   * @param oldAuthorizables
+   * @param newAuthorizables
+   * @throws SentryUserException
+   */
+  public void renamePrivilege(String requestorUserName, String component,
+      String serviceName, List<? extends Authorizable> oldAuthorizables,
+      List<? extends Authorizable> newAuthorizables) throws SentryUserException {
+    if ((oldAuthorizables == null) || (oldAuthorizables.size() == 0)
+        || (newAuthorizables == null) || (newAuthorizables.size() == 0)) {
+      throw new SentryUserException("oldAuthorizables and newAuthorizables can't be null or empty");
+    }
+
+    TRenamePrivilegesRequest request = new TRenamePrivilegesRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setComponent(component);
+    request.setRequestorUserName(requestorUserName);
+    request.setServiceName(serviceName);
+
+    List<TAuthorizable> oldTAuthorizables = Lists.newArrayList();
+    List<TAuthorizable> newTAuthorizables = Lists.newArrayList();
+    for (Authorizable authorizable : oldAuthorizables) {
+      oldTAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
+      request.setOldAuthorizables(oldTAuthorizables);
+    }
+    for (Authorizable authorizable : newAuthorizables) {
+      newTAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
+      request.setNewAuthorizables(newTAuthorizables);
+    }
+
+    try {
+      TRenamePrivilegesResponse response = client.rename_sentry_privilege(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  /**
+   * Gets sentry role objects for a given groupName using the Sentry service
+   * @param requestorUserName : user on whose behalf the request is issued
+   * @param groupName : groupName to look up ( if null returns all roles for groups related to requestorUserName)
+   * @param component: The request is issued to which component
+   * @return Set of thrift sentry role objects
+   * @throws SentryUserException
+   */
+  public synchronized Set<TSentryRole> listRolesByGroupName(
+      String requestorUserName,
+      String groupName,
+      String component)
+  throws SentryUserException {
+    TListSentryRolesRequest request = new TListSentryRolesRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setRequestorUserName(requestorUserName);
+    request.setGroupName(groupName);
+    request.setComponent(component);
+    TListSentryRolesResponse response;
+    try {
+      response = client.list_sentry_roles_by_group(request);
+      Status.throwIfNotOk(response.getStatus());
+      return response.getRoles();
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  public Set<TSentryRole> listUserRoles(String requestorUserName, String component)
+      throws SentryUserException {
+    return listRolesByGroupName(requestorUserName, AccessConstants.ALL, component);
+  }
+
+  public Set<TSentryRole> listAllRoles(String requestorUserName, String component)
+      throws SentryUserException {
+    return listRolesByGroupName(requestorUserName, null, component);
+  }
+
+  /**
+   * Gets sentry privileges for a given roleName and Authorizable Hirerchys using the Sentry service
+   * @param requestorUserName: user on whose behalf the request is issued
+   * @param roleName:
+   * @param component: The request is issued to which component
+   * @param serviceName
+   * @param authorizables
+   * @return
+   * @throws SentryUserException
+   */
+  public Set<TSentryPrivilege> listPrivilegesByRoleName(
+      String requestorUserName, String roleName, String component,
+      String serviceName, List<? extends Authorizable> authorizables)
+      throws SentryUserException {
+    TListSentryPrivilegesRequest request = new TListSentryPrivilegesRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setComponent(component);
+    request.setServiceName(serviceName);
+    request.setRequestorUserName(requestorUserName);
+    request.setRoleName(roleName);
+    if ((authorizables != null) && (authorizables.size() > 0)) {
+      List<TAuthorizable> tAuthorizables = Lists.newArrayList();
+      for (Authorizable authorizable : authorizables) {
+        tAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
+      }
+      request.setAuthorizables(tAuthorizables);
+    }
+
+    TListSentryPrivilegesResponse response;
+    try {
+      response = client.list_sentry_privileges_by_role(request);
+      Status.throwIfNotOk(response.getStatus());
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+    return response.getPrivileges();
+  }
+
+  public Set<TSentryPrivilege> listPrivilegesByRoleName(
+      String requestorUserName, String roleName, String component,
+      String serviceName) throws SentryUserException {
+    return listPrivilegesByRoleName(requestorUserName, roleName, component, serviceName, null);
+  }
+
+  /**
+   * get sentry permissions from provider as followings:
+   * @param: component: The request is issued to which component
+   * @param: serviceName: The privilege belongs to which service
+   * @param: roleSet
+   * @param: groupNames
+   * @param: the authorizables
+   * @returns the set of permissions
+   * @throws SentryUserException
+   */
+  public Set<String> listPrivilegesForProvider(String component,
+      String serviceName, ActiveRoleSet roleSet, Set<String> groups,
+      List<? extends Authorizable> authorizables) throws SentryUserException {
+    TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(roleSet.isAll(), roleSet.getRoles());
+    TListSentryPrivilegesForProviderRequest request = new TListSentryPrivilegesForProviderRequest();
+    request.setProtocol_version(sentry_common_serviceConstants.TSENTRY_SERVICE_V2);
+    request.setComponent(component);
+    request.setServiceName(serviceName);
+    request.setRoleSet(thriftRoleSet);
+    if (groups == null) {
+      request.setGroups(new HashSet<String>());
+    } else {
+      request.setGroups(groups);
+    }
+    List<TAuthorizable> tAuthoriables = Lists.newArrayList();
+    if ((authorizables != null) && (authorizables.size() > 0)) {
+      for (Authorizable authorizable : authorizables) {
+        tAuthoriables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
+      }
+      request.setAuthorizables(tAuthoriables);
+    }
+
+    try {
+      TListSentryPrivilegesForProviderResponse response = client.list_sentry_privileges_for_provider(request);
+      Status.throwIfNotOk(response.getStatus());
+      return response.getPrivileges();
+    } catch (TException e) {
+      throw new SentryUserException(THRIFT_EXCEPTION_MESSAGE, e);
+    }
+  }
+
+  @Override
+  public void close() {
+    if (transport != null) {
+      transport.close();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientFactory.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientFactory.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientFactory.java
new file mode 100644
index 0000000..b070c6d
--- /dev/null
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericServiceClientFactory.java
@@ -0,0 +1,34 @@
+/**
+ * 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.provider.db.generic.service.thrift;
+
+import org.apache.hadoop.conf.Configuration;
+
+/**
+ * SentryGenericServiceClientFactory is a public class for the components which using Generic Model to create sentry client.
+ */
+public class SentryGenericServiceClientFactory {
+
+  private SentryGenericServiceClientFactory() {
+  }
+
+  public static SentryGenericServiceClient create(Configuration conf) throws Exception {
+      return new SentryGenericServiceClientDefaultImpl(conf);
+  }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java
index 6b86077..4732ea2 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/service/thrift/TestSentryGenericServiceIntegration.java
@@ -56,15 +56,16 @@ public class TestSentryGenericServiceIntegration extends SentryServiceIntegratio
   public void connectToSentryService() throws Exception {
     // The client should already be logged in when running in solr
     // therefore we must manually login in the integration tests
+    final SentryGenericServiceClientFactory clientFactory;
     if (kerberos) {
       this.client = Subject.doAs(clientSubject, new PrivilegedExceptionAction<SentryGenericServiceClient>() {
         @Override
         public SentryGenericServiceClient run() throws Exception {
-          return new SentryGenericServiceClient(conf);
+          return SentryGenericServiceClientFactory.create(conf);
         }
       });
     } else {
-      this.client = new SentryGenericServiceClient(conf);
+      this.client = SentryGenericServiceClientFactory.create(conf);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/db/integration/AbstractSolrSentryTestWithDbProvider.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/db/integration/AbstractSolrSentryTestWithDbProvider.java b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/db/integration/AbstractSolrSentryTestWithDbProvider.java
index 33b35e6..29a5981 100644
--- a/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/db/integration/AbstractSolrSentryTestWithDbProvider.java
+++ b/sentry-tests/sentry-tests-solr/src/test/java/org/apache/sentry/tests/e2e/solr/db/integration/AbstractSolrSentryTestWithDbProvider.java
@@ -42,6 +42,7 @@ import org.apache.sentry.core.common.Action;
 import org.apache.sentry.core.model.search.SearchConstants;
 import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
 import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
@@ -204,7 +205,7 @@ public class AbstractSolrSentryTestWithDbProvider extends AbstractSolrSentryTest
   }
 
   public static void connectToSentryService() throws Exception {
-    client = new SentryGenericServiceClient(conf);
+    client = SentryGenericServiceClientFactory.create(conf);
   }
 
   public static void stopAllService() throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/fd293e11/sentry-tests/sentry-tests-sqoop/src/test/java/org/apache/sentry/tests/e2e/sqoop/AbstractSqoopSentryTestBase.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-sqoop/src/test/java/org/apache/sentry/tests/e2e/sqoop/AbstractSqoopSentryTestBase.java b/sentry-tests/sentry-tests-sqoop/src/test/java/org/apache/sentry/tests/e2e/sqoop/AbstractSqoopSentryTestBase.java
index 93ccd75..d60ee1c 100644
--- a/sentry-tests/sentry-tests-sqoop/src/test/java/org/apache/sentry/tests/e2e/sqoop/AbstractSqoopSentryTestBase.java
+++ b/sentry-tests/sentry-tests-sqoop/src/test/java/org/apache/sentry/tests/e2e/sqoop/AbstractSqoopSentryTestBase.java
@@ -37,6 +37,7 @@ import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
 import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
 import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
 import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
@@ -199,7 +200,7 @@ public class AbstractSqoopSentryTestBase {
     SentryGenericServiceClient sentryClient = null;
     try {
       /** grant all privilege to admin user */
-      sentryClient = new SentryGenericServiceClient(getClientConfig());
+      sentryClient = SentryGenericServiceClientFactory.create(getClientConfig());
       sentryClient.createRoleIfNotExist(ADMIN_USER, ADMIN_ROLE, COMPONENT);
       sentryClient.addRoleToGroups(ADMIN_USER, ADMIN_ROLE, COMPONENT, Sets.newHashSet(ADMIN_GROUP));
       sentryClient.grantPrivilege(ADMIN_USER, ADMIN_ROLE, COMPONENT,